dotfiles: leviathan: arch-openbox-20231010
This commit is contained in:
9
.local/bin/$
Executable file
9
.local/bin/$
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Ever pasted "$ somecommand" into the terminal and gotten this error?
|
||||
# -bash: $: command not found
|
||||
|
||||
# Begone, silly errors! Lazy copy + paste forever!! ETCETERA!!!!
|
||||
|
||||
echo 'Quit pasting in commands from the internet, you lazy bum.'
|
||||
"$@"
|
BIN
.local/bin/Anytype-0.34.3_61d7dedec57aa8dec9d3e01ff6a0b455.AppImage
Executable file
BIN
.local/bin/Anytype-0.34.3_61d7dedec57aa8dec9d3e01ff6a0b455.AppImage
Executable file
Binary file not shown.
BIN
.local/bin/__pycache__/exrex.cpython-311.pyc
Normal file
BIN
.local/bin/__pycache__/exrex.cpython-311.pyc
Normal file
Binary file not shown.
BIN
.local/bin/__pycache__/fbpack.cpython-311.pyc
Normal file
BIN
.local/bin/__pycache__/fbpack.cpython-311.pyc
Normal file
Binary file not shown.
BIN
.local/bin/__pycache__/packedstruct.cpython-311.pyc
Normal file
BIN
.local/bin/__pycache__/packedstruct.cpython-311.pyc
Normal file
Binary file not shown.
BIN
.local/bin/__pycache__/readelf.cpython-311.pyc
Normal file
BIN
.local/bin/__pycache__/readelf.cpython-311.pyc
Normal file
Binary file not shown.
43
.local/bin/aosp_gsi
Executable file
43
.local/bin/aosp_gsi
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
. build/envsetup.sh
|
||||
|
||||
PLATFORM="${1}"
|
||||
SQUASH="${2}"
|
||||
|
||||
TOP="${ANDROID_BUILD_TOP}"
|
||||
MANIFEST="${TOP}/.repo/manifest.xml"
|
||||
BRANCH=$(grep "default revision" "${MANIFEST}" \
|
||||
| sed 's/^ *//g;s/<default revision=\"refs\/heads\///g;s/\"//g')
|
||||
STAGINGBRANCH="${BRANCH}-${PLATFORM}-gsi"
|
||||
|
||||
# Build list of LineageOS forked repos
|
||||
PROJECTBLACKLIST="Gallery2"
|
||||
PROJECTPATHS=$(grep "name=\"LineageOS/" "${MANIFEST}" \
|
||||
| grep -v "clone-depth=\"1\"" \
|
||||
| egrep -v ${PROJECTBLACKLIST} \
|
||||
| sed -n 's/.*path="\([^"]\+\)".*/\1/p')
|
||||
|
||||
repo abandon "${STAGINGBRANCH}"
|
||||
|
||||
# Iterate over each forked project
|
||||
for PROJECTPATH in ${PROJECTPATHS}; do
|
||||
cd "${TOP}/${PROJECTPATH}"
|
||||
repo start "${STAGINGBRANCH}" .
|
||||
aospremote | grep -v "Remote 'aosp' created"
|
||||
git fetch -q aosp "${PLATFORM}"-gsi
|
||||
|
||||
echo "#### Merging ${PLATFORM} into ${PROJECTPATH} ####"
|
||||
if [ ! -z $SQUASH ]; then
|
||||
git merge --log --squash aosp/"${PLATFORM}"-gsi
|
||||
if [ $? -eq 1 ]; then read; fi
|
||||
if ! git diff --cached --exit-code > /dev/null; then
|
||||
git commit --no-edit
|
||||
OLD_MSG=$(git log --format=%B -n1)
|
||||
git commit --amend -m "[DNM] Squash of ${STAGINGBRANCH}" -m "$OLD_MSG"
|
||||
fi
|
||||
else
|
||||
git merge --log aosp/"${PLATFORM}"-gsi
|
||||
if [ $? -eq 1 ]; then read; fi
|
||||
fi
|
||||
done
|
43
.local/bin/aosp_merge
Executable file
43
.local/bin/aosp_merge
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
. build/envsetup.sh
|
||||
|
||||
NEWTAG="${1}"
|
||||
SQUASH="${2}"
|
||||
|
||||
TOP="${ANDROID_BUILD_TOP}"
|
||||
MANIFEST="${TOP}/.repo/manifests/default.xml"
|
||||
BRANCH=$(grep "default revision" "${MANIFEST}" \
|
||||
| sed 's/^ *//g;s/<default revision=\"refs\/heads\///g;s/\"//g')
|
||||
STAGINGBRANCH="${BRANCH}-${NEWTAG}"
|
||||
|
||||
# Build list of forked repos
|
||||
PROJECTBLACKLIST="Gallery2"
|
||||
PROJECTPATHS=$(grep "remote=\"omnirom" "${MANIFEST}" \
|
||||
| grep -v "clone-depth=\"1\"" \
|
||||
| egrep -v ${PROJECTBLACKLIST} \
|
||||
| sed -n 's/.*path="\([^"]\+\)".*/\1/p')
|
||||
|
||||
repo abandon "${STAGINGBRANCH}"
|
||||
|
||||
# Iterate over each forked project
|
||||
for PROJECTPATH in ${PROJECTPATHS}; do
|
||||
cd "${TOP}/${PROJECTPATH}"
|
||||
repo start "${STAGINGBRANCH}" .
|
||||
aospremote | grep -v "Remote 'aosp' created"
|
||||
git fetch -q --tags aosp "${NEWTAG}"
|
||||
|
||||
echo "#### Merging ${NEWTAG} into ${PROJECTPATH} ####"
|
||||
if [ ! -z $SQUASH ]; then
|
||||
git merge --log --squash "${NEWTAG}"
|
||||
if [ $? -eq 1 ]; then read; fi
|
||||
if ! git diff --cached --exit-code > /dev/null; then
|
||||
git commit --no-edit
|
||||
OLD_MSG=$(git log --format=%B -n1)
|
||||
git commit --amend -m "[DNM] Squash of ${STAGINGBRANCH}" -m "$OLD_MSG"
|
||||
fi
|
||||
else
|
||||
git merge --log "${NEWTAG}"
|
||||
if [ $? -eq 1 ]; then read; fi
|
||||
fi
|
||||
done
|
1
.local/bin/aospdtgen
Symbolic link
1
.local/bin/aospdtgen
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/aospdtgen/bin/aospdtgen
|
30
.local/bin/backup_home.sh
Executable file
30
.local/bin/backup_home.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# What to backup.
|
||||
bfiles=".local/bin .ssh .gnupg .config .xstefenrc .gitconfig \
|
||||
.bashrc .inputrc .nanorc .xprofile \
|
||||
.android-certs android/utils android/stock"
|
||||
|
||||
# Where to backup to.
|
||||
bdest="/mnt/seagate/Backups/"
|
||||
|
||||
# Create archive filename.
|
||||
bdate=$(date +%Y%m%d)
|
||||
bhost=$(hostname -s)
|
||||
barchive="$bhost-$bdate.tgz"
|
||||
|
||||
# Print start status message.
|
||||
echo "Backing up $bfiles to $bdest/$barchive"
|
||||
date
|
||||
echo
|
||||
|
||||
# Backup the files using tar.
|
||||
tar czf $bdest/$barchive $bfiles
|
||||
|
||||
# Print end status message.
|
||||
echo
|
||||
echo "Backup finished"
|
||||
date
|
||||
|
||||
# Long listing of files in $dest to check file sizes.
|
||||
ls -lh $bdest
|
196
.local/bin/bar
Executable file
196
.local/bin/bar
Executable file
@ -0,0 +1,196 @@
|
||||
#!/bin/bash
|
||||
# shellcheck disable=SC2059,SC2064,SC2086
|
||||
|
||||
# simple lightweight lemonbar script for use with dk
|
||||
|
||||
set -eE -o pipefail
|
||||
|
||||
bg="#111111"
|
||||
fg="#666666"
|
||||
highlight="#6699ee"
|
||||
underline=3
|
||||
separator="┃"
|
||||
|
||||
# xfonts (adjust size based on resolution)
|
||||
px=$(xrandr | grep ' connected' | tail -n1 | grep -o '[0-9]\+x[0-9]\+' | cut -d'x' -f2)
|
||||
mm=$(xrandr | grep ' connected' | tail -n1 | grep -o '[0-9]\+mm' | tail -n1 | sed 's/mm//')
|
||||
dpi=$(( (px / mm) * 25 ))
|
||||
|
||||
if (( dpi >= 140 )); then
|
||||
font0="-xos4-terminus-medium-r-normal--24-240-72-72-c-120-iso10646-1"
|
||||
elif (( dpi >= 120 )); then
|
||||
font0="-xos4-terminus-medium-r-normal--18-240-72-72-c-120-iso10646-1"
|
||||
elif (( dpi >= 100 )); then
|
||||
font0="-xos4-terminus-medium-r-normal--14-240-72-72-c-120-iso10646-1"
|
||||
else
|
||||
font0="-xos4-terminus-medium-r-normal--12-240-72-72-c-120-iso10646-1"
|
||||
fi
|
||||
|
||||
font1=""
|
||||
font2=""
|
||||
font3=""
|
||||
|
||||
# xft fonts
|
||||
# font0="monospace:pixelsize=24"
|
||||
# font1="Font Awesome 5 Brands:pixelsize=20"
|
||||
# font2="icomoon:pixelsize=18"
|
||||
# font3="Anonymice Nerd Font Mono:pixelsize=18"
|
||||
|
||||
fifo="/tmp/bar.fifo"
|
||||
|
||||
# mimic dwm style layout symbols
|
||||
typeset -A layouts=(
|
||||
[tile]="[]="
|
||||
[mono]="[M]"
|
||||
[none]="><>"
|
||||
[grid]="###"
|
||||
[spiral]="(@)"
|
||||
[dwindle]="[\\]"
|
||||
[tstack]="F^F"
|
||||
)
|
||||
|
||||
clock()
|
||||
{
|
||||
if [[ $1 ]]; then
|
||||
while :; do
|
||||
date +"T%%{A1:$1:} %a %H:%M %%{A}"
|
||||
sleep 60
|
||||
done
|
||||
else
|
||||
while :; do
|
||||
date +"T %a %H:%M "
|
||||
sleep 60
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
battery()
|
||||
{
|
||||
if [[ $1 ]]; then
|
||||
while :; do
|
||||
lvl=$(acpi --battery 2>/dev/null | grep -v 'Unknown\| 0%' | cut -d, -f2 | tr -d '[:space:]')
|
||||
if [[ $lvl ]]; then
|
||||
printf 'B%s\n' "%{A1:$1:} Bat: $(acpi --battery 2>/dev/null | grep -v 'Unknown\| 0%' | cut -d, -f2 | tr -d '[:space:]') %{A}${separator}"
|
||||
sleep 60
|
||||
else
|
||||
return # no battery so we don't need to continue
|
||||
fi
|
||||
done
|
||||
else
|
||||
while :; do
|
||||
lvl=$(acpi --battery 2>/dev/null | grep -v 'Unknown\| 0%' | cut -d, -f2 | tr -d '[:space:]')
|
||||
if [[ $lvl ]]; then
|
||||
printf 'B%s\n' " Bat: $(acpi --battery 2>/dev/null | grep -v 'Unknown\| 0%' | cut -d, -f2 | tr -d '[:space:]') ${separator}"
|
||||
sleep 60
|
||||
else
|
||||
return # no battery so we don't need to continue
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
volume()
|
||||
{
|
||||
if [[ $1 ]]; then
|
||||
while :; do
|
||||
printf 'V%s\n' "%{A1:$1:} Vol: $(pamixer --get-volume-human) %{A}${separator}"
|
||||
sleep 1
|
||||
done
|
||||
else
|
||||
while :; do
|
||||
printf 'V%s\n' " Vol: $(pamixer --get-volume-human) ${separator}"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
network()
|
||||
{
|
||||
check()
|
||||
{
|
||||
if hash nm-online > /dev/null 2>&1 && [[ $(systemctl is-active NetworkManager.service) == "active" ]]; then
|
||||
nm-online > /dev/null 2>&1
|
||||
else
|
||||
ping -qc1 'archlinux.org' > /dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $1 ]]; then
|
||||
until check; do
|
||||
printf 'N%s\n' "%{A1:$1:} disconnected %{A}${separator}"
|
||||
sleep 30
|
||||
done
|
||||
while :; do
|
||||
printf 'N%s\n' "%{A1:$1:} connected %{A}${separator}"
|
||||
sleep 240
|
||||
done
|
||||
else
|
||||
until check; do
|
||||
printf 'N%s\n' " disconnected %{A}${separator}"
|
||||
sleep 30
|
||||
done
|
||||
while :; do
|
||||
printf 'N%s\n' " connected %{A}${separator}"
|
||||
sleep 240
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
parsefifo()
|
||||
{
|
||||
typeset f='' b='' u='' wm='' time='' net='' bat='' vol='' title='' layout=''
|
||||
|
||||
while read -r line; do
|
||||
case $line in
|
||||
T*) time="${line#?}" ;;
|
||||
V*) vol="${line#?}" ;;
|
||||
B*) bat="${line#?}" ;;
|
||||
N*) net="${line#?}" ;;
|
||||
A*) title="${line#?}"; title="${title:0:50}";;
|
||||
L*) l="${line#?}"; layout="${layouts[$l]}" ;;
|
||||
W*)
|
||||
wm='' IFS=':' # set the internal field separator to ':'
|
||||
set -- ${line#?} # split the line into arguments ($@) based on the field separator
|
||||
for item in "$@"; do
|
||||
name=${item#?}
|
||||
case $item in
|
||||
A*) f="$highlight" b="$bg" u="$highlight" ;; # occupied - focused
|
||||
a*) f="$fg" b="$bg" u="$highlight" ;; # occupied - unfocused
|
||||
I*) f="$highlight" b="$bg" u="$fg" ;; # unoccupied - focused
|
||||
i*) f="$fg" b="$bg" u="$fg" ;; # unoccupied - unfocused
|
||||
esac
|
||||
wm="$wm%{F$f}%{B$b}%{+u}%{U$u}%{A:dkcmd ws $name:} $name %{A}%{-u}%{B-}%{F-}"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
printf "%s\n" "%{l}$wm $separator $layout%{c}$title%{r}${net}${bat}${vol}${time}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# kill the process and cleanup if we exit or get killed
|
||||
trap "trap - TERM; kill 0; rm -f '$fifo'" INT TERM QUIT EXIT PIPE
|
||||
|
||||
# make the fifo
|
||||
[ -e "$fifo" ] && rm "$fifo"
|
||||
mkfifo "$fifo"
|
||||
|
||||
|
||||
# here we dump info into the FIFO, order does not matter things are parsed
|
||||
# out using the first character of the line. Click commands for left button
|
||||
# can be added by passing an argument containing the command (like volume below)
|
||||
network 'al-terminal -e nmtui-connect' > "$fifo" &
|
||||
clock 'gsimplecal' > "$fifo" &
|
||||
battery '' > "$fifo" &
|
||||
volume 'pavucontrol' > "$fifo" &
|
||||
dkcmd status type=bar > "$fifo" &
|
||||
|
||||
|
||||
# run the pipeline
|
||||
if [[ $1 == '-b' ]]; then
|
||||
parsefifo < "$fifo" | lemonbar -b -a 32 -u $underline -B "$bg" -F "$fg" -f "$font0" -f "$font1" -f "$font2" -f "$font3" | sh
|
||||
else
|
||||
parsefifo < "$fifo" | lemonbar -a 32 -u $underline -B "$bg" -F "$fg" -f "$font0" -f "$font1" -f "$font2" -f "$font3" | sh
|
||||
fi
|
||||
|
||||
# vim:ft=sh:fdm=marker:fmr={,}
|
94
.local/bin/bash-template.sh
Normal file
94
.local/bin/bash-template.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
trap cleanup SIGINT SIGTERM ERR EXIT
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-c|-i] [-r] [-v eng|userdebug|user] [-j #] [-m <module>] [-s <path/to/keys>] [-p <path/to/pwfile>] [-o] [-f] <device>
|
||||
|
||||
Script description here.
|
||||
|
||||
Available options:
|
||||
|
||||
-h, --help Print this help and exit
|
||||
-c, --clobber Wipe the out directory
|
||||
-i, --installclean Remove installed files
|
||||
-r, --repo-sync Sync repos before build
|
||||
-v, --variant Target build variant (eng, userdebug, user)
|
||||
-j, --jobs Specify how many threads to use (defaults to auto)
|
||||
-m, --module Build a particular module
|
||||
-s, --sign-keys Location of signing keys to sign build with
|
||||
-p, --pwfile Signing keys passwd file if used
|
||||
-o, --ota Generate an OTA zip
|
||||
-f, --fastboot Generate a fastboot images zip
|
||||
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
trap - SIGINT SIGTERM ERR EXIT
|
||||
# script cleanup here
|
||||
}
|
||||
|
||||
setup_colors() {
|
||||
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
|
||||
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m'
|
||||
else
|
||||
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW=''
|
||||
fi
|
||||
}
|
||||
|
||||
msg() {
|
||||
echo >&2 -e "${1-}"
|
||||
}
|
||||
|
||||
die() {
|
||||
local msg=$1
|
||||
local code=${2-1} # default exit status 1
|
||||
msg "$msg"
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
parse_params() {
|
||||
# default values of variables set from params
|
||||
flag=0
|
||||
param=''
|
||||
|
||||
while :; do
|
||||
case "${1-}" in
|
||||
-h | --help) usage ;;
|
||||
-v | --verbose) set -x ;;
|
||||
--no-color) NO_COLOR=1 ;;
|
||||
-f | --flag) flag=1 ;;
|
||||
-p | --param)
|
||||
param="${2-}"
|
||||
shift
|
||||
;;
|
||||
-?*) die "Unknown option: $1" ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
args=("$@")
|
||||
|
||||
# check required params and arguments
|
||||
[[ -z "${param-}" ]] && die "Missing required parameter: param"
|
||||
[[ ${#args[@]} -eq 0 ]] && die "Missing script arguments"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_params "$@"
|
||||
setup_colors
|
||||
|
||||
# script logic here
|
||||
|
||||
msg "${RED}Read parameters:${NOFORMAT}"
|
||||
msg "- flag: ${flag}"
|
||||
msg "- param: ${param}"
|
||||
msg "- arguments: ${args[*]-}"
|
111
.local/bin/best_kernel
Executable file
111
.local/bin/best_kernel
Executable file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
|
||||
from multiprocessing import Event, Pool, Process, Queue
|
||||
from queue import Empty
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
|
||||
def run_subprocess(cmd):
|
||||
sp = Popen(cmd, stdout=PIPE, stderr=PIPE,
|
||||
shell=True, universal_newlines=True)
|
||||
comm = sp.communicate()
|
||||
exit_code = sp.returncode
|
||||
if exit_code != 0:
|
||||
print("There was an error running the subprocess.\n"
|
||||
"cmd: %s\n"
|
||||
"exit code: %d\n"
|
||||
"stdout: %s\n"
|
||||
"stderr: %s" % (cmd, exit_code, comm[0], comm[1]))
|
||||
return comm
|
||||
|
||||
|
||||
def get_tags(tag_name):
|
||||
cmd = "git tag -l %s" % tag_name
|
||||
comm = run_subprocess(cmd)
|
||||
return comm[0].strip("\n").split("\n")
|
||||
|
||||
|
||||
def get_total_changes(tag_name):
|
||||
cmd = "git diff %s --shortstat" % tag_name
|
||||
comm = run_subprocess(cmd)
|
||||
try:
|
||||
a, d = comm[0].split(",")[1:]
|
||||
a = int(a.strip().split()[0])
|
||||
d = int(d.strip().split()[0])
|
||||
except ValueError:
|
||||
total = None
|
||||
else:
|
||||
total = a + d
|
||||
return total
|
||||
|
||||
|
||||
def worker(tag_name):
|
||||
tc = get_total_changes(tag_name)
|
||||
worker.q.put((tag_name, tc))
|
||||
|
||||
|
||||
def worker_init(q):
|
||||
worker.q = q
|
||||
|
||||
|
||||
def background(q, e, s):
|
||||
best = 9999999999999
|
||||
tag = ""
|
||||
while True:
|
||||
try:
|
||||
tn, tc = q.get(False)
|
||||
except Empty:
|
||||
if e.is_set():
|
||||
break
|
||||
else:
|
||||
if not s:
|
||||
print("%s has %d lines changed" % (tn, tc))
|
||||
if best > tc:
|
||||
best = tc
|
||||
tag = tn
|
||||
if not s:
|
||||
print("%s is the new best match with %d lines changed" % (tn, tc))
|
||||
print("Best match")
|
||||
print("TAG: %s" % tag)
|
||||
print("Lines changed: %d" % best)
|
||||
|
||||
|
||||
def main():
|
||||
import argparse # Only needed for main()
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-j", action="store", dest="jobs", default=1, type=int,
|
||||
metavar="N", help="number of jobs to run at once")
|
||||
parser.add_argument("-s", action="store_true", dest="silent", default=False,
|
||||
help="reduce the verbosity of the output")
|
||||
parser.add_argument("tag_name", metavar="<Tag Name>",
|
||||
help="tag name to search for (can contain wildcards)")
|
||||
args = parser.parse_args()
|
||||
|
||||
tags = get_tags(args.tag_name)
|
||||
if not tags:
|
||||
print("No tags to check. bailing.")
|
||||
sys.exit(1)
|
||||
if not args.silent:
|
||||
print("number of tags to check: %d" % len(tags))
|
||||
|
||||
queue = Queue()
|
||||
event = Event()
|
||||
|
||||
b = Process(target=background, args=(queue, event, args.silent))
|
||||
b.start()
|
||||
|
||||
pool = Pool(args.jobs, worker_init, [queue])
|
||||
pool.map(worker, tags)
|
||||
|
||||
pool.close()
|
||||
pool.join()
|
||||
event.set()
|
||||
b.join()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
115
.local/bin/bin2hex.py
Executable file
115
.local/bin/bin2hex.py
Executable file
@ -0,0 +1,115 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format bin2hex convertor utility.'''
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Bin2Hex convertor utility.
|
||||
Usage:
|
||||
python bin2hex.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of bin file for processing.
|
||||
Use '-' for reading from stdin.
|
||||
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
--offset=N offset for loading bin file (default: 0).
|
||||
'''
|
||||
|
||||
offset = 0
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hv",
|
||||
["help", "version", "offset="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("--offset"):
|
||||
base = 10
|
||||
if a[:2].lower() == '0x':
|
||||
base = 16
|
||||
try:
|
||||
offset = int(a, base)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad offset value')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Input file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
from intelhex import compat
|
||||
|
||||
fin = args[0]
|
||||
if fin == '-':
|
||||
# read from stdin
|
||||
fin = compat.get_binary_stdin()
|
||||
elif not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
fout = sys.stdout # compat.get_binary_stdout()
|
||||
|
||||
from intelhex import bin2hex
|
||||
sys.exit(bin2hex(fin, fout, offset))
|
554
.local/bin/bonsai
Executable file
554
.local/bin/bonsai
Executable file
@ -0,0 +1,554 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# I'm a bonsai-making machine!
|
||||
|
||||
#################################################
|
||||
##
|
||||
# author: John Allbritten
|
||||
# my website: theSynAck.com
|
||||
#
|
||||
# repo: https://gitlab.com/jallbrit
|
||||
# script can be found in the bin/bin/fun folder.
|
||||
#
|
||||
# license: this script is published under GPLv3.
|
||||
# I don't care what you do with it, but I do ask
|
||||
# that you leave this message please!
|
||||
#
|
||||
# inspiration: http://andai.tv/bonsai/
|
||||
# andai's version was written in JS and served
|
||||
# as the basis for this script. Originally, this
|
||||
# was just a port.
|
||||
##
|
||||
#################################################
|
||||
|
||||
# ------ vars ------
|
||||
# CLI options
|
||||
|
||||
flag_h=false
|
||||
live=false
|
||||
infinite=false
|
||||
|
||||
termCols=$(tput cols)
|
||||
termRows=$(tput lines)
|
||||
geometry="$((termCols - 1)),$termRows"
|
||||
|
||||
leafchar='&'
|
||||
termColors=false
|
||||
|
||||
message=""
|
||||
flag_m=false
|
||||
basetype=1
|
||||
multiplier=5
|
||||
|
||||
lifeStart=28
|
||||
steptime=0.01 # time between steps
|
||||
|
||||
# non-CLI options
|
||||
lineWidth=4 # words per line
|
||||
|
||||
# ------ parse options ------
|
||||
|
||||
OPTS="hlt:ig:c:Tm:b:M:L:" # the colon means it requires a value
|
||||
LONGOPTS="help,live,time:,infinite,geo:,leaf:,termcolors,message:,base:,multiplier:,life:"
|
||||
|
||||
parsed=$(getopt --options=$OPTS --longoptions=$LONGOPTS -- "$@")
|
||||
eval set -- "${parsed[@]}"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
flag_h=true
|
||||
shift
|
||||
;;
|
||||
|
||||
-l|--live)
|
||||
live=true
|
||||
shift
|
||||
;;
|
||||
|
||||
-t|--time)
|
||||
steptime="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-i|--infinite)
|
||||
infinite=true
|
||||
shift
|
||||
;;
|
||||
|
||||
-g|--geo)
|
||||
geo=$2
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-c|--leaf)
|
||||
leafchar="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-T|--termcolors)
|
||||
termColors=true
|
||||
shift
|
||||
;;
|
||||
|
||||
-m|--message)
|
||||
flag_m=true
|
||||
message="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-b|--basetype)
|
||||
basetype="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-M|--multiplier)
|
||||
multiplier="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
-L|--life)
|
||||
lifeStart="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--) # end of arguments
|
||||
shift
|
||||
break
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "error while parsing CLI options"
|
||||
flag_h=true
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
HELP="Usage: bonsai [-h] [-i] [-l] [-T] [-m message] [-t time]
|
||||
[-g x,y] [ -c char] [-M 0-9]
|
||||
|
||||
bonsai.sh is a static and live bonsai tree generator, written in bash.
|
||||
|
||||
optional args:
|
||||
-l, --live enable live generation
|
||||
-t, --time time time between each step of growth [default: 0.01]
|
||||
-m, --message text attach a message to the tree
|
||||
-b, --basetype 0-2 which ascii-art plant base to use (0 for none) [default: 1]
|
||||
-i, --infinite keep generating trees until quit (2s between each)
|
||||
-T, --termcolors use terminal colors
|
||||
-g, --geo geo set custom geometry [default: fit to terminal]
|
||||
-c, --leaf char character used for leaves [default: &]
|
||||
-M, --multiplier 0-9 branch multiplier; higher equals more branching [default: 5]
|
||||
-L, --life int life of tree; higher equals more overall growth [default: 28]
|
||||
-h, --help show help"
|
||||
|
||||
# check for help
|
||||
$flag_h && echo -e "$HELP" && exit 0
|
||||
|
||||
# geometry processing
|
||||
cols=$(echo "$geometry" | cut -d ',' -f1) # width; X
|
||||
rows=$(echo "$geometry" | cut -d ',' -f2) # height; Y
|
||||
|
||||
IFS=$'\n' # delimit strings by newline
|
||||
tabs 4 # set tabs to 4 spaces
|
||||
|
||||
declare -A gridMessage
|
||||
|
||||
# message processing
|
||||
if [ $flag_m = true ]; then
|
||||
|
||||
messageWidth=20
|
||||
|
||||
# make room for the message to go on the right side
|
||||
cols=$((cols - messageWidth - 8 ))
|
||||
|
||||
# wordwrap message, delimiting by spaces
|
||||
message="$(echo "$message" | fold -sw $messageWidth)"
|
||||
|
||||
# get number of lines in the message
|
||||
messageLineCount=0
|
||||
for line in $message; do
|
||||
messageLineCount=$((messageLineCount + 1))
|
||||
done
|
||||
|
||||
messageOffset=$((rows - messageLineCount - 7))
|
||||
|
||||
# put lines of message into a grid
|
||||
index=$messageOffset
|
||||
for line in $message; do
|
||||
gridMessage[$index]="$line"
|
||||
index=$((index + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
# define colors
|
||||
if [ $termColors = true ]; then
|
||||
LightBrown='\e[1;33m'
|
||||
DarkBrown='\e[0;33m'
|
||||
BrownGreen='\e[1;32m'
|
||||
Green='\e[0;32m'
|
||||
else
|
||||
LightBrown='\e[38;5;172m'
|
||||
DarkBrown='\e[38;5;130m'
|
||||
BrownGreen='\e[38;5;142m'
|
||||
Green='\e[38;5;106m'
|
||||
fi
|
||||
Grey='\e[1;30m'
|
||||
R='\e[0m'
|
||||
|
||||
# create ascii base in lines
|
||||
base=""
|
||||
case $basetype in
|
||||
0)
|
||||
base="" ;;
|
||||
|
||||
1)
|
||||
width=15
|
||||
art="\
|
||||
${Grey}:${Green}___________${DarkBrown}./~~\\.${Green}___________${Grey}:
|
||||
\\ /
|
||||
\\________________________/
|
||||
(_) (_)"
|
||||
;;
|
||||
|
||||
2)
|
||||
width=7
|
||||
art="\
|
||||
${Grey}(${Green}---${DarkBrown}./~~\\.${Green}---${Grey})
|
||||
( )
|
||||
(________)"
|
||||
;;
|
||||
esac
|
||||
|
||||
# get base height
|
||||
baseHeight=0
|
||||
for line in $art; do
|
||||
baseHeight=$(( baseHeight + 1 ))
|
||||
done
|
||||
|
||||
# add spaces before base so that it's in the middle of the terminal
|
||||
iter=1
|
||||
for line in $art; do
|
||||
filler=''
|
||||
for (( i=0; i < $(( (cols / 2) - width )); i++)); do
|
||||
filler+=" "
|
||||
done
|
||||
base+="${filler}${line}"
|
||||
[ $iter -ne $baseHeight ] && base+='\n'
|
||||
iter=$((iter+1))
|
||||
done
|
||||
unset IFS # reset delimiter
|
||||
|
||||
rows=$((rows - baseHeight))
|
||||
|
||||
declare -A grid # must be done outside function for unknown reason
|
||||
|
||||
trap 'echo "press q to quit"' SIGINT # disable CTRL+C
|
||||
|
||||
init() {
|
||||
branches=0
|
||||
shoots=0
|
||||
|
||||
branchesMax=$((multiplier * 110))
|
||||
shootsMax=$multiplier
|
||||
|
||||
# fill grid full of spaces
|
||||
for (( row=0; row < $rows; row++ )); do
|
||||
for (( col=0; col < $cols; col++ )); do
|
||||
grid[$row,$col]=' '
|
||||
done
|
||||
done
|
||||
|
||||
# No echo stdin and hide the cursor
|
||||
if [ $live = true ]; then
|
||||
stty -echo
|
||||
echo -ne "\e[?25l"
|
||||
|
||||
echo -ne "\e[2J"
|
||||
fi
|
||||
}
|
||||
|
||||
grow() {
|
||||
local start=$((cols / 2))
|
||||
|
||||
local x=$((cols / 2)) # start halfway across the screen
|
||||
local y=$rows # start just above the base
|
||||
|
||||
branch $x $y trunk $lifeStart
|
||||
}
|
||||
|
||||
branch() {
|
||||
# argument declarations
|
||||
local x=$1
|
||||
local y=$2
|
||||
local type=$3
|
||||
local life=$4
|
||||
local dx=0
|
||||
local dy=0
|
||||
|
||||
# check if the user is hitting q
|
||||
timeout=0.001
|
||||
[ $live = "false" ] && timeout=.0001
|
||||
read -n 1 -t $timeout input
|
||||
[ "$input" = "q" ] && clean "quit"
|
||||
|
||||
branches=$((branches + 1))
|
||||
|
||||
# as long as we're alive...
|
||||
while [ $life -gt 0 ]; do
|
||||
|
||||
life=$((life - 1)) # ensure life ends
|
||||
|
||||
# case $life in
|
||||
# [0]) type=dead ;;
|
||||
# [1-4]) type=dying ;;
|
||||
# esac
|
||||
|
||||
# set dy based on type
|
||||
case $type in
|
||||
shoot*) # if this is a shoot, trend horizontal/downward growth
|
||||
case "$((RANDOM % 10))" in
|
||||
[0-1]) dy=-1 ;;
|
||||
[2-7]) dy=0 ;;
|
||||
[8-9]) dy=1 ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
dying) # discourage vertical growth
|
||||
case "$((RANDOM % 10))" in
|
||||
[0-1]) dy=-1 ;;
|
||||
[2-8]) dy=0 ;;
|
||||
[9-10]) dy=1 ;;
|
||||
esac
|
||||
;;
|
||||
|
||||
*) # otherwise, let it grow up/not at all
|
||||
dy=0
|
||||
[ $life -ne $lifeStart ] && [ $((RANDOM % 10)) -gt 2 ] && dy=-1
|
||||
;;
|
||||
esac
|
||||
# if we're about to hit the ground, cut it off
|
||||
[ $dy -gt 0 ] && [ $y -gt $(( rows - 1 )) ] && dy=0
|
||||
[ $type = "trunk" ] && [ $life -lt 4 ] && dy=0
|
||||
|
||||
# set dx based on type
|
||||
case $type in
|
||||
shootLeft) # tend left: dx=[-2,1]
|
||||
case $(( RANDOM % 10 )) in
|
||||
[0-1]) dx=-2 ;;
|
||||
[2-5]) dx=-1 ;;
|
||||
[6-8]) dx=0 ;;
|
||||
[9]) dx=1 ;;
|
||||
esac ;;
|
||||
|
||||
shootRight) # tend right: dx=[-1,2]
|
||||
case $(( RANDOM % 10 )) in
|
||||
[0-1]) dx=2 ;;
|
||||
[2-5]) dx=1 ;;
|
||||
[6-8]) dx=0 ;;
|
||||
[9]) dx=-1 ;;
|
||||
esac ;;
|
||||
|
||||
dying) # tend left/right: dx=[-3,3]
|
||||
dx=$(( (RANDOM % 7) - 3)) ;;
|
||||
|
||||
*) # tend equal: dx=[-1,1]
|
||||
dx=$(( (RANDOM % 3) - 1)) ;;
|
||||
|
||||
esac
|
||||
|
||||
# re-branch upon conditions
|
||||
if [ $branches -lt $branchesMax ]; then
|
||||
|
||||
# branch is dead
|
||||
if [ $life -lt 3 ]; then
|
||||
branch $x $y dead $life
|
||||
|
||||
# branch is dying and needs to branch into leaves
|
||||
elif [ $type = trunk ] && [ $life -lt $((multiplier + 2)) ]; then
|
||||
branch $x $y dying $life
|
||||
|
||||
elif [[ $type = "shoot"* ]] && [ $life -lt $((multiplier + 2)) ]; then
|
||||
branch $x $y dying $life
|
||||
|
||||
# re-branch if: not close to the base AND (pass a chance test OR be a trunk, not have too man shoots already, and not be about to die)
|
||||
elif [[ $type = trunk && $life -lt $((lifeStart - 8)) \
|
||||
&& ( $(( RANDOM % (16 - multiplier) )) -eq 0 \
|
||||
|| ($type = trunk && $(( life % 5 )) -eq 0 && $life -gt 5) ) ]]; then
|
||||
|
||||
# if a trunk is splitting and not about to die, chance to create another trunk
|
||||
if [ $((RANDOM % 3)) -eq 0 ] && [ $life -gt 7 ]; then
|
||||
branch $x $y trunk $life
|
||||
|
||||
elif [ $shoots -lt $shootsMax ]; then
|
||||
|
||||
# give the shoot some life
|
||||
tmpLife=$(( life + multiplier - 2 ))
|
||||
[ $tmpLife -lt 0 ] && tmpLife=0
|
||||
|
||||
# first shoot is randomly directed
|
||||
if [ $shoots -eq 0 ]; then
|
||||
tmpType=shootLeft
|
||||
[ $((RANDOM % 2)) -eq 0 ] && tmpType=shootRight
|
||||
|
||||
|
||||
# secondary shoots alternate from the first
|
||||
else
|
||||
case $tmpType in
|
||||
shootLeft) # last shoot was left, shoot right
|
||||
tmpType=shootRight ;;
|
||||
shootRight) # last shoot was right, shoot left
|
||||
tmpType=shootLeft ;;
|
||||
esac
|
||||
fi
|
||||
branch $x $y $tmpType $tmpLife
|
||||
shoots=$((shoots + 1))
|
||||
fi
|
||||
fi
|
||||
else # if we're past max branches but want to branch...
|
||||
char='<>'
|
||||
fi
|
||||
|
||||
# implement dx,dy
|
||||
x=$((x + dx))
|
||||
y=$((y + dy))
|
||||
|
||||
# choose color
|
||||
case $type in
|
||||
trunk|shoot*)
|
||||
color=${DarkBrown}
|
||||
[ $(( RANDOM % 4 )) -eq 0 ] && color=${LightBrown}
|
||||
;;
|
||||
|
||||
dying) color=${BrownGreen} ;;
|
||||
|
||||
dead) color=${Green} ;;
|
||||
esac
|
||||
|
||||
# choose branch character
|
||||
case $type in
|
||||
trunk)
|
||||
if [ $dx -lt 0 ]; then
|
||||
char='\\'
|
||||
elif [ $dx -eq 0 ]; then
|
||||
char='/|'
|
||||
elif [ $dx -gt 0 ]; then
|
||||
char='/'
|
||||
fi
|
||||
[ $dy -eq 0 ] && char='/~' # not growing
|
||||
#[ $dy -lt 0 ] && char='/~' # growing
|
||||
;;
|
||||
|
||||
# shoots tend to look horizontal
|
||||
shootLeft)
|
||||
case $dx in
|
||||
[-3,-1]) char='\\|' ;;
|
||||
[0]) char='/|' ;;
|
||||
[1,3]) char='/' ;;
|
||||
esac
|
||||
#[ $dy -lt 0 ] && char='/~' # growing up
|
||||
[ $dy -gt 0 ] && char='/' # growing down
|
||||
[ $dy -eq 0 ] && char='\\_' # not growing
|
||||
;;
|
||||
|
||||
shootRight)
|
||||
case $dx in
|
||||
[-3,-1]) char='\\|' ;;
|
||||
[0]) char='/|' ;;
|
||||
[1,3]) char='/' ;;
|
||||
esac
|
||||
#[ $dy -lt 0 ] && char='' # growing up
|
||||
[ $dy -gt 0 ] && char='\\' # growing down
|
||||
[ $dy -eq 0 ] && char='_/' # not growing
|
||||
;;
|
||||
|
||||
#dead)
|
||||
# #life=$((life + 1))
|
||||
# char="${leafchar}"
|
||||
# [ $dx -lt -2 ] || [ $dx -gt 2 ] && char="${leafchar}${leafchar}"
|
||||
# ;;
|
||||
|
||||
esac
|
||||
|
||||
# set leaf if needed
|
||||
[ $life -lt 4 ] && char="${leafchar}"
|
||||
|
||||
# uncomment for help debugging
|
||||
#echo -e "$life:\t$x, $y: $char"
|
||||
|
||||
# put character in grid
|
||||
grid[$y,$x]="${color}${char}${R}"
|
||||
|
||||
# if live, print what we have so far and let the user see it
|
||||
if [ $live = true ]; then
|
||||
print
|
||||
sleep $steptime
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
print() {
|
||||
# parse grid for output
|
||||
output=""
|
||||
for (( row=0; row < $rows; row++)); do
|
||||
|
||||
line=""
|
||||
|
||||
for (( col=0; col < $cols; col++ )); do
|
||||
|
||||
# this prints a space at 0,0 and is necessary at the moment
|
||||
[ $live = true ] && echo -ne "\e[0;0H "
|
||||
|
||||
# grab the character from our grid
|
||||
line+="${grid[$row,$col]}"
|
||||
done
|
||||
|
||||
# add our message
|
||||
if [ $flag_m = true ]; then
|
||||
# remove trailing whitespace before we add our message
|
||||
line=$(sed -r 's/[ \t]*$//' <(printf "$line"))
|
||||
line+=" \t${gridMessage[$row]}"
|
||||
fi
|
||||
|
||||
line="${line}\n"
|
||||
|
||||
# end 'er with the ol' newline
|
||||
output+="$line"
|
||||
done
|
||||
|
||||
# add the ascii-art base we generated earlier
|
||||
output+="$base"
|
||||
|
||||
# output, removing trailing whitespace
|
||||
sed -r 's/[ \t]*$//' <(printf "$output")
|
||||
}
|
||||
|
||||
clean() {
|
||||
# Show cursor and echo stdin
|
||||
if [ $live = true ]; then
|
||||
echo -ne "\e[?25h"
|
||||
stty echo
|
||||
fi
|
||||
|
||||
echo "" # ensure the cursor resets to the next line
|
||||
|
||||
# if we wanna quit
|
||||
if [ "$1" = "quit" ]; then
|
||||
trap SIGINT
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
bonsai() {
|
||||
init
|
||||
grow
|
||||
print
|
||||
clean
|
||||
}
|
||||
|
||||
bonsai
|
||||
|
||||
while [ $infinite = true ]; do
|
||||
sleep 2
|
||||
bonsai
|
||||
done
|
204
.local/bin/build-anykernel.sh
Executable file
204
.local/bin/build-anykernel.sh
Executable file
@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Build Script for RenderZenith!
|
||||
# Based off AK's build script - Thanks!
|
||||
#
|
||||
|
||||
# Bash Color
|
||||
rm .version
|
||||
green='\033[01;32m'
|
||||
red='\033[01;31m'
|
||||
blink_red='\033[05;31m'
|
||||
restore='\033[0m'
|
||||
|
||||
clear
|
||||
|
||||
# Resources
|
||||
THREAD="-j$(grep -c ^processor /proc/cpuinfo)"
|
||||
KERNEL="Image.gz"
|
||||
export DEFCONFIG="oneplus6_defconfig"
|
||||
|
||||
# Kernel Details
|
||||
VER=RenderZenith
|
||||
DEVICE=OP6
|
||||
VARIANT="OP6-Q-UNIFIED"
|
||||
|
||||
# Kernel zip name
|
||||
HASH=`git rev-parse --short=8 HEAD`
|
||||
KERNEL_ZIP="RZ-$VARIANT-$(date +%y%m%d)-$HASH"
|
||||
|
||||
# Enable ccache per device
|
||||
CCACHE=ccache
|
||||
export CCACHE_DIR="$HOME/.ccache/kernel/$DEVICE"
|
||||
|
||||
# Vars
|
||||
export LOCALVERSION=~`echo $VER`
|
||||
export ARCH=arm64
|
||||
export SUBARCH=arm64
|
||||
export KBUILD_BUILD_USER=xstefen
|
||||
export KBUILD_BUILD_HOST=leviathan
|
||||
export LOCALVERSION=~`echo $KERNEL_ZIP`
|
||||
|
||||
# Extra make arguments
|
||||
EXTRA_CONFIGS="CONFIG_DEBUG_SECTION_MISMATCH=y"
|
||||
|
||||
# Paths
|
||||
KERNEL_DIR=`pwd`
|
||||
KBUILD_OUTPUT="${KERNEL_DIR}/out"
|
||||
REPACK_DIR="${HOME}/android/AnyKernel3"
|
||||
PATCH_DIR="${HOME}/android/AnyKernel3/patch"
|
||||
MODULES_DIR="${HOME}/android/AnyKernel3/modules"
|
||||
ZIP_MOVE="${HOME}/android/zips"
|
||||
ZIMAGE_DIR="$KBUILD_OUTPUT/arch/arm64/boot"
|
||||
|
||||
# Create output directory
|
||||
mkdir -p $KBUILD_OUTPUT
|
||||
|
||||
# Functions
|
||||
#function checkout_ak3_branches {
|
||||
# cd $REPACK_DIR
|
||||
# git checkout rz-op6-oos-q
|
||||
# cd $KERNEL_DIR
|
||||
#}
|
||||
|
||||
function clean_all {
|
||||
rm -rf $REPACK_DIR/$MODULES_DIR/*
|
||||
rm -f $REPACK_DIR/$KERNEL
|
||||
rm -f $REPACK_DIR/zImage
|
||||
rm -f $REPACK_DIR/dtb
|
||||
echo
|
||||
make O=$KBUILD_OUTPUT clean && make O=$KBUILD_OUTPUT mrproper
|
||||
}
|
||||
|
||||
function make_clang_kernel {
|
||||
export CROSS_COMPILE="${HOME}/android/toolchains/proton-clang/bin/aarch64-linux-gnu-"
|
||||
REAL_CC="${HOME}/android/toolchains/proton-clang/bin/clang"
|
||||
|
||||
echo
|
||||
make $DEFCONFIG O=$KBUILD_OUTPUT $EXTRA_CONFIGS
|
||||
|
||||
echo
|
||||
echo "Building with Clang..."
|
||||
echo
|
||||
|
||||
PATH="${HOME}/android/toolchains/proton-clang/bin:${PATH}" \
|
||||
make $THREAD \
|
||||
ARCH=$ARCH \
|
||||
CC="$CCACHE $REAL_CC" \
|
||||
CROSS_COMPILE="$CROSS_COMPILE" \
|
||||
O=$KBUILD_OUTPUT \
|
||||
$EXTRA_CONFIGS
|
||||
}
|
||||
|
||||
function make_gcc_kernel {
|
||||
export CROSS_COMPILE="${CCACHE} ${HOME}/android/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-"
|
||||
|
||||
echo
|
||||
echo "Building with GCC..."
|
||||
echo
|
||||
|
||||
make O=${KBUILD_OUTPUT} $DEFCONFIG
|
||||
make -s O=${KBUILD_OUTPUT} $THREAD $EXTRA_CONFIGS
|
||||
}
|
||||
|
||||
function make_modules {
|
||||
# Remove and re-create modules directory
|
||||
rm -rf $MODULES_DIR
|
||||
mkdir -p $MODULES_DIR
|
||||
|
||||
# Copy modules over
|
||||
echo
|
||||
find $KBUILD_OUTPUT -name '*.ko' -exec cp -v {} $MODULES_DIR \;
|
||||
|
||||
# Strip modules
|
||||
${CROSS_COMPILE}strip --strip-unneeded $MODULES_DIR/*.ko
|
||||
|
||||
# Sign modules
|
||||
if grep -Fxq "CONFIG_MODULE_SIG=y" $KBUILD_OUTPUT/.config
|
||||
then
|
||||
find $MODULES_DIR -name '*.ko' -exec $KBUILD_OUTPUT/scripts/sign-file sha512 $KBUILD_OUTPUT/certs/signing_key.pem $KBUILD_OUTPUT/certs/signing_key.x509 {} \;
|
||||
fi
|
||||
}
|
||||
|
||||
function make_zip {
|
||||
cp -vr $ZIMAGE_DIR/$KERNEL $REPACK_DIR/$KERNEL
|
||||
find $KBUILD_OUTPUT/arch/arm64/boot/dts -name '*.dtb' -exec cat {} + > $REPACK_DIR/dtb
|
||||
cd $REPACK_DIR
|
||||
zip -r9 $KERNEL_ZIP.zip *
|
||||
mv $KERNEL_ZIP.zip $ZIP_MOVE
|
||||
cd $KERNEL_DIR
|
||||
}
|
||||
|
||||
DATE_START=$(date +"%s")
|
||||
|
||||
echo -e "${green}"
|
||||
echo "RenderZenith creation script:"
|
||||
echo -e "${restore}"
|
||||
|
||||
while read -p "Do you want to clean stuffs (y/n)? " cchoice
|
||||
do
|
||||
case "$cchoice" in
|
||||
y|Y )
|
||||
#checkout_ak3_branches
|
||||
clean_all
|
||||
echo
|
||||
echo "All Cleaned now."
|
||||
break
|
||||
;;
|
||||
n|N )
|
||||
#checkout_ak3_branches
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo
|
||||
echo "Invalid try again!"
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
echo "Pick which toolchain to build with:"
|
||||
select choice in Clang GCC
|
||||
do
|
||||
case "$choice" in
|
||||
"Clang")
|
||||
make_clang_kernel
|
||||
break;;
|
||||
"GCC")
|
||||
make_gcc_kernel
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
while read -p "Do you want to ZIP kernel (y/n)? " dchoice
|
||||
do
|
||||
case "$dchoice" in
|
||||
y|Y)
|
||||
make_modules
|
||||
make_zip
|
||||
break
|
||||
;;
|
||||
n|N )
|
||||
break
|
||||
;;
|
||||
* )
|
||||
echo
|
||||
echo "Invalid try again!"
|
||||
echo
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -e "${green}"
|
||||
echo "-------------------"
|
||||
echo "Build Completed in:"
|
||||
echo "-------------------"
|
||||
echo -e "${restore}"
|
||||
|
||||
DATE_END=$(date +"%s")
|
||||
DIFF=$(($DATE_END - $DATE_START))
|
||||
echo "Time: $(($DIFF / 60)) minute(s) and $(($DIFF % 60)) seconds."
|
||||
echo
|
94
.local/bin/build-cos.sh
Normal file
94
.local/bin/build-cos.sh
Normal file
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
trap cleanup SIGINT SIGTERM ERR EXIT
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-c|-i] [-r] [-v eng|userdebug|user] [-j #] [-m <module>] [-s <path/to/keys>] [-p <path/to/pwfile>] [-o] [-f] <device>
|
||||
|
||||
Script description here.
|
||||
|
||||
Available options:
|
||||
|
||||
-h, --help Print this help and exit
|
||||
-c, --clobber Wipe the out directory
|
||||
-i, --installclean Remove installed files
|
||||
-r, --repo-sync Sync repos before build
|
||||
-v, --variant Target build variant (eng, userdebug, user)
|
||||
-j, --jobs Specify how many threads to use (defaults to auto)
|
||||
-m, --module Build a particular module
|
||||
-s, --sign-keys Location of signing keys to sign build with
|
||||
-p, --pwfile Signing keys passwd file if used
|
||||
-o, --ota Generate an OTA zip
|
||||
-f, --fastboot Generate a fastboot images zip
|
||||
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
trap - SIGINT SIGTERM ERR EXIT
|
||||
# script cleanup here
|
||||
}
|
||||
|
||||
setup_colors() {
|
||||
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
|
||||
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m'
|
||||
else
|
||||
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW=''
|
||||
fi
|
||||
}
|
||||
|
||||
msg() {
|
||||
echo >&2 -e "${1-}"
|
||||
}
|
||||
|
||||
die() {
|
||||
local msg=$1
|
||||
local code=${2-1} # default exit status 1
|
||||
msg "$msg"
|
||||
exit "$code"
|
||||
}
|
||||
|
||||
parse_params() {
|
||||
# default values of variables set from params
|
||||
flag=0
|
||||
param=''
|
||||
|
||||
while :; do
|
||||
case "${1-}" in
|
||||
-h | --help) usage ;;
|
||||
-v | --verbose) set -x ;;
|
||||
--no-color) NO_COLOR=1 ;;
|
||||
-f | --flag) flag=1 ;;
|
||||
-p | --param)
|
||||
param="${2-}"
|
||||
shift
|
||||
;;
|
||||
-?*) die "Unknown option: $1" ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
args=("$@")
|
||||
|
||||
# check required params and arguments
|
||||
[[ -z "${param-}" ]] && die "Missing required parameter: param"
|
||||
[[ ${#args[@]} -eq 0 ]] && die "Missing script arguments"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_params "$@"
|
||||
setup_colors
|
||||
|
||||
# script logic here
|
||||
|
||||
msg "${RED}Read parameters:${NOFORMAT}"
|
||||
msg "- flag: ${flag}"
|
||||
msg "- param: ${param}"
|
||||
msg "- arguments: ${args[*]-}"
|
14
.local/bin/build-kernel
Executable file
14
.local/bin/build-kernel
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
make O=out ARCH=arm64 SUBARCH=arm64 oneplus6_defconfig
|
||||
|
||||
#PATH="/home/xstefen/android/toolchains/clang-11/bin:/home/xstefen/android/toolchains/aarch64-linux-android-4.9/bin:/home/xstefen/android/toolchains/arm-linux-androideabi-4.9/bin:${PATH}" \
|
||||
|
||||
export PATH="$HOME/android/toolchains/proton-clang/bin:$PATH"
|
||||
|
||||
make -j$(nproc --all) O=out \
|
||||
ARCH=arm64 \
|
||||
SUBARCH=arm64 \
|
||||
CC=clang \
|
||||
CROSS_COMPILE=aarch64-linux-gnu- \
|
||||
CROSS_COMPILE_ARM32=arm-linux-gnueabi-
|
1
.local/bin/buildcff2vf
Symbolic link
1
.local/bin/buildcff2vf
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/buildcff2vf
|
1
.local/bin/buildmasterotfs
Symbolic link
1
.local/bin/buildmasterotfs
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/buildmasterotfs
|
4
.local/bin/cache
Executable file
4
.local/bin/cache
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# fc-cache -vf
|
||||
sudo pacman -Scc && sudo pacman -Rsn $(pacman -Qdtq) && rm -rf ~/.cache/thumbnails/* && rm -rf ~/.build/*
|
1
.local/bin/charplot
Symbolic link
1
.local/bin/charplot
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/charplot
|
1
.local/bin/checkoutlinesufo
Symbolic link
1
.local/bin/checkoutlinesufo
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/checkoutlinesufo
|
70
.local/bin/clean
Executable file
70
.local/bin/clean
Executable file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
CLEAN_FILES = [
|
||||
'~/hostr/',
|
||||
'~/.bzr.log',
|
||||
'~/.cache/babl/',
|
||||
'~/.cache/gegl-0.2/',
|
||||
'~/.cache/google-chrome/',
|
||||
'~/.cache/gstreamer-1.0/',
|
||||
'~/.cache/menu/',
|
||||
'~/.cache/thumbnails/',
|
||||
'~/.local/share/gegl-0.2/',
|
||||
'~/.local/share/recently-used.xbel',
|
||||
'~/.local/share/Trash/',
|
||||
'~/.ncmpcpp/error.log',
|
||||
# '~/.npm/',
|
||||
# '~/.nv/',
|
||||
'~/.pki/',
|
||||
'~/.pylint.d/',
|
||||
'~/.recently-used',
|
||||
'~/.thumbnails/',
|
||||
'~/.w3m/',
|
||||
'~/.xsession-errors.old'
|
||||
]
|
||||
|
||||
|
||||
def answer(question, default="n"):
|
||||
prompt = "%s (y/[n]) " % question
|
||||
ans = input(prompt).strip().lower()
|
||||
|
||||
if not ans:
|
||||
ans = default
|
||||
|
||||
if ans == "y":
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def remove_clean():
|
||||
found = []
|
||||
|
||||
print("\n")
|
||||
for jfile in CLEAN_FILES:
|
||||
extra = os.path.expanduser(jfile)
|
||||
if os.path.exists(extra):
|
||||
found.append(extra)
|
||||
print(" %s" % jfile)
|
||||
total = len(found)
|
||||
|
||||
if total == 0:
|
||||
print("No clean files found :)\n")
|
||||
return
|
||||
|
||||
if answer("\nRemove all?", default="n"):
|
||||
for jfile in found:
|
||||
if os.path.isfile(jfile):
|
||||
os.remove(jfile)
|
||||
else:
|
||||
shutil.rmtree(jfile)
|
||||
print("\nAll clean cleaned")
|
||||
|
||||
else:
|
||||
print("\nNo files removed")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
remove_clean()
|
1
.local/bin/comparefamily
Symbolic link
1
.local/bin/comparefamily
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/comparefamily
|
30
.local/bin/deldog
Executable file
30
.local/bin/deldog
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
# Function to upload to del.dog
|
||||
#
|
||||
# This can be downloaded and sourced without any of the other scripts in this repo.
|
||||
#
|
||||
# $ curl -LSsO https://github.com/nathanchance/scripts/raw/master/env/stubs/deldog
|
||||
#
|
||||
# Open the deldog file to make sure it matches this one.
|
||||
#
|
||||
# $ source deldog
|
||||
#
|
||||
# Usage:
|
||||
# $ deldog <file>
|
||||
# $ command |& deldog
|
||||
function deldog() { (
|
||||
for BINARY in curl jq; do
|
||||
command -v ${BINARY} &>/dev/null || {
|
||||
echo "ERROR: ${BINARY} is not installed" >&2
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
[[ -z ${HASTE_URL} ]] && HASTE_URL=https://del.dog
|
||||
[[ -n ${DEL_DOG_API_KEY} && ${HASTE_URL} =~ del ]] && CURL_ARGS=(--header "X-api-key: ${DEL_DOG_API_KEY}")
|
||||
RESULT=$(curl -sf --data-binary @"${1:--}" "${CURL_ARGS[@]}" "${HASTE_URL}"/documents) || {
|
||||
echo "ERROR: failed to post document, ca-certificates might need to be installed" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "${HASTE_URL}/raw/$(jq -r .key <<<"${RESULT}")"
|
||||
); }
|
||||
# vi: filetype=zsh
|
1
.local/bin/detox
Symbolic link
1
.local/bin/detox
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/detox/bin/detox
|
1
.local/bin/detype1
Symbolic link
1
.local/bin/detype1
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/detype1
|
1
.local/bin/digiplot
Symbolic link
1
.local/bin/digiplot
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/digiplot
|
46
.local/bin/dna
Executable file
46
.local/bin/dna
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ANSI color scheme script by pfh
|
||||
#
|
||||
# Initializing mod by lolilolicon from Archlinux
|
||||
#
|
||||
|
||||
f=3 b=4
|
||||
for j in f b; do
|
||||
for i in {0..7}; do
|
||||
printf -v $j$i %b "\e[${!j}${i}m"
|
||||
done
|
||||
done
|
||||
bld=$'\e[1m'
|
||||
rst=$'\e[0m'
|
||||
inv=$'\e[7m'
|
||||
|
||||
cat << EOF
|
||||
|
||||
${f1} █-----${bld}█ ${rst}${f2} █-----${bld}█${rst} ${f3} █-----${bld}█${rst} ${f4} █-----${bld}█${rst} ${f5} █-----${bld}█${rst} ${f6} █-----${bld}█${rst}
|
||||
${f1} █---${bld}█${rst} ${f2} █---${bld}█${rst} ${f3} █---${bld}█${rst} ${f4} █---${bld}█${rst} ${f5} █---${bld}█${rst} ${f6} █---${bld}█${rst}
|
||||
${f1} █-${bld}█${rst} ${f2} █-${bld}█${rst} ${f3} █-${bld}█${rst} ${f4} █-${bld}█${rst} ${f5} █-${bld}█${rst} ${f6} █-${bld}█${rst}
|
||||
${f1} █${rst} ${f2} █${rst} ${f3} █${rst} ${f4} █${rst} ${f5} █${rst} ${f6} █${rst}
|
||||
${f1}${bld} █-${rst}${f1}█${rst} ${f2}${bld} █_${rst}${f2}█${rst} ${f3}${bld} █-${rst}${f3}█${rst} ${f4}${bld} █-${rst}${f4}█${rst} ${f5}${bld} █-${rst}${f5}█${rst} ${f6}${bld} █-${rst}${f6}█${rst}
|
||||
${f1}${bld} █---${rst}${f1}█${rst} ${f2}${bld} █---${rst}${f2}█${rst} ${f3}${bld} █---${rst}${f3}█${rst} ${f4}${bld} █---${rst}${f4}█${rst} ${f5}${bld} █---${rst}${f5}█${rst} ${f6}${bld} █---${rst}${f6}█${rst}
|
||||
${f1}${bld} █-----${rst}${f1}█${rst} ${f2}${bld} █-----${rst}${f2}█${rst} ${f3}${bld} █-----${rst}${f3}█${rst} ${f4}${bld} █-----${rst}${f4}█${rst} ${f5}${bld} █-----${rst}${f5}█${rst} ${f6}${bld} █-----${rst}${f6}█${rst}
|
||||
${f1}${bld} █---${rst}${f1}█${rst} ${f2}${bld} █---${rst}${f2}█${rst} ${f3}${bld} █---${rst}${f3}█${rst} ${f4}${bld} █---${rst}${f4}█${rst} ${f5}${bld} █---${rst}${f5}█${rst} ${f6}${bld} █---${rst}${f6}█${rst}
|
||||
${f1}${bld} █-${rst}${f1}█${rst} ${f2}${bld} █-${rst}${f2}█${rst} ${f3}${bld} █-${rst}${f3}█${rst} ${f4}${bld} █-${rst}${f4}█${rst} ${f5}${bld} █-${rst}${f5}█${rst} ${f6}${bld} █-${rst}${f6}█${rst}
|
||||
${f1}${bld} █${rst} ${f2}${bld} █${rst} ${f3}${bld}█${rst} ${f4}${bld} █${rst} ${f5}${bld} █${rst} ${f6}${bld} █${rst}
|
||||
${f1} █-${bld}█${rst} ${f2} █-${bld}█${rst} ${f3} █-${bld}█${rst} ${f4} █-${bld}█${rst} ${f5} █-${bld}█${rst} ${f6} █-${bld}█${rst}
|
||||
${f1} █---${bld}█${rst} ${f2} █---${bld}█${rst} ${f3} █---${bld}█${rst} ${f4} █---${bld}█${rst} ${f5} █---${bld}█${rst} ${f6} █---${bld}█${rst}
|
||||
${f1} █-----${bld}█ ${rst}${f2} █-----${bld}█${rst} ${f3} █-----${bld}█${rst} ${f4} █-----${bld}█${rst} ${f5} █-----${bld}█${rst} ${f6} █-----${bld}█${rst}
|
||||
${f1} █---${bld}█${rst} ${f2} █---${bld}█${rst} ${f3} █---${bld}█${rst} ${f4} █---${bld}█${rst} ${f5} █---${bld}█${rst} ${f6} █---${bld}█${rst}
|
||||
${f1} █-${bld}█${rst} ${f2} █-${bld}█${rst} ${f3} █-${bld}█${rst} ${f4} █-${bld}█${rst} ${f5} █-${bld}█${rst} ${f6} █-${bld}█${rst}
|
||||
${f1} █${rst} ${f2}█${rst} ${f3} █${rst} ${f4} █${rst} ${f5} █${rst} ${f6} █${rst}
|
||||
${f1}${bld} █-${rst}${f1}█${rst} ${f2}${bld} █_${rst}${f2}█${rst} ${f3}${bld} █-${rst}${f3}█${rst} ${f4}${bld} █-${rst}${f4}█${rst} ${f5}${bld} █-${rst}${f5}█${rst} ${f6}${bld} █-${rst}${f6}█${rst}
|
||||
${f1}${bld} █---${rst}${f1}█${rst} ${f2}${bld} █---${rst}${f2}█${rst} ${f3}${bld} █---${rst}${f3}█${rst} ${f4}${bld} █---${rst}${f4}█${rst} ${f5}${bld} █---${rst}${f5}█${rst} ${f6}${bld} █---${rst}${f6}█${rst}
|
||||
${f1}${bld} █-----${rst}${f1}█${rst} ${f2}${bld} █-----${rst}${f2}█${rst} ${f3}${bld} █-----${rst}${f3}█${rst} ${f4}${bld} █-----${rst}${f4}█${rst} ${f5}${bld} █-----${rst}${f5}█${rst} ${f6}${bld} █-----${rst}${f6}█${rst}
|
||||
${f1}${bld} █---${rst}${f1}█${rst} ${f2}${bld} █---${rst}${f2}█${rst} ${f3}${bld} █---${rst}${f3}█${rst} ${f4}${bld} █---${rst}${f4}█${rst} ${f5}${bld} █---${rst}${f5}█${rst} ${f6}${bld} █---${rst}${f6}█${rst}
|
||||
${f1}${bld} █-${rst}${f1}█${rst} ${f2}${bld} █-${rst}${f2}█${rst} ${f3}${bld} █-${rst}${f3}█${rst} ${f4}${bld} █-${rst}${f4}█${rst} ${f5}${bld} █-${rst}${f5}█${rst} ${f6}${bld} █-${rst}${f6}█${rst}
|
||||
${f1}${bld} █${rst} ${f2}${bld} █${rst} ${f3}${bld} █${rst} ${f4}${bld} █${rst} ${f5}${bld} █${rst} ${f6}${bld} █${rst}
|
||||
${f1} █-${bld}█${rst} ${f2} █-${bld}█${rst} ${f3} █-${bld}█${rst} ${f4} █-${bld}█${rst} ${f5} █-${bld}█${rst} ${f6} █-${bld}█${rst}
|
||||
${f1} █---${bld}█${rst} ${f2} █---${bld}█${rst} ${f3} █---${bld}█${rst} ${f4} █---${bld}█${rst} ${f5} █---${bld}█${rst} ${f6} █---${bld}█${rst}
|
||||
${f1} █-----${bld}█ ${rst}${f2} █-----${bld}█${rst} ${f3} █-----${bld}█${rst} ${f4} █-----${bld}█${rst} ${f5} █-----${bld}█${rst} ${f6} █-----${bld}█${rst}
|
||||
|
||||
EOF
|
240
.local/bin/dot-build.sh
Executable file
240
.local/bin/dot-build.sh
Executable file
@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env bash
|
||||
# dotOS build helper script, credit to @AOSPA, @YumeMichi
|
||||
|
||||
# red = errors, cyan = warnings, green = confirmations, blue = informational
|
||||
# plain for generic text, bold for titles, reset flag at each end of line
|
||||
# plain blue should not be used for readability reasons - use plain cyan instead
|
||||
CLR_RST=$(tput sgr0) ## reset flag
|
||||
CLR_RED=$CLR_RST$(tput setaf 1) # red, plain
|
||||
CLR_GRN=$CLR_RST$(tput setaf 2) # green, plain
|
||||
CLR_BLU=$CLR_RST$(tput setaf 4) # blue, plain
|
||||
CLR_CYA=$CLR_RST$(tput setaf 6) # cyan, plain
|
||||
CLR_BLD=$(tput bold) ## bold flag
|
||||
CLR_BLD_RED=$CLR_RST$CLR_BLD$(tput setaf 1) # red, bold
|
||||
CLR_BLD_GRN=$CLR_RST$CLR_BLD$(tput setaf 2) # green, bold
|
||||
CLR_BLD_BLU=$CLR_RST$CLR_BLD$(tput setaf 4) # blue, bold
|
||||
CLR_BLD_CYA=$CLR_RST$CLR_BLD$(tput setaf 6) # cyan, bold
|
||||
|
||||
# Set defaults
|
||||
DOT_BUILD_VARIANT="userdebug"
|
||||
DOT_MOD_VERSION="v6.0"
|
||||
DOT_BUILD_DATE=$(date -u +%Y%m%d-%H%M)
|
||||
DOT_BUILD_TYPE="UNOFFICIAL_GAPPS"
|
||||
|
||||
function checkExit () {
|
||||
if [ $? -ne 0 ]; then
|
||||
EXIT_CODE=$?
|
||||
echo "${CLR_BLD_RED}Build failed!${CLR_RST}"
|
||||
echo -e ""
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
}
|
||||
|
||||
# Output usage help
|
||||
function showHelpAndExit {
|
||||
echo -e "${CLR_BLD_BLU}Usage: $0 <device> [options]${CLR_RST}"
|
||||
echo -e ""
|
||||
echo -e "${CLR_BLD_BLU}Options:${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -h, --help Display this help message${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -c, --clean Wipe the tree before building${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -i, --installclean Dirty build - Use 'installclean'${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -r, --repo-sync Sync before building${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -t, --build-type Specify build type${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -j, --jobs Specify jobs/threads to use${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -m, --module Build a specific module${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -g, --gms Build with GMS${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -s, --sign-keys Specify path to sign key mappings${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -p, --pwfile Specify path to sign key password file${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -z, --imgzip Generate fastboot flashable image zip from signed target_files${CLR_RST}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Setup getopt.
|
||||
long_opts="help,clean,installclean,repo-sync,build-type:,jobs:,module:,gms,sign-keys:,pwfile:,imgzip"
|
||||
getopt_cmd=$(getopt -o hcir:t:j:m:gs:p:z --long "$long_opts" \
|
||||
-n $(basename $0) -- "$@") || \
|
||||
{ echo -e "${CLR_BLD_RED}\nError: Getopt failed. Extra args\n${CLR_RST}"; showHelpAndExit; exit 1;}
|
||||
|
||||
eval set -- "$getopt_cmd"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h|--help|h|help) showHelpAndExit;;
|
||||
-c|--clean|c|clean) FLAG_CLEAN_BUILD=y;;
|
||||
-i|--installclean|i|installclean) FLAG_INSTALLCLEAN_BUILD=y;;
|
||||
-r|--repo-sync|r|repo-sync) FLAG_SYNC=y;;
|
||||
-t|--build-type|t|build-type) DOT_BUILD_VARIANT="$2"; shift;;
|
||||
-j|--jobs|j|jobs) JOBS="$2"; shift;;
|
||||
-m|--module|m|module) MODULES+=("$2"); echo $2; shift;;
|
||||
-g|--gms|g|gms) FLAG_GMS="y";;
|
||||
-s|--sign-keys|s|sign-keys) KEY_MAPPINGS="$2"; shift;;
|
||||
-p|--pwfile|p|pwfile) PWFILE="$2"; shift;;
|
||||
-z|--imgzip|img|imgzip) FLAG_IMG_ZIP=y;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Mandatory argument
|
||||
if [ $# -eq 0 ]; then
|
||||
echo -e "${CLR_BLD_RED}Error: No device specified${CLR_RST}"
|
||||
showHelpAndExit
|
||||
fi
|
||||
export DEVICE="$1"; shift
|
||||
|
||||
# Make sure we are running on 64-bit before carrying on with anything
|
||||
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
|
||||
if [ "$ARCH" != "64" ]; then
|
||||
echo -e "${CLR_BLD_RED}error: unsupported arch (expected: 64, found: $ARCH)${CLR_RST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up paths
|
||||
#cd $(dirname $0)
|
||||
DIR_ROOT=$(pwd)
|
||||
|
||||
# Make sure everything looks sane so far
|
||||
if [ ! -d "$DIR_ROOT/vendor/dot" ]; then
|
||||
echo -e "${CLR_BLD_RED}error: insane root directory ($DIR_ROOT)${CLR_RST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initializationizing!
|
||||
echo -e "${CLR_BLD_BLU}Setting up the environment${CLR_RST}"
|
||||
echo -e ""
|
||||
. build/envsetup.sh
|
||||
echo -e ""
|
||||
|
||||
# Use the thread count specified by user
|
||||
CMD=""
|
||||
if [ $JOBS ]; then
|
||||
CMD+="-j$JOBS"
|
||||
fi
|
||||
|
||||
# Pick the default thread count (allow overrides from the environment)
|
||||
if [ -z "$JOBS" ]; then
|
||||
if [ "$(uname -s)" = 'Darwin' ]; then
|
||||
JOBS=$(sysctl -n machdep.cpu.core_count)
|
||||
else
|
||||
JOBS=$(cat /proc/cpuinfo | grep '^processor' | wc -l)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Grab the build version
|
||||
DOT_VERSION=dotOS-$DOT_MOD_VERSION-$DEVICE-$DOT_BUILD_TYPE-$DOT_BUILD_DATE
|
||||
|
||||
# Prep for a clean build, if requested so
|
||||
if [ "$FLAG_CLEAN_BUILD" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Cleaning output files left from old builds${CLR_RST}"
|
||||
echo -e ""
|
||||
m clobber "$CMD"
|
||||
fi
|
||||
|
||||
# Sync up, if asked to
|
||||
if [ "$FLAG_SYNC" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Downloading the latest source files${CLR_RST}"
|
||||
echo -e ""
|
||||
repo sync -j"$JOBS" -c --no-clone-bundle --current-branch --no-tags
|
||||
fi
|
||||
|
||||
# GMS
|
||||
if [ "$FLAG_GMS" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Building with GMS${CLR_RST}"
|
||||
echo -e ""
|
||||
export WITH_GMS=true
|
||||
fi
|
||||
|
||||
# Check the starting time (of the real build process)
|
||||
TIME_START=$(date +%s.%N)
|
||||
|
||||
# Friendly logging to tell the user everything is working fine is always nice
|
||||
echo -e "${CLR_BLD_GRN}Building $DOT_VERSION${CLR_RST}"
|
||||
echo -e "${CLR_GRN}Start time: $(date)${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
# Lunch-time!
|
||||
echo -e "${CLR_BLD_BLU}Lunching $DEVICE${CLR_RST} ${CLR_CYA}(Including dependencies sync)${CLR_RST}"
|
||||
echo -e ""
|
||||
lunch "dot_$DEVICE-$DOT_BUILD_VARIANT"
|
||||
checkExit
|
||||
echo -e ""
|
||||
|
||||
# Perform installclean, if requested so
|
||||
if [ "$FLAG_INSTALLCLEAN_BUILD" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Cleaning compiled image files left from old builds${CLR_RST}"
|
||||
echo -e ""
|
||||
m installclean "$CMD"
|
||||
fi
|
||||
|
||||
# Build away!
|
||||
echo -e "${CLR_BLD_BLU}Starting compilation${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
# Build a specific module(s)
|
||||
if [ "${MODULES}" ]; then
|
||||
m ${MODULES[@]} "$CMD"
|
||||
checkExit
|
||||
|
||||
# Build signed rom package if specified
|
||||
elif [ "${KEY_MAPPINGS}" ]; then
|
||||
# Set sign key password file if specified
|
||||
if [ "${PWFILE}" ]; then
|
||||
export ANDROID_PW_FILE=$PWFILE
|
||||
fi
|
||||
|
||||
# Make target-files-package
|
||||
m otatools target-files-package "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
echo -e "${CLR_BLD_BLU}Signing target files apks${CLR_RST}"
|
||||
sign_target_files_apks -o -d $KEY_MAPPINGS \
|
||||
"$OUT"/obj/PACKAGING/target_files_intermediates/dot_$DEVICE-target_files-eng.$USER.zip \
|
||||
signed-target_files.zip
|
||||
checkExit
|
||||
|
||||
if [ "$FLAG_IMG_ZIP" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Generating signed fastboot package${CLR_RST}"
|
||||
img_from_target_files \
|
||||
signed-target_files.zip \
|
||||
$DOT_VERSION-img.zip
|
||||
checkExit
|
||||
else
|
||||
echo -e "${CLR_BLD_BLU}Generating signed install package${CLR_RST}"
|
||||
ota_from_target_files -k $KEY_MAPPINGS/releasekey --block \
|
||||
signed-target_files.zip \
|
||||
$DOT_VERSION.zip
|
||||
checkExit
|
||||
fi
|
||||
|
||||
# Build rom package
|
||||
elif [ "$FLAG_IMG_ZIP" = 'y' ]; then
|
||||
m otatools target-files-package "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
echo -e "${CLR_BLD_BLU}Generating fastboot package${CLR_RST}"
|
||||
img_from_target_files \
|
||||
"$OUT"/obj/PACKAGING/target_files_intermediates/dot_$DEVICE-target_files-eng.$USER.zip \
|
||||
$DOT_VERSION-image.zip
|
||||
|
||||
checkExit
|
||||
|
||||
else
|
||||
m otapackage "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
mv -f $OUT/dot_$DEVICE-ota-eng.$USER.zip $DOT_VERSION.zip
|
||||
echo "Package Complete: $DOT_VERSION.zip"
|
||||
fi
|
||||
echo -e ""
|
||||
|
||||
# Check the finishing time
|
||||
TIME_END=$(date +%s.%N)
|
||||
|
||||
# Log those times at the end as a fun fact of the day
|
||||
echo -e "${CLR_BLD_GRN}Total time elapsed:${CLR_RST} ${CLR_GRN}$(echo "($TIME_END - $TIME_START) / 60" | bc) minutes ($(echo "$TIME_END - $TIME_START" | bc) seconds)${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
exit 0
|
318
.local/bin/dots
Executable file
318
.local/bin/dots
Executable file
@ -0,0 +1,318 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Ctlos Linux https://ctlos.github.io
|
||||
#
|
||||
# Dot file management script using zenity, git & rsync
|
||||
# Written by Nathaniel Maia, November 2017 - March 2018
|
||||
|
||||
# Config ~/.dotsrc
|
||||
# Ignore github ~/.gitignore
|
||||
# git.io/ctldotsrc
|
||||
# wget git.io/ctldots
|
||||
# sudo cp -fv ~/.bin/dots /usr/bin/dots
|
||||
|
||||
# immutable values
|
||||
readonly NAME=$(basename "$0")
|
||||
readonly CFG="$HOME/.${NAME}rc"
|
||||
|
||||
readonly B='\E[1;34m'
|
||||
readonly R='\E[1;31m'
|
||||
readonly G='\E[1;32m'
|
||||
readonly N='\E[0m'
|
||||
readonly BLD='\E[1m'
|
||||
|
||||
readonly WRN="${R}[WARN]${N}:"
|
||||
readonly INF="${B}[INFO]${N}:"
|
||||
readonly YN="${B}[${R}y${B}/${R}${BLD}N${N}${B}]${N}: "
|
||||
|
||||
readonly MENUTXT="\n Enter number or letter and press [Enter]. 0/q to cancel\n\n> "
|
||||
|
||||
readonly MENU="
|
||||
\n\t ${R}1 ${N}| ${R}${BLD}b${N}ackup\t\t-> Backup Files
|
||||
\t${B}------------------------------------------${N}
|
||||
\n\t ${R}2 ${N}| ${R}${BLD}r${N}estore\t\t-> Restore Files
|
||||
\t${B}------------------------------------------${N}"
|
||||
|
||||
|
||||
main_menu() {
|
||||
local choice
|
||||
|
||||
clear
|
||||
echo -e "$MENU"
|
||||
draw_box 12
|
||||
printf "$MENUTXT"
|
||||
read -e -r choice
|
||||
clear
|
||||
|
||||
[[ $choice =~ (v|V) ]] && V="v"
|
||||
|
||||
case "$choice" in
|
||||
0|[Qq]|quit) exit 0 ;;
|
||||
1*|[Bb]*|backup*) [[ $BASE_DIR ]] && { backup_files; exit 0; } || edit_config ;;
|
||||
2*|[Rr]*|restore*) restore_files && exit 0
|
||||
esac
|
||||
|
||||
src_cfg
|
||||
main_menu
|
||||
}
|
||||
|
||||
draw_box() {
|
||||
local h=${1:-12} # $1 Box Height
|
||||
local w=${2:-57} # $2 Box Width
|
||||
local row=${3:-1} # $3 Starting Row
|
||||
local col=${4:-2} # $4 Starting Column
|
||||
local co=${5:-1} # $5 Box Color, 1-7
|
||||
((h--)) # account for corner
|
||||
((w--)) # account for corner
|
||||
local endrow=$((row + h)) # end row
|
||||
local endcol=$((col + w)) # end column
|
||||
echo -ne "\E[3${co}m" # foreground colour
|
||||
|
||||
local hz="-" vt="|" cn="+" # horizontal, vertical, and corner chars
|
||||
|
||||
plot_char() {
|
||||
echo -e "\E[${1};${2}H""$3"
|
||||
}
|
||||
|
||||
local i=0
|
||||
for ((r=row; i<h; r++)); do
|
||||
plot_char "$r" "$col" "$vt" # left side
|
||||
((i++))
|
||||
done
|
||||
i=0
|
||||
for ((r=row; i<h; r++)); do
|
||||
plot_char "$r" "$endcol" "$vt" # right side
|
||||
((i++))
|
||||
done
|
||||
i=0
|
||||
for ((c=col; i<w; c++)); do
|
||||
plot_char "$row" "$c" "$hz" # top side
|
||||
((i++))
|
||||
done
|
||||
i=0
|
||||
for ((c=col; i<w; c++)); do
|
||||
plot_char "$endrow" "$c" "$hz" # bottom side
|
||||
((i++))
|
||||
done
|
||||
|
||||
plot_char "$row" "$col" "$cn" # left-top corner
|
||||
plot_char "$row" "$endcol" "$cn" # right-top corner
|
||||
plot_char "$endrow" "$col" "$cn" # left-bottom corner
|
||||
plot_char "$endrow" "$endcol" "$cn" # right-bottom corner
|
||||
tput sgr0 # Reset colours
|
||||
}
|
||||
|
||||
check_reqs() {
|
||||
if ! hash git rsync &>/dev/null && hash pacman &>/dev/null; then
|
||||
echo -e "\n\n\n\tInstalling:\n\t\tgit\n\t\trsync\n\n\tPlease Wait.."
|
||||
draw_box 8
|
||||
sleep 1
|
||||
clear
|
||||
sudo pacman -S git rsync --noconfirm --needed
|
||||
fi
|
||||
}
|
||||
|
||||
prep_directory() {
|
||||
if [[ $REQ != "True" ]]; then
|
||||
check_reqs
|
||||
if [[ $BASE_DIR ]]; then # is set in config but might not exist yet
|
||||
if [[ ! -d $BASE_DIR ]]; then # is not an existing dir
|
||||
|
||||
if [[ $REPO ]] && grep -wq '^https://.*/.*/.*$' <<< "$REPO"; then # is REPO actually and address
|
||||
git clone "$REPO" "$BASE_DIR"
|
||||
else
|
||||
mkdir -p$V "$BASE_DIR" # local backup
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ -d $BASE_DIR ]] && REQ="True"
|
||||
else
|
||||
echo -e "$WRN BASE_DIR must be set in config to continue. $EXITING"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
clean_backup_dirs() {
|
||||
if [[ ${PREV_BACKUPS[*]} ]] && sub_choice "Perform clean backup (wipe BASE_DIR)" "${R}$BASE_DIR${N}"; then
|
||||
for dir in "${PREV_BACKUPS[@]}"; do
|
||||
if [[ -d $dir ]] && sub_choice "Wipe all files in /$(basename "$dir")" "${R}$dir${N}"; then
|
||||
cd "$dir"
|
||||
git rm -r -f .
|
||||
# rm -rf$V "$dir"
|
||||
[[ $V ]] && sleep 0.5
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
commit_changes() {
|
||||
if grep -q 'https://' <<< "$REPO"; then
|
||||
if sub_choice "Commit and push changes to REPO" "${R}$REPO${N}"; then
|
||||
|
||||
printf "\nEnter commit message below, an example has been provided\n\n> "
|
||||
read -e -i "$(date +%Y.%m.%d) Update " -r comment
|
||||
|
||||
if grep -wq '[a-zA-Z0-9]*' <<< "$comment"; then
|
||||
cd "$BASE_DIR/" || return 1
|
||||
git add .
|
||||
git commit -m "$comment"
|
||||
git push origin "${BRANCH:-HEAD}"
|
||||
else
|
||||
echo "Bad commit message"
|
||||
sleep 1
|
||||
commit_changes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
backup_files() {
|
||||
prep_directory
|
||||
clean_backup_dirs
|
||||
|
||||
if [[ ${USER_PATHS[*]} || ${ROOT_PATHS[*]} ]]; then
|
||||
|
||||
echo -e "$INF ${B}Copying files, please wait..$N\n"
|
||||
for f in "${USER_PATHS[@]}"; do
|
||||
[[ -e $f ]] && rsync -aR$V $f "$BASE_DIR/$USER_DIR/"
|
||||
[[ $V ]] && sleep 0.5
|
||||
done
|
||||
|
||||
for f in "${ROOT_PATHS[@]}"; do
|
||||
[[ -e $f ]] && rsync -aR$V $f "$BASE_DIR/$ROOT_DIR/"
|
||||
[[ $V ]] && sleep 0.5
|
||||
done
|
||||
|
||||
echo -e "$INF ${G}Backup complete$N"
|
||||
sleep 1
|
||||
else
|
||||
echo -e "$WRN No valid file paths were found.."
|
||||
sleep 2
|
||||
fi
|
||||
commit_changes
|
||||
}
|
||||
|
||||
restore_files() {
|
||||
prep_directory
|
||||
if [[ ${PREV_BACKUPS[*]} ]]; then
|
||||
local msg=""
|
||||
|
||||
for x in "${PREV_BACKUPS[@]}"; do
|
||||
if [[ -e $x ]] && sub_choice "Restore everything from /$(basename "$x")" "${R}$x${N}"; then
|
||||
if grep -q "$BASE_DIR/$USER_DIR" <<< "$x"; then
|
||||
rsync -avPC --filter="exclude $ROOT_DIR" "$BASE_DIR/$USER_DIR/" "$HOME/"
|
||||
elif grep -q "$BASE_DIR/$ROOT_DIR" <<< "$x"; then
|
||||
sudo rsync -avn "$BASE_DIR/$ROOT_DIR/" /
|
||||
else
|
||||
echo -e "\n\n\n\t$WRN Unable to restore\n\n\t$x"
|
||||
draw_box 9
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
[[ $V ]] && sleep 0.5
|
||||
done
|
||||
|
||||
else
|
||||
echo -e "\n\n\n\t$INF ${R}No Existing backups to restore${N}"
|
||||
draw_box 9
|
||||
sleep 1
|
||||
fi
|
||||
}
|
||||
|
||||
mk_cfg() {
|
||||
[[ $1 == "new" ]] && edit_config
|
||||
|
||||
for f in "${USER_PATHS[@]}"; do
|
||||
if [[ -e $f ]] && ! grep "$f" <<< "$u_paths"; then
|
||||
u_paths="$u_paths\"$f\"\n"
|
||||
fi
|
||||
done
|
||||
|
||||
for f in "${ROOT_PATHS[@]}"; do
|
||||
if [[ -e $f ]] && ! grep "$f" <<< "$r_paths"; then
|
||||
r_paths="$r_paths\"$f\"\n"
|
||||
fi
|
||||
done
|
||||
|
||||
local cfg="# config file for dfm (dotfile manager)
|
||||
\n# repo https address for cloning & pushing (empty for local backup)
|
||||
REPO=\"$REPO\"
|
||||
\n# branch, defaults to current branch (HEAD)
|
||||
BRANCH=\"$BRANCH\"
|
||||
\n# location where backup folder or repo will be created or cloned
|
||||
BASE_DIR=\"$BASE_DIR\"
|
||||
\n# names for storage directories within BASE_DIR.
|
||||
# created only if needed, stores files from below arrays
|
||||
USER_DIR=\"${USER_DIR}\"
|
||||
ROOT_DIR=\"${ROOT_DIR:-root}\"
|
||||
\n# file paths which will be backed up into the directories above
|
||||
USER_PATHS=(\n$u_paths)
|
||||
\nROOT_PATHS=(\n$r_paths)"
|
||||
|
||||
echo -e "$cfg" > "$CFG" && clear
|
||||
src_cfg
|
||||
}
|
||||
|
||||
edit_config() {
|
||||
$EDITOR "$CFG"
|
||||
src_cfg
|
||||
}
|
||||
|
||||
src_cfg() {
|
||||
PREV_BACKUPS=()
|
||||
! . "$CFG" 2>/dev/null && mk_cfg "new"
|
||||
[[ -d $BASE_DIR/$USER_DIR ]] && PREV_BACKUPS+=("$BASE_DIR/$USER_DIR")
|
||||
[[ -d $BASE_DIR/$ROOT_DIR ]] && PREV_BACKUPS+=("$BASE_DIR/$ROOT_DIR")
|
||||
}
|
||||
|
||||
sub_choice() {
|
||||
local choice
|
||||
|
||||
clear
|
||||
printf "\n\n\n\t$1? $YN\n\n\t$2"
|
||||
draw_box 9
|
||||
tput cup 3 $((${#1} + 17))
|
||||
read -r choice
|
||||
clear
|
||||
|
||||
grep -q '[yY]' <<< "$choice" && return 0 || return 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
|
||||
USAGE:
|
||||
$NAME [OPTIONS..]
|
||||
|
||||
OPTIONS:
|
||||
|
||||
-h,--help Print this usage message
|
||||
-v,--verbose More information output
|
||||
|
||||
Without any options the main dialog menu opens.
|
||||
|
||||
INFO:
|
||||
Configuration is done in: '$CFG'
|
||||
|
||||
A default config will be created if one is not found,
|
||||
followed by opening it in $EDITOR for you to configure.
|
||||
|
||||
Alternatively open your favorite editor and edit it manually.
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
-v|--verbose) V="v" ;;
|
||||
-h|--help) usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
src_cfg
|
||||
main_menu
|
||||
|
||||
exit 0
|
49
.local/bin/dump-it.sh
Executable file
49
.local/bin/dump-it.sh
Executable file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# extract zip
|
||||
dumpdir="$(pwd)/dump_$(date +%m%d%y)"
|
||||
mkdir -pv "${dumpdir}"
|
||||
unzip -j "$1" "payload.bin" -d "${dumpdir}"
|
||||
payload-dumper-go "${dumpdir}/payload.bin" -o "${dumpdir}"
|
||||
|
||||
PARTITIONS="system systemex system_ext system_other vendor cust odm odm_ext oem factory product modem xrom oppo_product opproduct reserve india my_preload my_odm my_stock my_operator my_country my_product my_company my_engineering my_heytap my_custom my_manifest my_carrier my_region my_bigball my_version special_preload vendor_dlkm odm_dlkm"
|
||||
|
||||
for p in $PARTITIONS; do
|
||||
if [[ -e "$p.img" ]]; then
|
||||
mkdir "$p" 2> /dev/null || rm -rf "${p:?}"/*
|
||||
echo "Extracting $p partition"
|
||||
7z x "$p".img -y -o"$p"/ > /dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
rm "$p".img > /dev/null 2>&1
|
||||
else
|
||||
#handling erofs images, which can't be handled by 7z
|
||||
if [ -f $p.img ] && [ $p != "modem" ]; then
|
||||
echo "Couldn't extract $p partition by 7z. Using fsck.erofs."
|
||||
rm -rf "${p}"/*
|
||||
fsck.erofs --extract="$p" "$p".img
|
||||
if [ $? -eq 0 ]; then
|
||||
rm -fv "$p".img > /dev/null 2>&1
|
||||
else
|
||||
echo "Couldn't extract $p partition by fsck.erofs. Using mount loop"
|
||||
sudo mount -o loop -t auto "$p".img "$p"
|
||||
mkdir "${p}_"
|
||||
sudo cp -rf "${p}/"* "${p}_"
|
||||
sudo umount "${p}"
|
||||
sudo cp -rf "${p}_/"* "${p}"
|
||||
sudo rm -rf "${p}_"
|
||||
if [ $? -eq 0 ]; then
|
||||
rm -fv "$p".img > /dev/null 2>&1
|
||||
else
|
||||
echo "Couldn't extract $p partition. It might use an unsupported filesystem."
|
||||
echo "For EROFS: make sure you're using Linux 5.4+ kernel."
|
||||
echo "For F2FS: make sure you're using Linux 5.15+ kernel."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Fix permissions
|
||||
sudo chown "$(whoami)" "$DUMPDIR"/./* -fR
|
||||
sudo chmod -fR u+rwX "$DUMPDIR"/./*
|
8
.local/bin/exrex
Executable file
8
.local/bin/exrex
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from exrex import __main__
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(__main__())
|
550
.local/bin/exrex.py
Executable file
550
.local/bin/exrex.py
Executable file
@ -0,0 +1,550 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This file is part of exrex.
|
||||
#
|
||||
# exrex is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# exrex is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with exrex. If not, see < http://www.gnu.org/licenses/ >.
|
||||
#
|
||||
# (C) 2012- by Adam Tauber, <asciimoo@gmail.com>
|
||||
|
||||
try:
|
||||
from future_builtins import map, range
|
||||
except:
|
||||
pass
|
||||
from re import match, U
|
||||
try:
|
||||
import re._parser as sre_parse
|
||||
except ImportError: # Python < 3.11
|
||||
from re import sre_parse
|
||||
from itertools import tee
|
||||
from random import choice, randint
|
||||
from types import GeneratorType
|
||||
|
||||
from sys import version_info
|
||||
IS_PY3 = version_info[0] == 3
|
||||
IS_PY36_OR_GREATER = IS_PY3 and version_info[1] > 5
|
||||
|
||||
if IS_PY3:
|
||||
unichr = chr
|
||||
|
||||
__all__ = (
|
||||
'generate',
|
||||
'CATEGORIES',
|
||||
'count',
|
||||
'parse',
|
||||
'getone',
|
||||
'sre_to_string',
|
||||
'simplify'
|
||||
)
|
||||
|
||||
CATEGORIES = {
|
||||
sre_parse.CATEGORY_SPACE: sorted(sre_parse.WHITESPACE),
|
||||
sre_parse.CATEGORY_DIGIT: sorted(sre_parse.DIGITS),
|
||||
sre_parse.CATEGORY_WORD: [unichr(x) for x in range(256) if
|
||||
match('\w', unichr(x), U)],
|
||||
sre_parse.CATEGORY_NOT_WORD: [unichr(x) for x in range(256) if
|
||||
match('\W', unichr(x), U)],
|
||||
'category_any': [unichr(x) for x in range(32, 123)]
|
||||
}
|
||||
|
||||
|
||||
def _build_reverse_categories():
|
||||
reverse = {}
|
||||
for key, value in sre_parse.CATEGORIES.items():
|
||||
if not hasattr(value[1], '__iter__'):
|
||||
continue
|
||||
|
||||
for vv in value[1]:
|
||||
if value[0] == sre_parse.IN and vv[0] == sre_parse.CATEGORY:
|
||||
reverse.update({vv[1]: key})
|
||||
|
||||
return reverse
|
||||
|
||||
|
||||
REVERSE_CATEGORIES = _build_reverse_categories()
|
||||
|
||||
|
||||
def comb(g, i):
|
||||
for c in g:
|
||||
g2, i = tee(i)
|
||||
for c2 in g2:
|
||||
yield c + c2
|
||||
|
||||
|
||||
def mappend(g, c):
|
||||
for cc in g:
|
||||
yield cc + c
|
||||
|
||||
|
||||
def dappend(g, d, k):
|
||||
for cc in g:
|
||||
yield cc + d[k]
|
||||
|
||||
|
||||
def _in(d):
|
||||
ret = []
|
||||
neg = False
|
||||
for i in d:
|
||||
if i[0] == sre_parse.RANGE:
|
||||
subs = map(unichr, range(i[1][0], i[1][1] + 1))
|
||||
if neg:
|
||||
for char in subs:
|
||||
try:
|
||||
ret.remove(char)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
ret.extend(subs)
|
||||
elif i[0] == sre_parse.LITERAL:
|
||||
if neg:
|
||||
try:
|
||||
ret.remove(unichr(i[1]))
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
ret.append(unichr(i[1]))
|
||||
elif i[0] == sre_parse.CATEGORY:
|
||||
subs = CATEGORIES.get(i[1], [''])
|
||||
if neg:
|
||||
for char in subs:
|
||||
try:
|
||||
ret.remove(char)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
ret.extend(subs)
|
||||
elif i[0] == sre_parse.NEGATE:
|
||||
ret = list(CATEGORIES['category_any'])
|
||||
neg = True
|
||||
return ret
|
||||
|
||||
|
||||
def prods(orig, ran, items, limit, grouprefs):
|
||||
for o in orig:
|
||||
for r in ran:
|
||||
if r == 0:
|
||||
yield o
|
||||
else:
|
||||
ret = [o]
|
||||
for _ in range(r):
|
||||
ret = ggen(
|
||||
ret, _gen, items, limit=limit, count=False, grouprefs=grouprefs)
|
||||
for i in ret:
|
||||
yield i
|
||||
|
||||
|
||||
def ggen(g1, f, *args, **kwargs):
|
||||
groupref = None
|
||||
grouprefs = kwargs.get('grouprefs', {})
|
||||
if 'groupref' in kwargs.keys():
|
||||
groupref = kwargs.pop('groupref')
|
||||
for a in g1:
|
||||
g2 = f(*args, **kwargs)
|
||||
if isinstance(g2, GeneratorType):
|
||||
for b in g2:
|
||||
grouprefs[groupref] = b
|
||||
yield a + b
|
||||
else:
|
||||
yield g2
|
||||
|
||||
|
||||
def concit(g1, seqs, limit, grouprefs):
|
||||
for a in g1:
|
||||
for s in seqs:
|
||||
for b in _gen(s, limit, grouprefs=grouprefs):
|
||||
yield a + b
|
||||
|
||||
|
||||
def _gen(d, limit=20, count=False, grouprefs=None):
|
||||
"""docstring for _gen"""
|
||||
if grouprefs is None:
|
||||
grouprefs = {}
|
||||
ret = ['']
|
||||
strings = 0
|
||||
literal = False
|
||||
for i in d:
|
||||
if i[0] == sre_parse.IN:
|
||||
subs = _in(i[1])
|
||||
if count:
|
||||
strings = (strings or 1) * len(subs)
|
||||
ret = comb(ret, subs)
|
||||
elif i[0] == sre_parse.LITERAL:
|
||||
literal = True
|
||||
ret = mappend(ret, unichr(i[1]))
|
||||
elif i[0] == sre_parse.CATEGORY:
|
||||
subs = CATEGORIES.get(i[1], [''])
|
||||
if count:
|
||||
strings = (strings or 1) * len(subs)
|
||||
ret = comb(ret, subs)
|
||||
elif i[0] == sre_parse.ANY:
|
||||
subs = CATEGORIES['category_any']
|
||||
if count:
|
||||
strings = (strings or 1) * len(subs)
|
||||
ret = comb(ret, subs)
|
||||
elif i[0] == sre_parse.MAX_REPEAT or i[0] == sre_parse.MIN_REPEAT:
|
||||
items = list(i[1][2])
|
||||
if i[1][1] + 1 - i[1][0] >= limit:
|
||||
r1 = i[1][0]
|
||||
r2 = i[1][0] + limit
|
||||
else:
|
||||
r1 = i[1][0]
|
||||
r2 = i[1][1] + 1
|
||||
ran = range(r1, r2)
|
||||
if count:
|
||||
branch_count = 0
|
||||
for p in ran:
|
||||
branch_count += pow(_gen(items, limit, True, grouprefs), p)
|
||||
strings = (strings or 1) * branch_count
|
||||
|
||||
ret = prods(ret, ran, items, limit, grouprefs)
|
||||
elif i[0] == sre_parse.BRANCH:
|
||||
if count:
|
||||
for x in i[1][1]:
|
||||
strings += _gen(x, limit, True, grouprefs) or 1
|
||||
ret = concit(ret, i[1][1], limit, grouprefs)
|
||||
elif i[0] == sre_parse.SUBPATTERN or i[0] == sre_parse.ASSERT:
|
||||
subexpr = i[1][1]
|
||||
if IS_PY36_OR_GREATER and i[0] == sre_parse.SUBPATTERN:
|
||||
subexpr = i[1][3]
|
||||
if count:
|
||||
strings = (
|
||||
strings or 1) * (sum(ggen([0], _gen, subexpr, limit=limit, count=True, grouprefs=grouprefs)) or 1)
|
||||
ret = ggen(ret, _gen, subexpr, limit=limit, count=False, grouprefs=grouprefs, groupref=i[1][0])
|
||||
# ignore ^ and $
|
||||
elif i[0] == sre_parse.AT:
|
||||
continue
|
||||
elif i[0] == sre_parse.NOT_LITERAL:
|
||||
subs = list(CATEGORIES['category_any'])
|
||||
if unichr(i[1]) in subs:
|
||||
subs.remove(unichr(i[1]))
|
||||
if count:
|
||||
strings = (strings or 1) * len(subs)
|
||||
ret = comb(ret, subs)
|
||||
elif i[0] == sre_parse.GROUPREF:
|
||||
ret = dappend(ret, grouprefs, i[1])
|
||||
elif i[0] == sre_parse.ASSERT_NOT:
|
||||
pass
|
||||
else:
|
||||
print('[!] cannot handle expression ' + repr(i))
|
||||
|
||||
if count:
|
||||
if strings == 0 and literal:
|
||||
inc = True
|
||||
for i in d:
|
||||
if i[0] not in (sre_parse.AT, sre_parse.LITERAL):
|
||||
inc = False
|
||||
if inc:
|
||||
strings = 1
|
||||
return strings
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _randone(d, limit=20, grouprefs=None):
|
||||
if grouprefs is None:
|
||||
grouprefs = {}
|
||||
"""docstring for _randone"""
|
||||
ret = ''
|
||||
for i in d:
|
||||
if i[0] == sre_parse.IN:
|
||||
ret += choice(_in(i[1]))
|
||||
elif i[0] == sre_parse.LITERAL:
|
||||
ret += unichr(i[1])
|
||||
elif i[0] == sre_parse.CATEGORY:
|
||||
ret += choice(CATEGORIES.get(i[1], ['']))
|
||||
elif i[0] == sre_parse.ANY:
|
||||
ret += choice(CATEGORIES['category_any'])
|
||||
elif i[0] == sre_parse.MAX_REPEAT or i[0] == sre_parse.MIN_REPEAT:
|
||||
if i[1][1] + 1 - i[1][0] >= limit:
|
||||
min, max = i[1][0], i[1][0] + limit - 1
|
||||
else:
|
||||
min, max = i[1][0], i[1][1]
|
||||
for _ in range(randint(min, max)):
|
||||
ret += _randone(list(i[1][2]), limit, grouprefs)
|
||||
elif i[0] == sre_parse.BRANCH:
|
||||
ret += _randone(choice(i[1][1]), limit, grouprefs)
|
||||
elif i[0] == sre_parse.SUBPATTERN or i[0] == sre_parse.ASSERT:
|
||||
subexpr = i[1][1]
|
||||
if IS_PY36_OR_GREATER and i[0] == sre_parse.SUBPATTERN:
|
||||
subexpr = i[1][3]
|
||||
subp = _randone(subexpr, limit, grouprefs)
|
||||
if i[1][0]:
|
||||
grouprefs[i[1][0]] = subp
|
||||
ret += subp
|
||||
elif i[0] == sre_parse.AT:
|
||||
continue
|
||||
elif i[0] == sre_parse.NOT_LITERAL:
|
||||
c = list(CATEGORIES['category_any'])
|
||||
if unichr(i[1]) in c:
|
||||
c.remove(unichr(i[1]))
|
||||
ret += choice(c)
|
||||
elif i[0] == sre_parse.GROUPREF:
|
||||
ret += grouprefs[i[1]]
|
||||
elif i[0] == sre_parse.ASSERT_NOT:
|
||||
pass
|
||||
else:
|
||||
print('[!] cannot handle expression "%s"' % str(i))
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def sre_to_string(sre_obj, paren=True):
|
||||
"""sre_parse object to string
|
||||
|
||||
:param sre_obj: Output of sre_parse.parse()
|
||||
:type sre_obj: list
|
||||
:rtype: str
|
||||
"""
|
||||
ret = u''
|
||||
for i in sre_obj:
|
||||
if i[0] == sre_parse.IN:
|
||||
prefix = ''
|
||||
if len(i[1]) and i[1][0][0] == sre_parse.NEGATE:
|
||||
prefix = '^'
|
||||
ret += u'[{0}{1}]'.format(prefix, sre_to_string(i[1], paren=paren))
|
||||
elif i[0] == sre_parse.LITERAL:
|
||||
u = unichr(i[1])
|
||||
ret += u if u not in sre_parse.SPECIAL_CHARS else '\\{0}'.format(u)
|
||||
elif i[0] == sre_parse.CATEGORY:
|
||||
ret += REVERSE_CATEGORIES[i[1]]
|
||||
elif i[0] == sre_parse.ANY:
|
||||
ret += '.'
|
||||
elif i[0] == sre_parse.BRANCH:
|
||||
# TODO simplifications here
|
||||
parts = [sre_to_string(x, paren=paren) for x in i[1][1]]
|
||||
if not any(parts):
|
||||
continue
|
||||
if i[1][0]:
|
||||
if len(parts) == 1:
|
||||
paren = False
|
||||
prefix = ''
|
||||
else:
|
||||
prefix = '?:'
|
||||
branch = '|'.join(parts)
|
||||
if paren:
|
||||
ret += '({0}{1})'.format(prefix, branch)
|
||||
else:
|
||||
ret += '{0}'.format(branch)
|
||||
elif i[0] == sre_parse.SUBPATTERN:
|
||||
subexpr = i[1][1]
|
||||
if IS_PY36_OR_GREATER and i[0] == sre_parse.SUBPATTERN:
|
||||
subexpr = i[1][3]
|
||||
if i[1][0]:
|
||||
ret += '({0})'.format(sre_to_string(subexpr, paren=False))
|
||||
else:
|
||||
ret += '{0}'.format(sre_to_string(subexpr, paren=paren))
|
||||
elif i[0] == sre_parse.NOT_LITERAL:
|
||||
ret += '[^{0}]'.format(unichr(i[1]))
|
||||
elif i[0] == sre_parse.MAX_REPEAT:
|
||||
if i[1][0] == i[1][1]:
|
||||
range_str = '{{{0}}}'.format(i[1][0])
|
||||
else:
|
||||
if i[1][0] == 0 and i[1][1] - i[1][0] == sre_parse.MAXREPEAT:
|
||||
range_str = '*'
|
||||
elif i[1][0] == 1 and i[1][1] - i[1][0] == sre_parse.MAXREPEAT - 1:
|
||||
range_str = '+'
|
||||
else:
|
||||
range_str = '{{{0},{1}}}'.format(i[1][0], i[1][1])
|
||||
ret += sre_to_string(i[1][2], paren=paren) + range_str
|
||||
elif i[0] == sre_parse.MIN_REPEAT:
|
||||
if i[1][0] == 0 and i[1][1] == sre_parse.MAXREPEAT:
|
||||
range_str = '*?'
|
||||
elif i[1][0] == 1 and i[1][1] == sre_parse.MAXREPEAT:
|
||||
range_str = '+?'
|
||||
elif i[1][1] == sre_parse.MAXREPEAT:
|
||||
range_str = '{{{0},}}?'.format(i[1][0])
|
||||
else:
|
||||
range_str = '{{{0},{1}}}?'.format(i[1][0], i[1][1])
|
||||
ret += sre_to_string(i[1][2], paren=paren) + range_str
|
||||
elif i[0] == sre_parse.GROUPREF:
|
||||
ret += '\\{0}'.format(i[1])
|
||||
elif i[0] == sre_parse.AT:
|
||||
if i[1] == sre_parse.AT_BEGINNING:
|
||||
ret += '^'
|
||||
elif i[1] == sre_parse.AT_END:
|
||||
ret += '$'
|
||||
elif i[0] == sre_parse.NEGATE:
|
||||
pass
|
||||
elif i[0] == sre_parse.RANGE:
|
||||
ret += '{0}-{1}'.format(unichr(i[1][0]), unichr(i[1][1]))
|
||||
elif i[0] == sre_parse.ASSERT:
|
||||
if i[1][0]:
|
||||
ret += '(?={0})'.format(sre_to_string(i[1][1], paren=False))
|
||||
else:
|
||||
ret += '{0}'.format(sre_to_string(i[1][1], paren=paren))
|
||||
elif i[0] == sre_parse.ASSERT_NOT:
|
||||
pass
|
||||
else:
|
||||
print('[!] cannot handle expression "%s"' % str(i))
|
||||
return ret
|
||||
|
||||
|
||||
def simplify(regex_string):
|
||||
"""Simplify a regular expression
|
||||
|
||||
:param regex_string: Regular expression
|
||||
:type regex_string: str
|
||||
:rtype: str
|
||||
"""
|
||||
r = parse(regex_string)
|
||||
return sre_to_string(r)
|
||||
|
||||
|
||||
def parse(s):
|
||||
"""Regular expression parser
|
||||
|
||||
:param s: Regular expression
|
||||
:type s: str
|
||||
:rtype: list
|
||||
"""
|
||||
if IS_PY3:
|
||||
r = sre_parse.parse(s, flags=U)
|
||||
else:
|
||||
r = sre_parse.parse(s.decode('utf-8'), flags=U)
|
||||
return list(r)
|
||||
|
||||
|
||||
def generate(s, limit=20):
|
||||
"""Creates a generator that generates all matching strings to a given regular expression
|
||||
|
||||
:param s: Regular expression
|
||||
:type s: str
|
||||
:param limit: Range limit
|
||||
:type limit: int
|
||||
:returns: string generator object
|
||||
"""
|
||||
return _gen(parse(s), limit)
|
||||
|
||||
|
||||
def count(s, limit=20):
|
||||
"""Counts all matching strings to a given regular expression
|
||||
|
||||
:param s: Regular expression
|
||||
:type s: str
|
||||
:param limit: Range limit
|
||||
:type limit: int
|
||||
:rtype: int
|
||||
:returns: number of matching strings
|
||||
"""
|
||||
return _gen(parse(s), limit, count=True)
|
||||
|
||||
|
||||
def getone(regex_string, limit=20):
|
||||
"""Returns a random matching string to a given regular expression
|
||||
"""
|
||||
return _randone(parse(regex_string), limit)
|
||||
|
||||
|
||||
def argparser():
|
||||
import argparse
|
||||
from sys import stdout
|
||||
argp = argparse.ArgumentParser(
|
||||
description='exrex - regular expression string generator')
|
||||
argp.add_argument(
|
||||
'-o', '--output',
|
||||
help='Output file - default is STDOUT',
|
||||
metavar='FILE',
|
||||
default=stdout,
|
||||
type=argparse.FileType('w', encoding='utf-8')
|
||||
)
|
||||
argp.add_argument(
|
||||
'-l', '--limit',
|
||||
help='Max limit for range size - default is 20',
|
||||
default=20,
|
||||
action='store',
|
||||
type=int,
|
||||
metavar='N'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-c', '--count',
|
||||
help='Count matching strings',
|
||||
default=False,
|
||||
action='store_true'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-m', '--max-number',
|
||||
help='Max number of strings - default is -1',
|
||||
default=-1,
|
||||
action='store',
|
||||
type=int,
|
||||
metavar='N'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-r', '--random',
|
||||
help='Returns a random string that matches to the regex',
|
||||
default=False,
|
||||
action='store_true'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-s', '--simplify',
|
||||
help='Simplifies a regular expression',
|
||||
default=False,
|
||||
action='store_true'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-d', '--delimiter',
|
||||
help='Delimiter - default is \\n',
|
||||
default='\n'
|
||||
)
|
||||
argp.add_argument(
|
||||
'-v', '--verbose',
|
||||
action='store_true',
|
||||
help='Verbose mode',
|
||||
default=False
|
||||
)
|
||||
argp.add_argument(
|
||||
'regex',
|
||||
metavar='REGEX',
|
||||
help='REGEX string'
|
||||
)
|
||||
return vars(argp.parse_args())
|
||||
|
||||
|
||||
def __main__():
|
||||
from sys import exit, stderr
|
||||
args = argparser()
|
||||
if args['verbose']:
|
||||
args['output'].write(
|
||||
'%r%s' % (parse(args['regex']), args['delimiter']))
|
||||
if args['count']:
|
||||
args['output'].write(
|
||||
'%d%s' % (count(args['regex'], limit=args['limit']), args['delimiter']))
|
||||
exit(0)
|
||||
if args['random']:
|
||||
args['output'].write(
|
||||
'%s%s' % (getone(args['regex'], limit=args['limit']), args['delimiter']))
|
||||
exit(0)
|
||||
if args['simplify']:
|
||||
args['output'].write(
|
||||
'%s%s' % (simplify(args['regex']), args['delimiter']))
|
||||
exit(0)
|
||||
try:
|
||||
g = generate(args['regex'], args['limit'])
|
||||
except Exception as e:
|
||||
stderr.write('[!] Error: %s\n' % e)
|
||||
exit(1)
|
||||
args['output'].write(next(g))
|
||||
args['max_number'] -= 1
|
||||
for s in g:
|
||||
if args['max_number'] == 0:
|
||||
break
|
||||
args['max_number'] -= 1
|
||||
args['output'].write(args['delimiter'])
|
||||
args['output'].write(s)
|
||||
if args['delimiter'] == '\n':
|
||||
args['output'].write('\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__()
|
52
.local/bin/extract
Executable file
52
.local/bin/extract
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -f "$1" ]]; then
|
||||
case "$1" in
|
||||
*.tar.lrz)
|
||||
b=$(basename "$1" .tar.lrz)
|
||||
lrztar -d "$1" ;;
|
||||
*.lrz)
|
||||
b=$(basename "$1" .lrz)
|
||||
lrunzip "$1" ;;
|
||||
*.tar.bz2)
|
||||
b=$(basename "$1" .tar.bz2)
|
||||
bsdtar xjf "$1" ;;
|
||||
*.bz2)
|
||||
b=$(basename "$1" .bz2)
|
||||
bunzip2 "$1" ;;
|
||||
*.tar.gz)
|
||||
b=$(basename "$1" .tar.gz)
|
||||
bsdtar xzf "$1" ;;
|
||||
*.gz)
|
||||
b=$(basename "$1" .gz)
|
||||
gunzip "$1" ;;
|
||||
*.tar.xz)
|
||||
b=$(basename "$1" .tar.xz)
|
||||
bsdtar Jxf "$1" ;;
|
||||
*.xz)
|
||||
b=$(basename "$1" .gz)
|
||||
xz -d "$1" ;;
|
||||
*.rar)
|
||||
b=$(basename "$1" .rar)
|
||||
unrar e "$1" ;;
|
||||
*.tar)
|
||||
b=$(basename "$1" .tar)
|
||||
bsdtar xf "$1" ;;
|
||||
*.tbz2)
|
||||
b=$(basename "$1" .tbz2)
|
||||
bsdtar xjf "$1" ;;
|
||||
*.tgz)
|
||||
b=$(basename "$1" .tgz)
|
||||
bsdtar xzf "$1" ;;
|
||||
*.zip)
|
||||
b=$(basename "$1" .zip)
|
||||
unzip "$1" ;;
|
||||
*.Z)
|
||||
b=$(basename "$1" .Z)
|
||||
uncompress "$1" ;;
|
||||
*.7z)
|
||||
b=$(basename "$1" .7z)
|
||||
7z x "$1" ;;
|
||||
*) echo "don't know how to extract '$1'..." && return 1;;
|
||||
esac
|
||||
fi
|
1
.local/bin/extract-dtb
Symbolic link
1
.local/bin/extract-dtb
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/extract-dtb/bin/extract-dtb
|
64
.local/bin/extract-vmlinux
Executable file
64
.local/bin/extract-vmlinux
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# ----------------------------------------------------------------------
|
||||
# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
|
||||
#
|
||||
# Inspired from extract-ikconfig
|
||||
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
|
||||
#
|
||||
# (c) 2011 Corentin Chary <corentin.chary@gmail.com>
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
check_vmlinux()
|
||||
{
|
||||
# Use readelf to check if it's a valid ELF
|
||||
# TODO: find a better to way to check that it's really vmlinux
|
||||
# and not just an elf
|
||||
readelf -h $1 > /dev/null 2>&1 || return 1
|
||||
|
||||
cat $1
|
||||
exit 0
|
||||
}
|
||||
|
||||
try_decompress()
|
||||
{
|
||||
# The obscure use of the "tr" filter is to work around older versions of
|
||||
# "grep" that report the byte offset of the line instead of the pattern.
|
||||
|
||||
# Try to find the header ($1) and decompress from here
|
||||
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
|
||||
do
|
||||
pos=${pos%%:*}
|
||||
tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
|
||||
check_vmlinux $tmp
|
||||
done
|
||||
}
|
||||
|
||||
# Check invocation:
|
||||
me=${0##*/}
|
||||
img=$1
|
||||
if [ $# -ne 1 -o ! -s "$img" ]
|
||||
then
|
||||
echo "Usage: $me <kernel-image>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Prepare temp files:
|
||||
tmp=$(mktemp /tmp/vmlinux-XXX)
|
||||
trap "rm -f $tmp" 0
|
||||
|
||||
# That didn't work, so retry after decompression.
|
||||
try_decompress '\037\213\010' xy gunzip
|
||||
try_decompress '\3757zXZ\000' abcde unxz
|
||||
try_decompress 'BZh' xy bunzip2
|
||||
try_decompress '\135\0\0\0' xxx unlzma
|
||||
try_decompress '\211\114\132' xy 'lzop -d'
|
||||
try_decompress '\002!L\030' xxx 'lz4 -d'
|
||||
try_decompress '(\265/\375' xxx unzstd
|
||||
|
||||
# Finally check for uncompressed images or objects:
|
||||
check_vmlinux $img
|
||||
|
||||
# Bail out:
|
||||
echo "$me: Cannot find vmlinux." >&2
|
85
.local/bin/fbpack.py
Normal file
85
.local/bin/fbpack.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Copyright 2021 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
import struct
|
||||
from packedstruct import PackedStruct
|
||||
from collections import OrderedDict
|
||||
|
||||
FBPACK_MAGIC = 0x4b504246 # "FBPK" FastBook PacK
|
||||
FBPACK_VERSION = 2
|
||||
FBPACK_DEFAULT_DATA_ALIGN = 16
|
||||
|
||||
FBPACK_PARTITION_TABLE = 0
|
||||
FBPACK_PARTITION_DATA = 1
|
||||
FBPACK_SIDELOAD_DATA = 2
|
||||
|
||||
|
||||
class PackEntry(PackedStruct):
|
||||
"""Pack entry info."""
|
||||
|
||||
_FIELDS = OrderedDict([
|
||||
('type', 'I'),
|
||||
('name', '36s'),
|
||||
('product', '40s'),
|
||||
('offset', 'Q'),
|
||||
('size', 'Q'),
|
||||
('slotted', 'I'),
|
||||
('crc32', 'I'),
|
||||
])
|
||||
|
||||
def __init__(self, type_=0, name=b'', prod=b'', offset=0, size=0, slotted=0, crc32=0):
|
||||
super(PackEntry, self).__init__(type_, name, prod, offset, size, slotted, crc32)
|
||||
|
||||
|
||||
class PackHeader(PackedStruct):
|
||||
""" A packed image representation """
|
||||
|
||||
_FIELDS = OrderedDict([
|
||||
('magic', 'I'),
|
||||
('version', 'I'),
|
||||
('header_size', 'I'),
|
||||
('entry_header_size', 'I'),
|
||||
('platform', '16s'),
|
||||
('pack_version', '64s'),
|
||||
('slot_type', 'I'),
|
||||
('data_align', 'I'),
|
||||
('total_entries', 'I'),
|
||||
('total_size', 'I'),
|
||||
])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
magic=FBPACK_MAGIC,
|
||||
version=FBPACK_VERSION,
|
||||
header_size=0,
|
||||
entry_header_size=len(PackEntry()),
|
||||
platform=b'',
|
||||
pack_version=b'',
|
||||
slot_type=0,
|
||||
data_align=FBPACK_DEFAULT_DATA_ALIGN,
|
||||
total_entries=0,
|
||||
total_size=0):
|
||||
super(PackHeader, self).__init__(
|
||||
magic,
|
||||
version,
|
||||
header_size,
|
||||
entry_header_size,
|
||||
platform,
|
||||
pack_version,
|
||||
slot_type,
|
||||
data_align,
|
||||
total_entries,
|
||||
total_size)
|
||||
# update header size once we know all fields
|
||||
self.header_size = len(self)
|
256
.local/bin/fbpacktool
Executable file
256
.local/bin/fbpacktool
Executable file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2021 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import logging
|
||||
from fbpack import *
|
||||
|
||||
|
||||
def bytes_to_str(bstr):
|
||||
return bstr.decode().rstrip('\x00')
|
||||
|
||||
|
||||
def print_pack_header(pack):
|
||||
print('magic: {:#x}'.format(pack.magic))
|
||||
print('version: {}'.format(pack.version))
|
||||
print('header size: {}'.format(pack.header_size))
|
||||
print('entry header size: {}'.format(pack.entry_header_size))
|
||||
platform = bytes_to_str(pack.platform)
|
||||
print('platform: {}'.format(platform))
|
||||
pack_version = bytes_to_str(pack.pack_version)
|
||||
print('pack version: {}'.format(pack_version))
|
||||
print('slock type: {}'.format(pack.slot_type))
|
||||
print('data align: {}'.format(pack.data_align))
|
||||
print('total entries: {}'.format(pack.total_entries))
|
||||
print('total size: {}'.format(pack.total_size))
|
||||
|
||||
|
||||
def print_pack_entry(entry, prefix):
|
||||
name = bytes_to_str(entry.name)
|
||||
print('{}name: {}'.format(prefix, name))
|
||||
etype = 'unknown'
|
||||
if entry.type == FBPACK_PARTITION_TABLE:
|
||||
etype = 'partiton table'
|
||||
elif entry.type == FBPACK_PARTITION_DATA:
|
||||
etype = 'partition'
|
||||
elif entry.type == FBPACK_SIDELOAD_DATA:
|
||||
etype = 'sideload'
|
||||
else:
|
||||
print("entry else")
|
||||
print('{}type: {}'.format(prefix, etype))
|
||||
product = bytes_to_str(entry.product)
|
||||
print('{}product: {}'.format(prefix, product))
|
||||
print('{}offset: {:#x} ({})'.format(prefix, entry.offset, entry.offset))
|
||||
print('{}size: {:#x} ({})'.format(prefix, entry.size, entry.size))
|
||||
print('{}slotted: {}'.format(entry.size, bool(entry.slotted)))
|
||||
print('{}crc32: {:#08x}'.format(prefix, entry.crc32))
|
||||
|
||||
|
||||
def cmd_info(args):
|
||||
with open(args.file, 'rb') as f:
|
||||
pack = PackHeader.from_bytes(f.read(len(PackHeader())))
|
||||
|
||||
if pack.version != FBPACK_VERSION:
|
||||
raise NotImplementedError('unsupported version {}'.format(pack.version))
|
||||
|
||||
print("Header:")
|
||||
print_pack_header(pack)
|
||||
|
||||
print('\nEntries:')
|
||||
for i in range(1, pack.total_entries + 1):
|
||||
entry = PackEntry.from_bytes(f.read(len(PackEntry())))
|
||||
print('Entry {}: {{'.format(i))
|
||||
print_pack_entry(entry, ' ')
|
||||
print('}')
|
||||
|
||||
|
||||
def align_up(val, align):
|
||||
return (val + align - 1) & ~(align - 1)
|
||||
|
||||
|
||||
def create_pack_file(file_name, in_dir_name, pack):
|
||||
pack.total_entries = len(pack.entries)
|
||||
offset = pack.header_size + pack.total_entries * pack.entry_header_size
|
||||
with open(file_name, 'wb') as f:
|
||||
# write entries data
|
||||
for entry in pack.entries:
|
||||
# align data
|
||||
offset = align_up(offset, pack.data_align)
|
||||
entry.offset = offset
|
||||
f.seek(offset)
|
||||
fin_name = os.path.join(in_dir_name, entry.filepath)
|
||||
with open(fin_name, 'rb') as fin:
|
||||
data = fin.read()
|
||||
entry.size = len(data)
|
||||
f.write(data)
|
||||
offset += len(data)
|
||||
|
||||
pack.total_size = offset
|
||||
f.seek(0)
|
||||
# write pack header
|
||||
f.write(bytes(pack))
|
||||
# iterate over entries again to write entry header
|
||||
for entry in pack.entries:
|
||||
f.write(bytes(entry))
|
||||
|
||||
|
||||
def cmd_create(args):
|
||||
if args.file.lower().endswith('.xml'):
|
||||
import xmlparser as parser
|
||||
elif args.file.lower().endswith('.yaml'):
|
||||
import yamlparser as parser
|
||||
else:
|
||||
raise NotImplementedError('{} type not supported'.format(args.file))
|
||||
|
||||
pack = parser.parse(args.file)
|
||||
pack.pack_version = bytes(str(args.pack_version).encode('ascii'))
|
||||
pack.header_size = len(pack)
|
||||
|
||||
# create output directory if missing
|
||||
if not os.path.isdir(args.out_dir):
|
||||
os.makedirs(args.out_dir, 0o755)
|
||||
|
||||
file_name = os.path.join(args.out_dir, pack.name + '.img')
|
||||
|
||||
create_pack_file(file_name, args.in_dir, pack)
|
||||
|
||||
|
||||
def product_match(products, product):
|
||||
return product in products.split('|')
|
||||
|
||||
|
||||
def copyfileobj(src, dst, file_size):
|
||||
while file_size > 0:
|
||||
buf = src.read(min(128 * 1024, file_size))
|
||||
dst.write(buf)
|
||||
file_size -= len(buf)
|
||||
|
||||
|
||||
def cmd_unpack(args):
|
||||
with open(args.file, 'rb') as f:
|
||||
pack = PackHeader.from_bytes(f.read(len(PackHeader())))
|
||||
|
||||
if pack.version != FBPACK_VERSION:
|
||||
raise NotImplementedError('unsupported version {}'.format(pack.version))
|
||||
|
||||
entries = []
|
||||
# create list of entries we want to extact
|
||||
for _ in range(pack.total_entries):
|
||||
entry = PackEntry.from_bytes(f.read(len(PackEntry())))
|
||||
name = bytes_to_str(entry.name)
|
||||
if not args.partitions or name in args.partitions:
|
||||
# if both product are valid then match product name too
|
||||
if not args.product or not entry.product or product_match(
|
||||
entry.product, args.product):
|
||||
entries.append(entry)
|
||||
|
||||
if not entries and not args.unpack_ver:
|
||||
raise RuntimeError('no images to unpack')
|
||||
|
||||
# create output directory if it does not exists
|
||||
if not os.path.isdir(args.out_dir):
|
||||
os.makedirs(args.out_dir, 0o755)
|
||||
|
||||
out_files = {}
|
||||
# write file per entry
|
||||
for entry in entries:
|
||||
name = bytes_to_str(entry.name)
|
||||
logging.info(
|
||||
'Unpacking {} (size: {}, offset: {})'.format(
|
||||
name, entry.size, entry.offset))
|
||||
f.seek(entry.offset)
|
||||
entry_filename = os.path.join(args.out_dir, name + '.img')
|
||||
instance = out_files.get(entry_filename, 0) + 1
|
||||
out_files[entry_filename] = instance
|
||||
if instance > 1:
|
||||
entry_filename = os.path.join(args.out_dir, name + '({}).img'.format(instance - 1))
|
||||
with open(entry_filename, 'wb') as entry_file:
|
||||
copyfileobj(f, entry_file, entry.size)
|
||||
|
||||
if args.unpack_ver:
|
||||
ver_file_path = os.path.join(args.out_dir, 'version.txt')
|
||||
with open(ver_file_path, 'w') as ver_file:
|
||||
ver_file.write(bytes_to_str(pack.pack_version))
|
||||
|
||||
logging.info('Done')
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Tool to create/modify/inspect fastboot packed images")
|
||||
parser.add_argument("-v", "--verbosity", action="count", default=0,
|
||||
help="increase output verbosity")
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# info command
|
||||
info = subparsers.add_parser('info')
|
||||
info.add_argument('file', help="packed image file")
|
||||
info.set_defaults(func=cmd_info)
|
||||
|
||||
# create command
|
||||
create = subparsers.add_parser('create')
|
||||
create.add_argument('-d', '--in_dir', help='directory to search for data files', default='.')
|
||||
create.add_argument(
|
||||
'-o',
|
||||
'--out_dir',
|
||||
help='output directory for the packed image',
|
||||
default='.')
|
||||
create.add_argument('-v', '--pack_version', help='Packed image version ', default='')
|
||||
create.add_argument('file', help="config file describing packed image (yaml/xml)")
|
||||
create.set_defaults(func=cmd_create)
|
||||
|
||||
# unpack command
|
||||
unpack = subparsers.add_parser('unpack')
|
||||
unpack.add_argument('-o', '--out_dir', help='directory to store unpacked images', default='.')
|
||||
unpack.add_argument('-p', '--product', help='filter images by product', default='')
|
||||
unpack.add_argument('-v', '--unpack_ver', help='Unpack version to a file', action='store_true')
|
||||
unpack.add_argument('file', help="packed image file")
|
||||
unpack.add_argument('partitions', metavar='PART', type=str, nargs='*',
|
||||
help='Partition names to extract (default all).')
|
||||
unpack.set_defaults(func=cmd_unpack)
|
||||
|
||||
args = parser.parse_args()
|
||||
# make sure a command was passed
|
||||
if not hasattr(args, 'func'):
|
||||
parser.print_usage()
|
||||
print("fbpacktool.py: error: no command was passed")
|
||||
sys.exit(2)
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
log_level = logging.DEBUG
|
||||
if args.verbosity >= 2:
|
||||
log_level = logging.DEBUG
|
||||
elif args.verbosity == 1:
|
||||
log_level = logging.INFO
|
||||
else:
|
||||
log_level = logging.WARNING
|
||||
|
||||
logging.basicConfig(level=log_level)
|
||||
|
||||
# execute command
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
256
.local/bin/fbpacktool.py
Executable file
256
.local/bin/fbpacktool.py
Executable file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2021 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import logging
|
||||
from fbpack import *
|
||||
|
||||
|
||||
def bytes_to_str(bstr):
|
||||
return bstr.decode().rstrip('\x00')
|
||||
|
||||
|
||||
def print_pack_header(pack):
|
||||
print('magic: {:#x}'.format(pack.magic))
|
||||
print('version: {}'.format(pack.version))
|
||||
print('header size: {}'.format(pack.header_size))
|
||||
print('entry header size: {}'.format(pack.entry_header_size))
|
||||
platform = bytes_to_str(pack.platform)
|
||||
print('platform: {}'.format(platform))
|
||||
pack_version = bytes_to_str(pack.pack_version)
|
||||
print('pack version: {}'.format(pack_version))
|
||||
print('slock type: {}'.format(pack.slot_type))
|
||||
print('data align: {}'.format(pack.data_align))
|
||||
print('total entries: {}'.format(pack.total_entries))
|
||||
print('total size: {}'.format(pack.total_size))
|
||||
|
||||
|
||||
def print_pack_entry(entry, prefix):
|
||||
name = bytes_to_str(entry.name)
|
||||
print('{}name: {}'.format(prefix, name))
|
||||
etype = 'unknown'
|
||||
if entry.type == FBPACK_PARTITION_TABLE:
|
||||
etype = 'partiton table'
|
||||
elif entry.type == FBPACK_PARTITION_DATA:
|
||||
etype = 'partition'
|
||||
elif entry.type == FBPACK_SIDELOAD_DATA:
|
||||
etype = 'sideload'
|
||||
else:
|
||||
print("entry else")
|
||||
print('{}type: {}'.format(prefix, etype))
|
||||
product = bytes_to_str(entry.product)
|
||||
print('{}product: {}'.format(prefix, product))
|
||||
print('{}offset: {:#x} ({})'.format(prefix, entry.offset, entry.offset))
|
||||
print('{}size: {:#x} ({})'.format(prefix, entry.size, entry.size))
|
||||
print('{}slotted: {}'.format(entry.size, bool(entry.slotted)))
|
||||
print('{}crc32: {:#08x}'.format(prefix, entry.crc32))
|
||||
|
||||
|
||||
def cmd_info(args):
|
||||
with open(args.file, 'rb') as f:
|
||||
pack = PackHeader.from_bytes(f.read(len(PackHeader())))
|
||||
|
||||
if pack.version != FBPACK_VERSION:
|
||||
raise NotImplementedError('unsupported version {}'.format(pack.version))
|
||||
|
||||
print("Header:")
|
||||
print_pack_header(pack)
|
||||
|
||||
print('\nEntries:')
|
||||
for i in range(1, pack.total_entries + 1):
|
||||
entry = PackEntry.from_bytes(f.read(len(PackEntry())))
|
||||
print('Entry {}: {{'.format(i))
|
||||
print_pack_entry(entry, ' ')
|
||||
print('}')
|
||||
|
||||
|
||||
def align_up(val, align):
|
||||
return (val + align - 1) & ~(align - 1)
|
||||
|
||||
|
||||
def create_pack_file(file_name, in_dir_name, pack):
|
||||
pack.total_entries = len(pack.entries)
|
||||
offset = pack.header_size + pack.total_entries * pack.entry_header_size
|
||||
with open(file_name, 'wb') as f:
|
||||
# write entries data
|
||||
for entry in pack.entries:
|
||||
# align data
|
||||
offset = align_up(offset, pack.data_align)
|
||||
entry.offset = offset
|
||||
f.seek(offset)
|
||||
fin_name = os.path.join(in_dir_name, entry.filepath)
|
||||
with open(fin_name, 'rb') as fin:
|
||||
data = fin.read()
|
||||
entry.size = len(data)
|
||||
f.write(data)
|
||||
offset += len(data)
|
||||
|
||||
pack.total_size = offset
|
||||
f.seek(0)
|
||||
# write pack header
|
||||
f.write(bytes(pack))
|
||||
# iterate over entries again to write entry header
|
||||
for entry in pack.entries:
|
||||
f.write(bytes(entry))
|
||||
|
||||
|
||||
def cmd_create(args):
|
||||
if args.file.lower().endswith('.xml'):
|
||||
import xmlparser as parser
|
||||
elif args.file.lower().endswith('.yaml'):
|
||||
import yamlparser as parser
|
||||
else:
|
||||
raise NotImplementedError('{} type not supported'.format(args.file))
|
||||
|
||||
pack = parser.parse(args.file)
|
||||
pack.pack_version = bytes(str(args.pack_version).encode('ascii'))
|
||||
pack.header_size = len(pack)
|
||||
|
||||
# create output directory if missing
|
||||
if not os.path.isdir(args.out_dir):
|
||||
os.makedirs(args.out_dir, 0o755)
|
||||
|
||||
file_name = os.path.join(args.out_dir, pack.name + '.img')
|
||||
|
||||
create_pack_file(file_name, args.in_dir, pack)
|
||||
|
||||
|
||||
def product_match(products, product):
|
||||
return product in products.split('|')
|
||||
|
||||
|
||||
def copyfileobj(src, dst, file_size):
|
||||
while file_size > 0:
|
||||
buf = src.read(min(128 * 1024, file_size))
|
||||
dst.write(buf)
|
||||
file_size -= len(buf)
|
||||
|
||||
|
||||
def cmd_unpack(args):
|
||||
with open(args.file, 'rb') as f:
|
||||
pack = PackHeader.from_bytes(f.read(len(PackHeader())))
|
||||
|
||||
if pack.version != FBPACK_VERSION:
|
||||
raise NotImplementedError('unsupported version {}'.format(pack.version))
|
||||
|
||||
entries = []
|
||||
# create list of entries we want to extact
|
||||
for _ in range(pack.total_entries):
|
||||
entry = PackEntry.from_bytes(f.read(len(PackEntry())))
|
||||
name = bytes_to_str(entry.name)
|
||||
if not args.partitions or name in args.partitions:
|
||||
# if both product are valid then match product name too
|
||||
if not args.product or not entry.product or product_match(
|
||||
entry.product, args.product):
|
||||
entries.append(entry)
|
||||
|
||||
if not entries and not args.unpack_ver:
|
||||
raise RuntimeError('no images to unpack')
|
||||
|
||||
# create output directory if it does not exists
|
||||
if not os.path.isdir(args.out_dir):
|
||||
os.makedirs(args.out_dir, 0o755)
|
||||
|
||||
out_files = {}
|
||||
# write file per entry
|
||||
for entry in entries:
|
||||
name = bytes_to_str(entry.name)
|
||||
logging.info(
|
||||
'Unpacking {} (size: {}, offset: {})'.format(
|
||||
name, entry.size, entry.offset))
|
||||
f.seek(entry.offset)
|
||||
entry_filename = os.path.join(args.out_dir, name + '.img')
|
||||
instance = out_files.get(entry_filename, 0) + 1
|
||||
out_files[entry_filename] = instance
|
||||
if instance > 1:
|
||||
entry_filename = os.path.join(args.out_dir, name + '({}).img'.format(instance - 1))
|
||||
with open(entry_filename, 'wb') as entry_file:
|
||||
copyfileobj(f, entry_file, entry.size)
|
||||
|
||||
if args.unpack_ver:
|
||||
ver_file_path = os.path.join(args.out_dir, 'version.txt')
|
||||
with open(ver_file_path, 'w') as ver_file:
|
||||
ver_file.write(bytes_to_str(pack.pack_version))
|
||||
|
||||
logging.info('Done')
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Tool to create/modify/inspect fastboot packed images")
|
||||
parser.add_argument("-v", "--verbosity", action="count", default=0,
|
||||
help="increase output verbosity")
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# info command
|
||||
info = subparsers.add_parser('info')
|
||||
info.add_argument('file', help="packed image file")
|
||||
info.set_defaults(func=cmd_info)
|
||||
|
||||
# create command
|
||||
create = subparsers.add_parser('create')
|
||||
create.add_argument('-d', '--in_dir', help='directory to search for data files', default='.')
|
||||
create.add_argument(
|
||||
'-o',
|
||||
'--out_dir',
|
||||
help='output directory for the packed image',
|
||||
default='.')
|
||||
create.add_argument('-v', '--pack_version', help='Packed image version ', default='')
|
||||
create.add_argument('file', help="config file describing packed image (yaml/xml)")
|
||||
create.set_defaults(func=cmd_create)
|
||||
|
||||
# unpack command
|
||||
unpack = subparsers.add_parser('unpack')
|
||||
unpack.add_argument('-o', '--out_dir', help='directory to store unpacked images', default='.')
|
||||
unpack.add_argument('-p', '--product', help='filter images by product', default='')
|
||||
unpack.add_argument('-v', '--unpack_ver', help='Unpack version to a file', action='store_true')
|
||||
unpack.add_argument('file', help="packed image file")
|
||||
unpack.add_argument('partitions', metavar='PART', type=str, nargs='*',
|
||||
help='Partition names to extract (default all).')
|
||||
unpack.set_defaults(func=cmd_unpack)
|
||||
|
||||
args = parser.parse_args()
|
||||
# make sure a command was passed
|
||||
if not hasattr(args, 'func'):
|
||||
parser.print_usage()
|
||||
print("fbpacktool.py: error: no command was passed")
|
||||
sys.exit(2)
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
log_level = logging.DEBUG
|
||||
if args.verbosity >= 2:
|
||||
log_level = logging.DEBUG
|
||||
elif args.verbosity == 1:
|
||||
log_level = logging.INFO
|
||||
else:
|
||||
log_level = logging.WARNING
|
||||
|
||||
logging.basicConfig(level=log_level)
|
||||
|
||||
# execute command
|
||||
args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
5
.local/bin/figfonts.sh
Executable file
5
.local/bin/figfonts.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
figlist | awk '/fonts/ {f=1;next} /control/ {f=0} f {print}' | while read font; do
|
||||
echo "=== $font ==="
|
||||
echo $font | figlet -f $font
|
||||
done | less
|
14
.local/bin/fix_dot_perms
Executable file
14
.local/bin/fix_dot_perms
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
chown -R $(whoami) ~/.gnupg/
|
||||
find ~/.gnupg -type f -exec chmod 600 {} \;
|
||||
find ~/.gnupg -type d -exec chmod 700 {} \;
|
||||
|
||||
chmod 700 ~/.ssh
|
||||
chmod 644 ~/.ssh/known_hosts
|
||||
chmod 644 ~/.ssh/config
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
chmod 644 ~/.ssh/id_ed25519.pub
|
||||
|
||||
eval "$(ssh-agent -s)"
|
||||
ssh-add ~/.ssh/id_ed25519
|
33
.local/bin/flash_oneplus
Executable file
33
.local/bin/flash_oneplus
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
images=(
|
||||
abl
|
||||
aop
|
||||
bluetooth
|
||||
boot
|
||||
cmnlib64
|
||||
cmnlib
|
||||
devcfg
|
||||
dsp
|
||||
dtbo
|
||||
fw_4j1ed
|
||||
fw_4u1ea
|
||||
hyp
|
||||
keymaster
|
||||
LOGO
|
||||
modem
|
||||
qupfw
|
||||
storsec
|
||||
system
|
||||
tz
|
||||
vbmeta
|
||||
vendor
|
||||
xbl
|
||||
xbl_config
|
||||
)
|
||||
|
||||
for image in "${images[@]}"; do
|
||||
fastboot flash ${image}_a $image.img
|
||||
fastboot flash ${image}_b $image.img
|
||||
done
|
||||
fastboot flash oem_stanvbk oem_stanvbk.img
|
20
.local/bin/flashit
Executable file
20
.local/bin/flashit
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Dispatching brickware!.."
|
||||
echo ""
|
||||
|
||||
fastboot flash boot boot.img
|
||||
fastboot flash dtbo dtbo.img
|
||||
fastboot flash system system.img
|
||||
fastboot flash vbmeta --disable-verity --disable-verification vbmeta.img
|
||||
|
||||
echo ""
|
||||
read -r -p "Reboot? [Y/n] " response
|
||||
case $response in
|
||||
[nN][oO]|[nN])
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "Good luck!.."; fastboot reboot
|
||||
;;
|
||||
esac
|
1
.local/bin/fontplot
Symbolic link
1
.local/bin/fontplot
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/fontplot
|
1
.local/bin/fontplot2
Symbolic link
1
.local/bin/fontplot2
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/fontplot2
|
1
.local/bin/fontsetplot
Symbolic link
1
.local/bin/fontsetplot
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/fontsetplot
|
347
.local/bin/food
Executable file
347
.local/bin/food
Executable file
@ -0,0 +1,347 @@
|
||||
#!/bin/sh
|
||||
# food: {ascii/ansi} art food in your terminal
|
||||
#
|
||||
# ████ ██
|
||||
# ░██░ ░██
|
||||
# ██████ ██████ ██████ ░██
|
||||
# ░░░██░ ██░░░░██ ██░░░░██ ██████
|
||||
# ░██ ░██ ░██░██ ░██ ██░░░██
|
||||
# ░██ ░██ ░██░██ ░██░██ ░██
|
||||
# ░██ ░░██████ ░░██████ ░░██████
|
||||
# ░░ ░░░░░░ ░░░░░░ ░░░░░░
|
||||
#
|
||||
# ▓▓▓▓▓▓▓▓▓▓
|
||||
# ░▓ author ▓ xero <x@xero.nu>
|
||||
# ░▓ code ▓ http://code.xero.nu/dotfiles
|
||||
# ░▓ mirror ▓ http://git.io/.files
|
||||
# ░▓▓▓▓▓▓▓▓▓▓
|
||||
# ░░░░░░░░░░
|
||||
|
||||
usage() {
|
||||
printf "usage: `basename $0` \n\
|
||||
[--burger burger] curl -L git.io/burger\n\
|
||||
[--coffee coffee] curl -L git.io/coffee\n\
|
||||
[--hotcoffee hotcoffee] curl -Ls git.io/hotcoffee | sh\n\
|
||||
[--pancakes pancakes] curl -L git.io/pancakes\n\
|
||||
[--pizza pizza] curl -L git.io/pizzza\n\
|
||||
[--pizza2 pizza2] curl -L git.io/pizzza\n\
|
||||
[--poptart poptart] curl -L git.io/poptart\n\
|
||||
[--rice rice] curl -L git.io/rice\n\
|
||||
[--vburger vburger] curl -L git.io/vburger\n\
|
||||
[--waffles waffles] curl -L git.io/waffles\n\
|
||||
[--help help]\n"
|
||||
}
|
||||
|
||||
taco() {
|
||||
cat << TACO
|
||||
[49m
|
||||
[38;5;16m▄▄▄▄[48;5;16m [38;5;220m▄[49m[38;5;16m▄ ▄[48;5;16m[38;5;28m▄▄[49m[38;5;16m▄▄▄
|
||||
▄[48;5;16m[38;5;94m▄[38;5;208m▄[38;5;94m▄[48;5;94m[38;5;220m▄[48;5;166m [48;5;208m▄[48;5;94m[38;5;16m▄▄[48;5;16m[38;5;94m▄▄▄▄▄▄▄[48;5;28m[38;5;16m▄▄[48;5;16m [49m
|
||||
▄▄[48;5;16m[38;5;94m▄[48;5;220m▄ [48;5;94m[38;5;220m▄[48;5;166m [48;5;220m[38;5;16m▄[48;5;16m[38;5;94m▄▄[48;5;94m[38;5;220m▄▄[48;5;220m [38;5;100m▄ [48;5;94m[38;5;220m▄[48;5;220m [38;5;100m▄ [48;5;94m [38;5;220m▄[48;5;16m[38;5;94m▄[49m[38;5;16m▄
|
||||
▄[48;5;16m[38;5;166m▄▄[48;5;220m[38;5;94m▄[38;5;166m▄ ▄[38;5;16m▄[48;5;16m[38;5;94m▄[48;5;94m[38;5;220m▄[48;5;220m[38;5;100m▄ [38;5;94m▄ [48;5;94m[38;5;220m▄[48;5;220m [38;5;100m▄ [48;5;94m[38;5;220m▄[48;5;16m[38;5;94m▄[49m[38;5;16m▄
|
||||
▀[48;5;166m▄[48;5;220m[38;5;94m▄[38;5;28m▄[48;5;94m▄[48;5;166m[38;5;88m▄[48;5;220m[38;5;52m▄[38;5;16m▄[48;5;16m[38;5;94m▄[48;5;94m[38;5;220m▄[48;5;220m [48;5;100m▄[48;5;220m [48;5;100m▄[48;5;220m [38;5;100m▄ ▄ [48;5;94m [48;5;16m [49m
|
||||
[38;5;16m▄[48;5;16m[38;5;22m▄[48;5;40m▄[48;5;94m [48;5;208m[38;5;40m▄[48;5;40m [48;5;88m▄[48;5;52m▄[48;5;16m [48;5;94m [48;5;220m [48;5;100m[38;5;220m▄[48;5;220m [48;5;94m▄[48;5;220m [48;5;100m▄[48;5;220m [38;5;100m▄ [48;5;94m[38;5;220m▄[48;5;220m [38;5;100m▄[48;5;100m[38;5;94m▄[48;5;16m [49m
|
||||
[48;5;16m [48;5;40m[38;5;22m▄[48;5;22m[38;5;40m▄▄[48;5;40m[38;5;88m▄[48;5;88m[38;5;52m▄[48;5;52m[38;5;40m▄[48;5;16m [48;5;94m [48;5;220m[38;5;100m▄ [48;5;100m[38;5;220m▄[48;5;220m [48;5;100m▄[48;5;220m [48;5;100m▄[48;5;220m[38;5;100m▄▄[48;5;100m[38;5;94m▄▄[48;5;94m [48;5;16m [49m
|
||||
[38;5;16m▄[48;5;16m[38;5;28m▄[48;5;40m[38;5;22m▄[48;5;88m[38;5;52m▄▄[48;5;40m[38;5;22m▄[38;5;88m▄[38;5;52m▄[38;5;28m▄[48;5;16m [48;5;94m [48;5;220m [48;5;100m[38;5;220m▄[48;5;220m[38;5;94m▄ [38;5;100m▄ ▄▄[48;5;100m[38;5;94m▄▄[48;5;94m [38;5;16m▄▄[48;5;16m[38;5;240m▄▄[48;5;240m [49m[38;5;243m▄
|
||||
[48;5;16m [38;5;233m▄[48;5;22m[38;5;58m▄[48;5;40m [38;5;233m▄[48;5;52m▄▄[48;5;16m [48;5;94m [48;5;220m [48;5;94m[38;5;220m▄[48;5;220m[38;5;100m▄ ▄▄[48;5;100m[38;5;94m▄▄[48;5;94m [38;5;16m▄▄[48;5;16m[38;5;240m▄▄[48;5;240m [38;5;243m▄▄[49m▀▀
|
||||
[38;5;16m▀[48;5;58m▄[48;5;233m [48;5;58m[38;5;233m▄ [48;5;233m [48;5;58m▄[48;5;16m [48;5;94m [48;5;220m [38;5;100m▄▄[48;5;100m[38;5;94m▄▄[48;5;94m [38;5;16m▄▄[48;5;16m[38;5;240m▄▄[48;5;240m [38;5;243m▄▄[49m▀▀
|
||||
[48;5;16m [48;5;58m[38;5;233m▄[48;5;233m[38;5;58m▄ [48;5;58m[38;5;16m▄[48;5;16m[38;5;100m▄[48;5;94m▄[48;5;100m[38;5;94m▄▄[48;5;94m [38;5;16m▄▄[48;5;16m[38;5;240m▄▄[48;5;240m [38;5;243m▄▄[49m▀▀
|
||||
[48;5;16m[38;5;240m▄▄[48;5;233m[38;5;16m▄[48;5;58m▄[48;5;16m [48;5;94m▄▄▄[48;5;16m[38;5;240m▄▄[48;5;240m [38;5;243m▄▄[49m▀▀
|
||||
▀[38;5;240m▀▀[48;5;240m[38;5;243m▄▄▄▄▄▄[49m[38;5;240m▀[38;5;243m▀▀
|
||||
[39m
|
||||
[0m
|
||||
TACO
|
||||
}
|
||||
|
||||
pizza() {
|
||||
cat << PIZZA
|
||||
[38;5;16m▄[m[38;5;16m▄[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;220;38;5;16m▀[m[48;5;220;38;5;16m▀[m[48;5;223;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[38;5;16m▄[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;223;38;5;220m▀[m[48;5;223;38;5;220m▀[m[48;5;220;38;5;223m▀[m[48;5;220;38;5;223m▀[m[48;5;220;38;5;223m▀[m[48;5;203;38;5;220m▀[m[48;5;209;38;5;227m▀[m[48;5;16m [m
|
||||
[38;5;16m▄[m[48;5;223;38;5;16m▀[m[48;5;220;38;5;16m▀[m[48;5;223m [m[48;5;223m [m[48;5;220m [m[48;5;220;38;5;223m▀[m[48;5;203;38;5;220m▀[m[48;5;209;38;5;220m▀[m[48;5;227;38;5;203m▀[m[48;5;229;38;5;203m▀[m[48;5;229;38;5;203m▀[m[48;5;222;38;5;203m▀[m[48;5;222;38;5;215m▀[m[48;5;221m [m[48;5;221;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;220m [m[48;5;220;38;5;223m▀[m[48;5;220;38;5;223m▀[m[48;5;203;38;5;220m▀[m[48;5;203;38;5;220m▀[m[48;5;209;38;5;203m▀[m[48;5;229;38;5;209m▀[m[48;5;229;38;5;227m▀[m[48;5;222;38;5;229m▀[m[48;5;222;38;5;229m▀[m[48;5;160;38;5;222m▀[m[48;5;160;38;5;222m▀[m[48;5;160;38;5;221m▀[m[48;5;222;38;5;221m▀[m[48;5;222;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;220;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;223;38;5;220m▀[m[48;5;223;38;5;220m▀[m[48;5;220m [m[48;5;220;38;5;223m▀[m[48;5;203;38;5;220m▀[m[48;5;203;38;5;220m▀[m[48;5;209;38;5;203m▀[m[48;5;229;38;5;209m▀[m[48;5;229m [m[48;5;229m [m[48;5;229;38;5;222m▀[m[48;5;160;38;5;222m▀[m[48;5;160;38;5;172m▀[m[48;5;160;38;5;172m▀[m[48;5;160m [m[48;5;160;38;5;124m▀[m[48;5;124;38;5;160m▀[m[48;5;160;38;5;172m▀[m[48;5;160;38;5;216m▀[m[48;5;221;38;5;16m▀[m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;223m [m[48;5;223;38;5;220m▀[m[48;5;223;38;5;220m▀[m[48;5;220;38;5;223m▀[m[48;5;203;38;5;220m▀[m[48;5;203;38;5;220m▀[m[48;5;203m [m[48;5;160;38;5;172m▀[m[48;5;160m [m[48;5;160;38;5;124m▀[m[48;5;172;38;5;160m▀[m[48;5;160;38;5;222m▀[m[48;5;222;38;5;229m▀[m[48;5;216;38;5;221m▀[m[48;5;209;38;5;221m▀[m[48;5;222;38;5;124m▀[m[48;5;124m [m[48;5;124m [m[48;5;124;38;5;160m▀[m[48;5;124;38;5;160m▀[m[48;5;160m [m[48;5;124;38;5;160m▀[m[48;5;216;38;5;160m▀[m[48;5;216;38;5;222m▀[m[48;5;222;38;5;221m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;222;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220m [m[48;5;220;38;5;203m▀[m[48;5;220;38;5;203m▀[m[48;5;220;38;5;209m▀[m[48;5;124m [m[48;5;124;38;5;160m▀[m[48;5;124;38;5;160m▀[m[48;5;172;38;5;160m▀[m[48;5;223;38;5;160m▀[m[48;5;227;38;5;229m▀[m[48;5;229;38;5;222m▀[m[48;5;229;38;5;216m▀[m[48;5;229;38;5;222m▀[m[48;5;229m [m[48;5;229m [m[48;5;229;38;5;160m▀[m[48;5;222;38;5;124m▀[m[48;5;222;38;5;124m▀[m[48;5;209m [m[48;5;209m [m[48;5;216;38;5;229m▀[m[48;5;216;38;5;229m▀[m[48;5;229m [m[48;5;16m [m
|
||||
[38;5;16m▀[m[48;5;16;38;5;137m▀[m[48;5;137;38;5;222m▀[m[48;5;137;38;5;222m▀[m[48;5;222m [m[48;5;222m [m[48;5;222m [m[48;5;222;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220m [m[48;5;220;38;5;227m▀[m[48;5;220;38;5;227m▀[m[48;5;160;38;5;227m▀[m[48;5;160m [m[48;5;160m [m[48;5;160m [m[48;5;124;38;5;160m▀[m[48;5;124;38;5;160m▀[m[48;5;160;38;5;221m▀[m[48;5;229;38;5;222m▀[m[48;5;221;38;5;228m▀[m[48;5;221m [m[48;5;221m [m[48;5;229m [m[48;5;160;38;5;222m▀[m[48;5;160m [m[48;5;124;38;5;160m▀[m[48;5;160;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;137;38;5;222m▀[m[48;5;137;38;5;222m▀[m[48;5;222m [m[48;5;222;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220m [m[48;5;220;38;5;124m▀[m[48;5;220;38;5;124m▀[m[48;5;124m [m[48;5;124m [m[48;5;124;38;5;160m▀[m[48;5;160m [m[48;5;229m [m[48;5;229m [m[48;5;229m [m[48;5;221;38;5;229m▀[m[48;5;216;38;5;172m▀[m[48;5;124m [m[48;5;124;38;5;160m▀[m[48;5;160;38;5;124m▀[m[48;5;160;38;5;16m▀[m[48;5;160;38;5;16m▀[m[38;5;16m▄[m
|
||||
[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;137;38;5;222m▀[m[48;5;137;38;5;222m▀[m[48;5;222m [m[48;5;222;38;5;220m▀[m[48;5;215;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220;38;5;124m▀[m[48;5;220;38;5;124m▀[m[48;5;220;38;5;124m▀[m[48;5;220;38;5;160m▀[m[48;5;227;38;5;229m▀[m[48;5;227;38;5;229m▀[m[48;5;229m [m[48;5;222;38;5;221m▀[m[48;5;215;38;5;216m▀[m[48;5;209;38;5;124m▀[m[48;5;221;38;5;124m▀[m[48;5;124;38;5;160m▀[m[48;5;160m [m[48;5;160m [m[48;5;16m [m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;222;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220;38;5;227m▀[m[48;5;220;38;5;160m▀[m[48;5;124;38;5;160m▀[m[48;5;124m [m[48;5;160m [m[48;5;124;38;5;166m▀[m[48;5;160;38;5;221m▀[m[48;5;221;38;5;228m▀[m[48;5;221;38;5;228m▀[m[48;5;216;38;5;221m▀[m[48;5;221;38;5;16m▀[m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;215m [m[48;5;16m [m[38;5;16m▀[m[48;5;16;38;5;137m▀[m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;215;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;220;38;5;124m▀[m[48;5;220;38;5;124m▀[m[48;5;220;38;5;160m▀[m[48;5;227;38;5;209m▀[m[48;5;227;38;5;209m▀[m[48;5;229;38;5;221m▀[m[48;5;229;38;5;221m▀[m[48;5;229;38;5;16m▀[m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;229;38;5;221m▀[m[48;5;229;38;5;16m▀[m[38;5;16m▄[m [38;5;16m▀[m[48;5;16;38;5;215m▀[m[48;5;215;38;5;221m▀[m[48;5;221;38;5;215m▀[m[48;5;221;38;5;215m▀[m[48;5;16;38;5;215m▀[m[48;5;137;38;5;215m▀[m[48;5;137;38;5;222m▀[m[48;5;137;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;222;38;5;220m▀[m[48;5;222;38;5;227m▀[m[48;5;220;38;5;227m▀[m[48;5;220;38;5;227m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;221m [m[48;5;229m [m[48;5;16m [m [38;5;16m▀[m[48;5;16;38;5;215m▀[m[48;5;221m [m[48;5;16m [m [38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[48;5;16;38;5;137m▀[m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m [48;5;16m [m[48;5;221m [m[48;5;16m [m
|
||||
[38;5;16m▄[m[48;5;229;38;5;16m▀[m[48;5;229;38;5;221m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;221m [m[48;5;229m [m[48;5;16m [m
|
||||
[38;5;16m▀[m[38;5;16m▀[m
|
||||
[0m
|
||||
PIZZA
|
||||
}
|
||||
|
||||
pizza2() {
|
||||
cat << PIZZA
|
||||
[49m [38;5;16m▄▄[48;5;16m[38;5;214m▄▄▄▄▄[38;5;172m▄▄[49m[38;5;16m▄
|
||||
▄[48;5;16m[38;5;214m▄▄[48;5;214m[38;5;221m▄[38;5;222m▄ [48;5;221m[38;5;214m▄▄[48;5;214m [38;5;172m▄▄[48;5;172m [48;5;16m [49m
|
||||
[38;5;16m▄[48;5;16m[38;5;172m▄[48;5;172m [38;5;222m▄[48;5;222m[38;5;214m▄[48;5;214m [38;5;172m▄▄[48;5;172m [38;5;136m▄▄▄▄ [48;5;124m[38;5;88m▄[48;5;16m [49m
|
||||
[38;5;16m▄[48;5;233m[38;5;172m▄[48;5;172m [48;5;214m ▄ [48;5;172m[38;5;214m▄[38;5;136m▄[48;5;136m [38;5;88m▄[48;5;88m [38;5;160m▄[38;5;223m▄[38;5;196m▄[38;5;124m▄[48;5;124m[38;5;222m▄[48;5;160m[38;5;215m▄[48;5;16m [49m
|
||||
[38;5;16m▄[48;5;16m[38;5;136m▄▄[48;5;172m [38;5;214m▄[48;5;214m [38;5;172m▄[48;5;172m [48;5;214m[38;5;136m▄[48;5;172m▄[48;5;136m[38;5;88m▄▄[48;5;88m[38;5;160m▄[48;5;160m[38;5;223m▄[48;5;124m▄[48;5;196m[38;5;222m▄[38;5;160m▄▄[48;5;94m▄[48;5;124m▄[48;5;223m▄[48;5;16m[38;5;215m▄[49m[38;5;16m▄
|
||||
[48;5;16m [48;5;136m [48;5;172m [48;5;214m[38;5;172m▄[48;5;172m [48;5;214m[38;5;136m▄[48;5;136m [38;5;88m▄[38;5;160m▄[48;5;88m▄[38;5;223m▄[48;5;223m [38;5;94m▄ [48;5;160m▄[38;5;222m▄[48;5;223m [48;5;196m[38;5;223m▄▄[48;5;222m [48;5;16m [49m
|
||||
[38;5;16m▀[48;5;136m▄ [48;5;214m [48;5;136m [38;5;88m▄[48;5;88m[38;5;124m▄[48;5;223m[38;5;196m▄[48;5;160m▄[38;5;223m▄[48;5;222m[38;5;94m▄[48;5;223m[38;5;222m▄[38;5;94m▄[48;5;222m [38;5;223m▄▄[48;5;223m[38;5;124m▄[48;5;124m [48;5;196m▄ [48;5;223m[38;5;196m▄[48;5;222m [48;5;196m[38;5;215m▄[48;5;16m [49m
|
||||
[38;5;16m▀[48;5;214m▄[48;5;88m[38;5;214m▄[38;5;221m▄[48;5;196m[38;5;124m▄[38;5;222m▄[48;5;223m▄[38;5;22m▄▄▄[48;5;222m[38;5;196m▄[48;5;196m[38;5;223m▄▄[48;5;223m [48;5;124m▄ ▄[48;5;223m [48;5;215m[38;5;222m▄[48;5;16m[38;5;215m▄[49m[38;5;16m▄
|
||||
▀▀[48;5;214m▄[48;5;124m[38;5;234m▄[48;5;22m[38;5;221m▄[38;5;222m▄[48;5;222m [48;5;22m[38;5;223m▄ [48;5;223m[38;5;160m▄ [38;5;124m▄[38;5;196m▄[48;5;124m▄[48;5;160m [38;5;223m▄[38;5;222m▄▄[48;5;222m[38;5;223m▄ [48;5;16m [49m
|
||||
[38;5;16m▀[48;5;221m▄[48;5;160m[38;5;214m▄[48;5;22m [48;5;160m[38;5;124m▄[48;5;124m[38;5;222m▄[38;5;223m▄[48;5;223m [38;5;94m▄[38;5;58m▄[48;5;222m[38;5;223m▄[48;5;223m [48;5;196m [38;5;222m▄[48;5;16m[38;5;215m▄[49m[38;5;16m▄
|
||||
▀[38;5;233m▀[48;5;124m[38;5;16m▄[48;5;196m[38;5;214m▄[48;5;223m[38;5;124m▄[48;5;222m[38;5;196m▄[48;5;223m[38;5;222m▄▄[48;5;58m [48;5;223m [48;5;196m[38;5;124m▄[48;5;223m[38;5;222m▄[48;5;222m [48;5;215m▄[48;5;16m [49m[38;5;16m▄
|
||||
▀[48;5;124m▄[38;5;214m▄[38;5;196m▄▄[38;5;222m▄▄▄ [48;5;223m[38;5;124m▄ [48;5;222m [48;5;215m [48;5;16m [49m
|
||||
[38;5;16m▀▀[48;5;221m▄▄[48;5;196m[38;5;221m▄[48;5;124m[38;5;196m▄[38;5;222m▄[48;5;223m▄ [48;5;222m[38;5;160m▄[48;5;16m▄[49m[38;5;16m▄
|
||||
▀[48;5;221m▄[48;5;222m▄[48;5;124m[38;5;221m▄[48;5;223m[38;5;222m▄ [48;5;215m [48;5;16m [49m
|
||||
[38;5;16m▀[48;5;124m▄[48;5;196m▄[38;5;221m▄[48;5;222m[38;5;223m▄[48;5;16m[38;5;222m▄[49m[38;5;16m▄
|
||||
▀▀[48;5;215m▄[48;5;16m [39;49m
|
||||
[0m
|
||||
PIZZA
|
||||
}
|
||||
|
||||
pancakes() {
|
||||
cat << PANCAKES
|
||||
[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[48;5;214;38;5;130m▀[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m[38;5;130m▄[m
|
||||
[38;5;130m▄[m[38;5;130m▄[m[38;5;221m▄[m[38;5;221m▄[m[48;5;214;38;5;130m▀[m[48;5;214;38;5;130m▀[m[48;5;214;38;5;221m▀[m[48;5;214;38;5;221m▀[m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172;38;5;214m▀[m[48;5;214;38;5;130m▀[m[48;5;214;38;5;130m▀[m[38;5;172m▄[m[38;5;172m▄[m[38;5;130m▄[m
|
||||
[38;5;130m▄[m[38;5;221m▄[m[48;5;221m [m[48;5;214;38;5;221m▀[m[48;5;214m [m[48;5;221;38;5;214m▀[m[48;5;221m [m[48;5;214m [m[48;5;214m [m[48;5;221;38;5;214m▀[m[48;5;214m [m[48;5;214m [m[48;5;166;38;5;214m▀[m[48;5;229;38;5;214m▀[m[48;5;229;38;5;208m▀[m[48;5;229;38;5;166m▀[m[48;5;229;38;5;166m▀[m[48;5;226;38;5;166m▀[m[48;5;226;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;214m [m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[38;5;172m▄[m
|
||||
[38;5;130m▄[m[48;5;214;38;5;130m▀[m[48;5;223;38;5;214m▀[m[48;5;214m [m[48;5;214m [m[48;5;221m [m[48;5;214m [m[48;5;214m [m[48;5;221;38;5;214m▀[m[48;5;214;38;5;221m▀[m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;208;38;5;227m▀[m[48;5;208;38;5;227m▀[m[48;5;208;38;5;227m▀[m[48;5;166;38;5;227m▀[m[48;5;166;38;5;226m▀[m[48;5;172;38;5;226m▀[m[48;5;172;38;5;226m▀[m[48;5;172m [m[48;5;214m [m[48;5;172m [m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[38;5;130m▄[m
|
||||
[48;5;130m [m[48;5;214m [m[48;5;223m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214;38;5;221m▀[m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;223;38;5;172m▀[m[48;5;130m [m
|
||||
[38;5;130m▀[m[48;5;130;38;5;223m▀[m[48;5;223m [m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;214m [m[48;5;214m [m[48;5;214;38;5;221m▀[m[48;5;214;38;5;221m▀[m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;214m [m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;223;38;5;214m▀[m[48;5;223;38;5;172m▀[m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;223m [m[48;5;172;38;5;130m▀[m[38;5;130m▄[m
|
||||
[38;5;130m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;130;38;5;223m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;172m [m[48;5;130m [m
|
||||
[48;5;130m [m[48;5;223m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;130;38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;130;38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;172m [m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;223m [m[48;5;130m [m
|
||||
[48;5;130m [m[48;5;223m [m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;214m [m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172;38;5;214m▀[m[48;5;172m [m[48;5;172;38;5;214m▀[m[48;5;223;38;5;172m▀[m[48;5;172;38;5;223m▀[m[48;5;223m [m[48;5;130m [m
|
||||
[38;5;130m▀[m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;214;38;5;223m▀[m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;214;38;5;223m▀[m[48;5;172;38;5;223m▀[m[48;5;223;38;5;172m▀[m[48;5;223;38;5;172m▀[m[48;5;223m [m[48;5;223m [m[48;5;172;38;5;130m▀[m[48;5;130m [m
|
||||
[48;5;130m [m[48;5;214m [m[48;5;214;38;5;130m▀[m[48;5;130;38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;130;38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;172m [m[48;5;220m [m[48;5;130m [m
|
||||
[48;5;130m [m[48;5;223;38;5;214m▀[m[48;5;214;38;5;223m▀[m[48;5;223;38;5;214m▀[m[48;5;214m [m[48;5;214;38;5;172m▀[m[48;5;214;38;5;172m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;214;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;220;38;5;172m▀[m[48;5;220;38;5;172m▀[m[48;5;220;38;5;172m▀[m[48;5;220m [m[48;5;130m [m
|
||||
[48;5;130;38;5;223m▀[m[48;5;223m [m[48;5;223;38;5;214m▀[m[48;5;223m [m[48;5;223m [m[48;5;214m [m[48;5;214m [m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;172m▀[m[48;5;223;38;5;172m▀[m[48;5;223;38;5;214m▀[m[48;5;214;38;5;172m▀[m[48;5;214m [m[48;5;220m [m[48;5;220m [m[48;5;223;38;5;172m▀[m[48;5;220;38;5;172m▀[m[48;5;130;38;5;220m▀[m[38;5;130m▀[m
|
||||
[38;5;130m▀[m[38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;130;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;220;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;223;38;5;214m▀[m[48;5;220;38;5;214m▀[m[48;5;220m [m[48;5;220m [m[48;5;130;38;5;223m▀[m[48;5;130;38;5;220m▀[m[38;5;220m▀[m[38;5;220m▀[m
|
||||
[38;5;130m▀[m[38;5;130m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[48;5;130;38;5;220m▀[m[38;5;130m▀[m[38;5;130m▀[m
|
||||
[0m
|
||||
PANCAKES
|
||||
}
|
||||
|
||||
poptart() {
|
||||
cat << POPTART
|
||||
[38;5;52m▄[m[38;5;52m▄[m[48;5;216;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;222;38;5;52m▀[m[48;5;215;38;5;52m▀[m[48;5;215;38;5;52m▀[m[48;5;172;38;5;52m▀[m[48;5;204;38;5;52m▀[m[48;5;205;38;5;52m▀[m[38;5;125m▄[m
|
||||
[48;5;52m [m[48;5;222;38;5;179m▀[m[48;5;222m [m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;214;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;179;38;5;215m▀[m[48;5;179m [m[48;5;172m [m[48;5;224;38;5;204m▀[m[48;5;205m [m[48;5;205;38;5;125m▀[m[48;5;205;38;5;125m▀[m[38;5;125m▄[m
|
||||
[48;5;52m [m[48;5;222;38;5;215m▀[m[48;5;222m [m[48;5;215m [m[48;5;215m [m[48;5;186;38;5;179m▀[m[48;5;195;38;5;215m▀[m[48;5;231;38;5;195m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;220;38;5;231m▀[m[48;5;220;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;194m▀[m[48;5;224;38;5;172m▀[m[48;5;172;38;5;205m▀[m[48;5;172;38;5;205m▀[m[48;5;204;38;5;205m▀[m[48;5;205m [m[48;5;205;38;5;125m▀[m[48;5;205;38;5;125m▀[m[48;5;205;38;5;125m▀[m[38;5;89m▄[m
|
||||
[48;5;52m [m[48;5;215;38;5;221m▀[m[48;5;179;38;5;222m▀[m[48;5;215m [m[48;5;195;38;5;186m▀[m[48;5;195;38;5;187m▀[m[48;5;231;38;5;195m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;220m [m[48;5;220m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;173m▀[m[48;5;195;38;5;172m▀[m[48;5;172;38;5;205m▀[m[48;5;224;38;5;205m▀[m[48;5;211;38;5;204m▀[m[48;5;205m [m[48;5;205m [m[48;5;199;38;5;126m▀[m[38;5;125m▄[m
|
||||
[48;5;52m [m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;205;38;5;231m▀[m[48;5;205;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;99m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195;38;5;172m▀[m[48;5;205;38;5;204m▀[m[48;5;211;38;5;205m▀[m[48;5;204m [m[48;5;204;38;5;205m▀[m[48;5;130;38;5;198m▀[m[48;5;130m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222m [m[48;5;222m [m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;205m▀[m[48;5;231;38;5;205m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;205m [m[48;5;205m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;205m [m[48;5;224m [m[48;5;224m [m[48;5;205m [m[48;5;205m [m[48;5;199;38;5;198m▀[m[48;5;215;38;5;172m▀[m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215;38;5;221m▀[m[48;5;179;38;5;222m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;99;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;45m [m[48;5;45m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;195m▀[m[48;5;195;38;5;175m▀[m[48;5;205;38;5;225m▀[m[48;5;205;38;5;225m▀[m[48;5;204;38;5;205m▀[m[48;5;204m [m[48;5;172;38;5;199m▀[m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;98m▀[m[48;5;195m [m[48;5;195m [m[48;5;205;38;5;225m▀[m[48;5;198;38;5;205m▀[m[48;5;199;38;5;210m▀[m[48;5;199;38;5;198m▀[m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;221;38;5;222m▀[m[48;5;222m [m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;159;38;5;195m▀[m[48;5;162;38;5;205m▀[m[48;5;198;38;5;199m▀[m[48;5;198;38;5;199m▀[m[48;5;198m [m[48;5;172;38;5;215m▀[m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215;38;5;221m▀[m[48;5;179;38;5;222m▀[m[48;5;215m [m[48;5;195m [m[48;5;195;38;5;159m▀[m[48;5;230;38;5;231m▀[m[48;5;220m [m[48;5;220m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;211;38;5;205m▀[m[48;5;205m [m[48;5;211;38;5;205m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;220;38;5;230m▀[m[48;5;220;38;5;231m▀[m[48;5;231m [m[48;5;231;38;5;195m▀[m[48;5;159;38;5;195m▀[m[48;5;215;38;5;172m▀[m[48;5;179;38;5;172m▀[m[48;5;215;38;5;172m▀[m[48;5;215;38;5;172m▀[m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;179;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;220m▀[m[48;5;230;38;5;220m▀[m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222m [m[48;5;222m [m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;99;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;45m [m[48;5;39;38;5;45m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215;38;5;221m▀[m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;205;38;5;231m▀[m[48;5;205;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222;38;5;179m▀[m[48;5;222;38;5;179m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231;38;5;195m▀[m[48;5;231m [m[48;5;195;38;5;231m▀[m[48;5;231;38;5;205m▀[m[48;5;231;38;5;205m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;175;38;5;231m▀[m[48;5;205;38;5;231m▀[m[48;5;225;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222m [m[48;5;222m [m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;195;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;220m [m[48;5;214;38;5;220m▀[m[48;5;220m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;225;38;5;204m▀[m[48;5;231;38;5;205m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;179;38;5;221m▀[m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;195m [m[48;5;195m [m[48;5;231;38;5;195m▀[m[48;5;231;38;5;230m▀[m[48;5;220;38;5;231m▀[m[48;5;220;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;220m▀[m[48;5;231;38;5;220m▀[m[48;5;231;38;5;220m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;195m [m[48;5;195;38;5;159m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;230m▀[m[48;5;231;38;5;220m▀[m[48;5;231;38;5;220m▀[m[48;5;230;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;99;38;5;225m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;195m [m[48;5;215m [m[48;5;179m [m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215m [m[48;5;215;38;5;179m▀[m[48;5;215m [m[48;5;194;38;5;195m▀[m[48;5;194;38;5;159m▀[m[48;5;195m [m[48;5;195;38;5;231m▀[m[48;5;231;38;5;195m▀[m[48;5;195;38;5;231m▀[m[48;5;231m [m[48;5;195;38;5;231m▀[m[48;5;231;38;5;195m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;231m▀[m[48;5;195m [m[48;5;231;38;5;195m▀[m[48;5;195;38;5;231m▀[m[48;5;231m [m[48;5;45m [m[48;5;45m [m[48;5;123;38;5;231m▀[m[48;5;231;38;5;195m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;231m▀[m[48;5;195m [m[48;5;195;38;5;159m▀[m[48;5;215;38;5;179m▀[m[48;5;179;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;172m [m[48;5;172;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;214m [m[48;5;180;38;5;159m▀[m[48;5;195;38;5;230m▀[m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;180;38;5;159m▀[m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;130m [m[48;5;130m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;130m [m[48;5;130;38;5;172m▀[m[48;5;130;38;5;215m▀[m[48;5;130;38;5;215m▀[m[48;5;130;38;5;215m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;179m▀[m[48;5;130;38;5;215m▀[m[48;5;130;38;5;214m▀[m[48;5;130;38;5;215m▀[m[48;5;130m [m[48;5;130m [m[48;5;130m [m[48;5;52m [m
|
||||
[38;5;88m▀[m[38;5;52m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[48;5;52;38;5;130m▀[m[38;5;52m▀[m[38;5;52m▀[m[38;5;52m▀[m
|
||||
[0m
|
||||
POPTART
|
||||
}
|
||||
|
||||
waffles() {
|
||||
cat << WAFFLES
|
||||
[38;5;52m▄[m[38;5;52m▄[m[48;5;228;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;185;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;228;38;5;52m▀[m[48;5;179;38;5;52m▀[m[48;5;178;38;5;52m▀[m[48;5;215;38;5;52m▀[m[38;5;52m▄[m
|
||||
[38;5;52m▄[m[48;5;228;38;5;52m▀[m[48;5;215;38;5;228m▀[m[48;5;179;38;5;228m▀[m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;179;38;5;215m▀[m[48;5;179;38;5;215m▀[m[48;5;179;38;5;215m▀[m[48;5;179m [m[48;5;215;38;5;179m▀[m[48;5;179;38;5;222m▀[m[48;5;179;38;5;215m▀[m[48;5;179;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;215;38;5;179m▀[m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;215;38;5;179m▀[m[48;5;215m [m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;215;38;5;52m▀[m[38;5;52m▄[m
|
||||
[38;5;52m▄[m[48;5;228;38;5;52m▀[m[48;5;215;38;5;228m▀[m[48;5;222;38;5;179m▀[m[48;5;172;38;5;222m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;172;38;5;222m▀[m[48;5;222;38;5;215m▀[m[48;5;172m [m[48;5;221;38;5;222m▀[m[48;5;222;38;5;215m▀[m[48;5;172;38;5;228m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;172;38;5;221m▀[m[48;5;222;38;5;215m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222;38;5;221m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;172;38;5;221m▀[m[48;5;179m [m[48;5;172;38;5;52m▀[m[38;5;52m▄[m
|
||||
[48;5;52m [m[48;5;228m [m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;178;38;5;228m▀[m[48;5;172m [m[48;5;220;38;5;172m▀[m[48;5;220;38;5;130m▀[m[48;5;172m [m[48;5;130m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;222;38;5;228m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;215;38;5;222m▀[m[48;5;130m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;166;38;5;172m▀[m[48;5;215;38;5;179m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;179;38;5;228m▀[m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;215;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;208;38;5;130m▀[m[48;5;172m [m[48;5;221;38;5;178m▀[m[48;5;228;38;5;220m▀[m[48;5;228m [m[48;5;220m [m[48;5;220;38;5;130m▀[m[48;5;130m [m[48;5;124;38;5;172m▀[m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;222;38;5;172m▀[m[48;5;179;38;5;222m▀[m[48;5;172m [m[48;5;215;38;5;222m▀[m[48;5;172m [m[48;5;215m [m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;222;38;5;172m▀[m[48;5;215;38;5;179m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;228;38;5;179m▀[m[48;5;222;38;5;179m▀[m[48;5;222;38;5;215m▀[m[48;5;215;38;5;179m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;178m [m[48;5;221;38;5;178m▀[m[48;5;231;38;5;220m▀[m[48;5;231;38;5;228m▀[m[48;5;228m [m[48;5;220;38;5;227m▀[m[48;5;220m [m[48;5;220m [m[48;5;220m [m[48;5;214;38;5;221m▀[m[48;5;124;38;5;222m▀[m[48;5;52;38;5;222m▀[m[48;5;215;38;5;179m▀[m[48;5;179;38;5;215m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;179m▀[m[48;5;222;38;5;172m▀[m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;179;38;5;222m▀[m[48;5;179;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;222;38;5;215m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;228m [m[48;5;215;38;5;179m▀[m[48;5;215;38;5;179m▀[m[48;5;185;38;5;179m▀[m[48;5;222m [m[48;5;222m [m[48;5;130m [m[48;5;220;38;5;221m▀[m[48;5;231m [m[48;5;228m [m[48;5;228m [m[48;5;221;38;5;220m▀[m[48;5;220m [m[48;5;220m [m[48;5;220m [m[48;5;215;38;5;220m▀[m[48;5;124;38;5;130m▀[m[48;5;88;38;5;52m▀[m[48;5;216m [m[48;5;215m [m[48;5;222m [m[48;5;222m [m[48;5;222m [m[48;5;179;38;5;215m▀[m[48;5;221;38;5;222m▀[m[48;5;222m [m[48;5;222m [m[48;5;215m [m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;215;38;5;179m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;179;38;5;228m▀[m[48;5;215m [m[48;5;222m [m[48;5;172m [m[48;5;130m [m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;130m [m[48;5;220m [m[48;5;221;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;220m [m[48;5;220m [m[48;5;130;38;5;220m▀[m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;228;38;5;222m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222;38;5;215m▀[m[48;5;130m [m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;179;38;5;215m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;228;38;5;179m▀[m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;94m [m[48;5;220m [m[48;5;220m [m[48;5;221;38;5;220m▀[m[48;5;220m [m[48;5;220;38;5;130m▀[m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;215;38;5;222m▀[m[48;5;130m [m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;179m [m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215;38;5;228m▀[m[48;5;215;38;5;179m▀[m[48;5;215m [m[48;5;215;38;5;172m▀[m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;222;38;5;172m▀[m[48;5;215;38;5;94m▀[m[48;5;214;38;5;221m▀[m[48;5;130;38;5;220m▀[m[48;5;229;38;5;228m▀[m[48;5;220m [m[48;5;220m [m[48;5;130m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;221;38;5;172m▀[m[48;5;179;38;5;222m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;215m [m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;172m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;222;38;5;172m▀[m[48;5;215;38;5;179m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215m [m[48;5;222m [m[48;5;222m [m[48;5;214;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;215m [m[48;5;215m [m[48;5;222;38;5;221m▀[m[48;5;222m [m[48;5;130;38;5;221m▀[m[48;5;220m [m[48;5;130;38;5;220m▀[m[48;5;130m [m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;215m [m[48;5;215;38;5;179m▀[m[48;5;222m [m[48;5;222m [m[48;5;222m [m[48;5;215m [m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;215m [m[48;5;222m [m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215;38;5;228m▀[m[48;5;215m [m[48;5;215;38;5;179m▀[m[48;5;222;38;5;179m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;222;38;5;179m▀[m[48;5;179m [m[48;5;172;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;228;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;215m▀[m[48;5;221;38;5;215m▀[m[48;5;221;38;5;215m▀[m[48;5;172;38;5;222m▀[m[48;5;215;38;5;222m▀[m[48;5;172;38;5;222m▀[m[48;5;221;38;5;215m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;222;38;5;179m▀[m[48;5;179;38;5;215m▀[m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;222;38;5;215m▀[m[48;5;215m [m[48;5;222m [m[48;5;172m [m[48;5;130m [m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;228m [m[48;5;172m [m[48;5;222m [m[48;5;222m [m[48;5;172m [m[48;5;130m [m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;222;38;5;228m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222m [m[48;5;130m [m[48;5;130m [m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172;38;5;130m▀[m[48;5;172m [m[48;5;179m [m[48;5;172m [m[48;5;52m [m
|
||||
[48;5;52m [m[48;5;215m [m[48;5;215m [m[48;5;215;38;5;222m▀[m[48;5;172m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222m [m[48;5;215;38;5;221m▀[m[48;5;172m [m[48;5;130m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;222m [m[48;5;172m [m[48;5;215;38;5;221m▀[m[48;5;130m [m[48;5;172m [m[48;5;172m [m[48;5;130;38;5;172m▀[m[48;5;130;38;5;172m▀[m[48;5;172m [m[48;5;179m [m[48;5;172m [m[48;5;52m [m
|
||||
[38;5;52m▀[m[48;5;52;38;5;215m▀[m[48;5;215m [m[48;5;215;38;5;179m▀[m[48;5;179;38;5;215m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;179;38;5;222m▀[m[48;5;215m [m[48;5;172m [m[48;5;215;38;5;222m▀[m[48;5;215m [m[48;5;179;38;5;215m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;179;38;5;222m▀[m[48;5;215;38;5;179m▀[m[48;5;172m [m[48;5;215;38;5;222m▀[m[48;5;172m [m[48;5;215m [m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;222;38;5;172m▀[m[48;5;215;38;5;222m▀[m[48;5;179;38;5;215m▀[m[48;5;52;38;5;172m▀[m[38;5;52m▀[m
|
||||
[38;5;52m▀[m[48;5;52;38;5;172m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;222m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;215m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;179m▀[m[48;5;172;38;5;215m▀[m[48;5;52;38;5;172m▀[m[38;5;52m▀[m
|
||||
[38;5;52m▀[m[38;5;52m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[48;5;52;38;5;172m▀[m[38;5;52m▀[m
|
||||
[0m
|
||||
WAFFLES
|
||||
}
|
||||
|
||||
burger() {
|
||||
cat << BURGER
|
||||
[38;5;16m▄[m[38;5;16m▄[m[38;5;16m▄[m[38;5;16m▄[m[48;5;124;38;5;16m▀[m[48;5;166;38;5;16m▀[m[48;5;160;38;5;16m▀[m[48;5;166;38;5;16m▀[m[48;5;130;38;5;16m▀[m[48;5;124;38;5;16m▀[m[38;5;16m▄[m[38;5;16m▄[m[38;5;16m▄[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[38;5;16m▄[m[48;5;203;38;5;16m▀[m[48;5;203;38;5;16m▀[m[48;5;203;38;5;124m▀[m[48;5;203;38;5;208m▀[m[48;5;203;38;5;209m▀[m[48;5;203m [m[48;5;209;38;5;203m▀[m[48;5;209m [m[48;5;203m [m[48;5;209;38;5;203m▀[m[48;5;209;38;5;216m▀[m[48;5;209;38;5;215m▀[m[48;5;209;38;5;203m▀[m[48;5;209;38;5;215m▀[m[48;5;209;38;5;215m▀[m[48;5;209;38;5;130m▀[m[48;5;209;38;5;16m▀[m[48;5;215;38;5;16m▀[m[38;5;16m▄[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;172;38;5;16m▀[m[48;5;203m [m[48;5;203m [m[48;5;209;38;5;203m▀[m[48;5;203m [m[48;5;209m [m[48;5;209;38;5;203m▀[m[48;5;209m [m[48;5;203m [m[48;5;210;38;5;203m▀[m[48;5;215;38;5;208m▀[m[48;5;209;38;5;203m▀[m[48;5;215m [m[48;5;210;38;5;209m▀[m[48;5;209m [m[48;5;209;38;5;215m▀[m[48;5;210;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;209m [m[48;5;210;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;209m [m[48;5;221;38;5;172m▀[m[48;5;173;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;209;38;5;16m▀[m[48;5;209;38;5;167m▀[m[48;5;203m [m[48;5;203m [m[48;5;209;38;5;203m▀[m[48;5;203;38;5;208m▀[m[48;5;203m [m[48;5;209m [m[48;5;209m [m[48;5;203;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;203;38;5;209m▀[m[48;5;209m [m[48;5;215;38;5;209m▀[m[48;5;209m [m[48;5;209m [m[48;5;215;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;209m [m[48;5;215;38;5;209m▀[m[48;5;215;38;5;209m▀[m[48;5;215m [m[48;5;215m [m[48;5;229;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;222;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;209;38;5;16m▀[m[48;5;203m [m[48;5;203m [m[48;5;202;38;5;203m▀[m[48;5;203m [m[48;5;209;38;5;203m▀[m[48;5;209m [m[48;5;203m [m[48;5;209m [m[48;5;215;38;5;203m▀[m[48;5;215m [m[48;5;209m [m[48;5;215;38;5;203m▀[m[48;5;222;38;5;215m▀[m[48;5;215;38;5;209m▀[m[48;5;215m [m[48;5;216;38;5;209m▀[m[48;5;215m [m[48;5;215m [m[48;5;215m [m[48;5;222;38;5;215m▀[m[48;5;221;38;5;215m▀[m[48;5;222;38;5;215m▀[m[48;5;229m [m[48;5;222;38;5;221m▀[m[48;5;228;38;5;222m▀[m[48;5;228;38;5;222m▀[m[48;5;228;38;5;222m▀[m[48;5;16m [m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;172;38;5;16m▀[m[48;5;215;38;5;209m▀[m[48;5;215;38;5;210m▀[m[48;5;215;38;5;209m▀[m[48;5;222;38;5;215m▀[m[48;5;215;38;5;203m▀[m[48;5;229;38;5;222m▀[m[48;5;222;38;5;215m▀[m[48;5;221;38;5;209m▀[m[48;5;222m [m[48;5;215m [m[48;5;228;38;5;221m▀[m[48;5;215m [m[48;5;222m [m[48;5;222;38;5;215m▀[m[48;5;222m [m[48;5;222m [m[48;5;222m [m[48;5;222;38;5;228m▀[m[48;5;229;38;5;222m▀[m[48;5;222m [m[48;5;222m [m[48;5;222;38;5;229m▀[m[48;5;228;38;5;222m▀[m[48;5;228;38;5;227m▀[m[48;5;227;38;5;222m▀[m[48;5;228;38;5;229m▀[m[48;5;228m [m[48;5;228m [m[48;5;229m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;166;38;5;216m▀[m[48;5;228;38;5;223m▀[m[48;5;215;38;5;222m▀[m[48;5;215;38;5;216m▀[m[48;5;222m [m[48;5;215;38;5;222m▀[m[48;5;229;38;5;227m▀[m[48;5;222m [m[48;5;222;38;5;229m▀[m[48;5;222;38;5;229m▀[m[48;5;222m [m[48;5;228;38;5;229m▀[m[48;5;228m [m[48;5;228m [m[48;5;228;38;5;229m▀[m[48;5;228m [m[48;5;228;38;5;229m▀[m[48;5;228m [m[48;5;228m [m[48;5;229;38;5;227m▀[m[48;5;228m [m[48;5;228;38;5;229m▀[m[48;5;228;38;5;229m▀[m[48;5;228;38;5;229m▀[m[48;5;228;38;5;229m▀[m[48;5;228m [m[48;5;229;38;5;228m▀[m[48;5;228;38;5;229m▀[m[48;5;230;38;5;229m▀[m[48;5;16m [m[38;5;16m▀[m
|
||||
[48;5;16m [m[48;5;166;38;5;227m▀[m[48;5;228;38;5;221m▀[m[48;5;228;38;5;222m▀[m[48;5;229;38;5;228m▀[m[48;5;228m [m[48;5;227;38;5;229m▀[m[48;5;229;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;227;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;230;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;230;38;5;228m▀[m[48;5;229;38;5;228m▀[m[48;5;230;38;5;229m▀[m[48;5;229;38;5;228m▀[m[48;5;229;38;5;227m▀[m[48;5;230;38;5;229m▀[m[48;5;229;38;5;228m▀[m[48;5;230;38;5;228m▀[m[48;5;230;38;5;229m▀[m[48;5;231;38;5;229m▀[m[48;5;172;38;5;228m▀[m[48;5;208;38;5;230m▀[m[48;5;130;38;5;230m▀[m[48;5;209;38;5;229m▀[m[48;5;223;38;5;215m▀[m[48;5;246;38;5;16m▀[m[38;5;16m▄[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;64;38;5;16m▀[m[48;5;227;38;5;100m▀[m[48;5;227;38;5;226m▀[m[48;5;228;38;5;130m▀[m[48;5;178;38;5;214m▀[m[48;5;124;38;5;228m▀[m[48;5;172;38;5;227m▀[m[48;5;208;38;5;230m▀[m[48;5;215;38;5;230m▀[m[48;5;223;38;5;229m▀[m[48;5;223;38;5;229m▀[m[48;5;222;38;5;230m▀[m[48;5;229m [m[48;5;223;38;5;230m▀[m[48;5;222;38;5;230m▀[m[48;5;223;38;5;229m▀[m[48;5;223;38;5;229m▀[m[48;5;172;38;5;229m▀[m[48;5;166;38;5;230m▀[m[48;5;208;38;5;231m▀[m[48;5;172;38;5;230m▀[m[48;5;208;38;5;230m▀[m[48;5;230;38;5;166m▀[m[48;5;231;38;5;130m▀[m[48;5;231;38;5;130m▀[m[48;5;146;38;5;188m▀[m[48;5;153;38;5;187m▀[m[48;5;139;38;5;224m▀[m[48;5;139;38;5;231m▀[m[48;5;181;38;5;231m▀[m[48;5;181;38;5;231m▀[m[48;5;251m [m[48;5;16;38;5;246m▀[m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[48;5;52;38;5;70m▀[m[48;5;28;38;5;190m▀[m[48;5;70;38;5;190m▀[m[48;5;106;38;5;190m▀[m[48;5;94;38;5;106m▀[m[48;5;124;38;5;22m▀[m[48;5;70;38;5;148m▀[m[48;5;154;38;5;227m▀[m[48;5;148;38;5;185m▀[m[48;5;190;38;5;172m▀[m[48;5;106;38;5;136m▀[m[48;5;187;38;5;88m▀[m[48;5;231;38;5;173m▀[m[48;5;230;38;5;173m▀[m[48;5;230;38;5;173m▀[m[48;5;231;38;5;173m▀[m[48;5;230;38;5;131m▀[m[48;5;182;38;5;146m▀[m[48;5;188m [m[48;5;189;38;5;251m▀[m[48;5;231m [m[48;5;189;38;5;230m▀[m[48;5;189;38;5;231m▀[m[48;5;189;38;5;231m▀[m[48;5;189;38;5;231m▀[m[48;5;225;38;5;231m▀[m[48;5;146;38;5;231m▀[m[48;5;203;38;5;132m▀[m[48;5;160m [m[48;5;16;38;5;124m▀[m[38;5;16m▀[m[38;5;16m▀[m
|
||||
[48;5;16m [m[48;5;160;38;5;202m▀[m[48;5;196;38;5;202m▀[m[48;5;196;38;5;160m▀[m[48;5;202;38;5;160m▀[m[48;5;203;38;5;22m▀[m[48;5;196;38;5;28m▀[m[48;5;124;38;5;28m▀[m[48;5;138;38;5;251m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;189;38;5;231m▀[m[48;5;60;38;5;231m▀[m[48;5;160;38;5;90m▀[m[48;5;160m [m[48;5;222;38;5;124m▀[m[48;5;202m [m[48;5;202;38;5;197m▀[m[48;5;196;38;5;202m▀[m[48;5;52;38;5;160m▀[m[48;5;34;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;28;38;5;16m▀[m[38;5;16m▄[m
|
||||
[38;5;22m▄[m[48;5;112;38;5;16m▀[m[48;5;76;38;5;82m▀[m[48;5;28;38;5;64m▀[m[48;5;34;38;5;124m▀[m[48;5;94;38;5;196m▀[m[48;5;88;38;5;196m▀[m[48;5;94;38;5;196m▀[m[48;5;94;38;5;196m▀[m[48;5;160;38;5;196m▀[m[48;5;196m [m[48;5;196;38;5;181m▀[m[48;5;160;38;5;139m▀[m[48;5;196;38;5;139m▀[m[48;5;196;38;5;182m▀[m[48;5;160;38;5;133m▀[m[48;5;196;38;5;139m▀[m[48;5;196;38;5;139m▀[m[48;5;196;38;5;182m▀[m[48;5;196;38;5;139m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;202m▀[m[48;5;196;38;5;203m▀[m[48;5;94;38;5;209m▀[m[48;5;88;38;5;196m▀[m[48;5;76;38;5;160m▀[m[48;5;82;38;5;88m▀[m[48;5;40;38;5;34m▀[m[48;5;34;38;5;28m▀[m[48;5;22;38;5;70m▀[m[48;5;16;38;5;34m▀[m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[38;5;28m▀[m[48;5;16m [m[48;5;131;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;34;38;5;22m▀[m[48;5;76;38;5;28m▀[m[48;5;118;38;5;82m▀[m[48;5;154;38;5;82m▀[m[48;5;154;38;5;142m▀[m[48;5;76;38;5;136m▀[m[48;5;40;38;5;58m▀[m[48;5;34;38;5;16m▀[m[48;5;34;38;5;52m▀[m[48;5;34;38;5;52m▀[m[48;5;118;38;5;94m▀[m[48;5;154;38;5;136m▀[m[48;5;154;38;5;136m▀[m[48;5;82;38;5;58m▀[m[48;5;40;38;5;52m▀[m[48;5;28;38;5;52m▀[m[48;5;34;38;5;52m▀[m[48;5;34;38;5;16m▀[m[48;5;16;38;5;58m▀[m[48;5;16;38;5;40m▀[m[48;5;22;38;5;76m▀[m[48;5;118;38;5;154m▀[m[48;5;154;38;5;82m▀[m[48;5;40m [m[48;5;22;38;5;34m▀[m[48;5;95;38;5;28m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;167;38;5;88m▀[m[48;5;52;38;5;16m▀[m[48;5;16;38;5;34m▀[m[48;5;22;38;5;28m▀[m[48;5;52;38;5;22m▀[m[48;5;16;38;5;28m▀[m[48;5;28;38;5;154m▀[m[48;5;118m [m[48;5;76;38;5;34m▀[m[48;5;76;38;5;28m▀[m[48;5;34;38;5;22m▀[m[48;5;16;38;5;34m▀[m[48;5;124;38;5;22m▀[m[48;5;16;38;5;118m▀[m[48;5;154m [m[48;5;82;38;5;118m▀[m[48;5;40m [m[48;5;34m [m[48;5;34;38;5;22m▀[m[48;5;16m [m[48;5;124m [m[48;5;88m [m[48;5;88;38;5;124m▀[m[48;5;88;38;5;16m▀[m[48;5;22;38;5;118m▀[m[48;5;88;38;5;70m▀[m[48;5;167;38;5;58m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;167;38;5;210m▀[m[48;5;210;38;5;125m▀[m[48;5;173;38;5;166m▀[m[48;5;172;38;5;52m▀[m[48;5;166;38;5;52m▀[m[48;5;88;38;5;16m▀[m[48;5;16;38;5;22m▀[m[48;5;22;38;5;76m▀[m[48;5;28;38;5;40m▀[m[48;5;52;38;5;22m▀[m[48;5;52;38;5;88m▀[m[48;5;88m [m[48;5;52;38;5;16m▀[m[48;5;16;38;5;28m▀[m[48;5;22;38;5;34m▀[m[48;5;94;38;5;70m▀[m[48;5;166;38;5;16m▀[m[48;5;160;38;5;16m▀[m[48;5;167;38;5;52m▀[m[48;5;166;38;5;88m▀[m[48;5;203;38;5;124m▀[m[48;5;210;38;5;197m▀[m[48;5;138;38;5;210m▀[m[48;5;166;38;5;209m▀[m[48;5;130;38;5;131m▀[m[48;5;216;38;5;166m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;167;38;5;124m▀[m[48;5;203;38;5;88m▀[m[48;5;88;38;5;174m▀[m[48;5;88;38;5;167m▀[m[48;5;88;38;5;204m▀[m[48;5;131;38;5;209m▀[m[48;5;173;38;5;203m▀[m[48;5;131;38;5;174m▀[m[48;5;167;38;5;166m▀[m[48;5;131;38;5;209m▀[m[48;5;167;38;5;209m▀[m[48;5;161;38;5;167m▀[m[48;5;131;38;5;209m▀[m[48;5;173;38;5;167m▀[m[48;5;130;38;5;173m▀[m[48;5;125;38;5;210m▀[m[48;5;174;38;5;203m▀[m[48;5;130;38;5;210m▀[m[48;5;88;38;5;167m▀[m[48;5;88;38;5;173m▀[m[48;5;88;38;5;174m▀[m[48;5;88;38;5;167m▀[m[48;5;215;38;5;88m▀[m[48;5;222;38;5;130m▀[m[48;5;173;38;5;215m▀[m[48;5;16m [m
|
||||
[38;5;16m▀[m[48;5;16;38;5;167m▀[m[48;5;16;38;5;203m▀[m[48;5;203m [m[48;5;203;38;5;166m▀[m[48;5;203;38;5;88m▀[m[48;5;203;38;5;88m▀[m[48;5;203;38;5;124m▀[m[48;5;167;38;5;88m▀[m[48;5;209;38;5;88m▀[m[48;5;209;38;5;124m▀[m[48;5;203;38;5;88m▀[m[48;5;209;38;5;88m▀[m[48;5;215;38;5;88m▀[m[48;5;215;38;5;124m▀[m[48;5;215;38;5;124m▀[m[48;5;221;38;5;88m▀[m[48;5;215;38;5;130m▀[m[48;5;215;38;5;229m▀[m[48;5;215;38;5;229m▀[m[48;5;221;38;5;229m▀[m[48;5;209;38;5;222m▀[m[48;5;16;38;5;222m▀[m[48;5;16;38;5;203m▀[m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m[48;5;16;38;5;124m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;203m▀[m[48;5;16;38;5;209m▀[m[48;5;16;38;5;209m▀[m[48;5;16;38;5;209m▀[m[48;5;16;38;5;215m▀[m[48;5;16;38;5;209m▀[m[48;5;16;38;5;209m▀[m[38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m
|
||||
[0m
|
||||
BURGER
|
||||
}
|
||||
|
||||
vburger() {
|
||||
cat << VBURGER
|
||||
[49m [38;5;16m▄▄▄▄▄▄▄▄▄▄
|
||||
▄▄▄[48;5;16m[38;5;208m▄▄▄[48;5;166m ▄▄ [48;5;94m[38;5;166m▄[38;5;208m▄[38;5;166m▄▄ [48;5;16m[38;5;94m▄▄▄[49m[38;5;16m▄▄
|
||||
▄[48;5;16m[38;5;208m▄[38;5;221m▄[48;5;208m▄▄ ▄▄ [38;5;166m▄[48;5;166m[38;5;208m▄▄[48;5;208m [38;5;166m▄[48;5;166m[38;5;208m▄▄ [48;5;94m[38;5;166m▄ [48;5;16m[38;5;94m▄[49m[38;5;16m▄
|
||||
▄[48;5;16m[38;5;221m▄[48;5;221m[38;5;208m▄[48;5;208m[38;5;221m▄[48;5;221m [48;5;208m [48;5;221m[38;5;208m▄▄[48;5;208m [38;5;166m▄ [48;5;166m [48;5;208m▄[48;5;166m [48;5;94m [48;5;166m[38;5;94m▄[48;5;94m[38;5;166m▄[48;5;166m[38;5;94m▄[48;5;94m [48;5;16m▄[49m[38;5;16m▄
|
||||
▄[48;5;16m[38;5;221m▄[48;5;172m[38;5;208m▄[48;5;221m ▄[48;5;208m [38;5;166m▄ ▄▄[48;5;166m [48;5;208m▄[48;5;166m [48;5;94m[38;5;172m▄[48;5;166m ▄[48;5;94m[38;5;166m▄[48;5;166m[38;5;94m▄[48;5;94m [48;5;16m [49m
|
||||
[48;5;16m [48;5;221m [48;5;172m [48;5;166m[38;5;172m▄[48;5;208m[38;5;166m▄[48;5;166m [48;5;208m▄[48;5;166m [48;5;208m▄[48;5;166m [48;5;208m▄[48;5;166m[38;5;208m▄[48;5;208m[38;5;166m▄[48;5;166m [48;5;208m▄[48;5;166m [48;5;208m▄[48;5;166m [48;5;172m▄[48;5;166m[38;5;172m▄▄▄[48;5;172m [38;5;221m▄[48;5;166m[38;5;94m▄[48;5;172m [48;5;94m[38;5;16m▄[49m▀
|
||||
▀[48;5;221m▄ [48;5;172m[38;5;221m▄ [48;5;166m[38;5;172m▄▄▄[48;5;172m [48;5;166m [48;5;172m[38;5;166m▄[48;5;166m [38;5;172m▄ [48;5;172m[38;5;166m▄[48;5;166m[38;5;172m▄▄[48;5;172m [38;5;221m▄▄[48;5;221m [38;5;172m▄[48;5;172m[38;5;209m▄▄[48;5;209m[38;5;22m▄[48;5;16m[38;5;28m▄▄▄[49m[38;5;16m▄
|
||||
▄[48;5;16m[38;5;28m▄[48;5;209m▄[48;5;221m[38;5;209m▄▄▄ [48;5;172m[38;5;221m▄▄▄▄▄▄▄▄▄[48;5;221m [38;5;209m▄▄[48;5;172m▄[48;5;221m▄[48;5;209m[38;5;28m▄▄[48;5;22m▄▄ ▄[48;5;28m[38;5;16m▄[49m[38;5;28m▀
|
||||
[38;5;16m▀[48;5;28m▄ [38;5;118m▄▄ [48;5;209m[38;5;28m▄[38;5;231m▄▄[48;5;221m[38;5;209m▄▄▄▄▄▄[48;5;209m[38;5;231m▄▄▄[38;5;228m▄[48;5;231m▄ [48;5;228m [38;5;118m▄[48;5;28m[38;5;40m▄ [38;5;16m▄▄[48;5;16m [49m
|
||||
▀[48;5;118m▄[38;5;52m▄[38;5;28m▄[48;5;28m [48;5;40m[38;5;88m▄[48;5;22m▄[48;5;40m [48;5;228m[38;5;28m▄[48;5;231m▄[38;5;40m▄[38;5;28m▄[48;5;228m[38;5;40m▄[38;5;118m▄ [48;5;231m[38;5;228m▄[48;5;228m [38;5;40m▄[48;5;28m [48;5;40m[38;5;28m▄[38;5;118m▄[38;5;52m▄[48;5;118m▄[48;5;28m▄[48;5;16m▄▄ [49m
|
||||
[38;5;16m▀[48;5;52m▄[48;5;88m [38;5;166m▄[48;5;94m [48;5;88m [48;5;118m[38;5;88m▄[38;5;40m▄ [48;5;40m[38;5;118m▄▄▄▄[48;5;118m [38;5;28m▄ ▄[38;5;88m▄[48;5;88m [38;5;94m▄ [48;5;94m[38;5;88m▄[48;5;52m [38;5;16m▄[48;5;16m [38;5;166m▄[48;5;166m [48;5;94m [48;5;16m [49m
|
||||
[48;5;16m [48;5;52m▄[48;5;88m[38;5;52m▄[48;5;94m[38;5;88m▄ [48;5;166m[38;5;94m▄[48;5;94m[38;5;166m▄[48;5;88m[38;5;94m▄▄[48;5;118m▄[48;5;88m▄[48;5;118m▄[48;5;88m[38;5;166m▄[38;5;94m▄▄[48;5;28m[38;5;166m▄[38;5;94m▄[48;5;94m [38;5;88m▄[48;5;88m[38;5;94m▄[38;5;52m▄[48;5;52m [38;5;221m▄▄[48;5;221m[38;5;227m▄[48;5;172m[38;5;208m▄[38;5;94m▄[48;5;94m [48;5;88m [48;5;16m [48;5;235m [49m
|
||||
[48;5;16m [48;5;166m [48;5;88m[38;5;172m▄▄[48;5;94m[38;5;88m▄▄▄▄[48;5;166m▄[48;5;94m▄▄▄[48;5;166m▄[48;5;94m▄▄▄[48;5;88m[38;5;221m▄▄[38;5;227m▄[48;5;221m▄▄[48;5;227m[38;5;208m▄[38;5;166m▄[48;5;208m▄[48;5;166m [38;5;94m▄[48;5;88m[38;5;16m▄[48;5;16m[38;5;235m▄[48;5;235m[38;5;238m▄[49m▀
|
||||
[48;5;16m [48;5;166m [48;5;172m[38;5;166m▄▄ [48;5;208m[38;5;172m▄[48;5;227m▄▄▄[38;5;208m▄▄▄▄▄▄▄▄▄[48;5;208m[38;5;172m▄[48;5;172m [38;5;166m▄[48;5;166m [38;5;16m▄[48;5;94m▄[48;5;16m[38;5;235m▄[48;5;235m[38;5;238m▄[48;5;238m [49m▀
|
||||
[38;5;16m▀[48;5;16m[38;5;238m▄[48;5;166m[38;5;16m▄▄▄ [48;5;172m[38;5;166m▄▄▄▄▄▄▄▄▄▄▄[48;5;166m[38;5;16m▄▄▄[48;5;16m[38;5;235m▄▄[48;5;235m[38;5;238m▄▄[49m▀▀
|
||||
▀[38;5;16m▀▀▀[48;5;16m[38;5;238m▄▄▄▄▄▄▄▄▄[48;5;235m▄[49m[38;5;235m▀▀[38;5;238m▀[39m
|
||||
[0m
|
||||
VBURGER
|
||||
}
|
||||
|
||||
rice() {
|
||||
cat << RICE
|
||||
[38;5;16m▄▄▄▄▄▄
|
||||
▄[48;5;16m[38;5;231m▄▄▄[48;5;231m [38;5;246m▄ ▄ [48;5;16m[38;5;231m▄▄▄[49m[38;5;16m▄
|
||||
[38;5;234m▄[38;5;235m▄[38;5;236m▄[38;5;16m▄[48;5;16m[38;5;231m▄[48;5;231m [48;5;246m▄[48;5;231m[38;5;246m▄ [48;5;246m[38;5;231m▄[48;5;231m [48;5;246m▄[48;5;231m [38;5;246m▄[48;5;16m[38;5;231m▄[49m[38;5;16m▄[38;5;236m▄[38;5;235m▄[38;5;234m▄
|
||||
[48;5;236m[38;5;233m▄[48;5;23m[38;5;236m▄[48;5;24m[38;5;23m▄[48;5;66m [48;5;103m[38;5;16m▄[48;5;16m[38;5;255m▄[48;5;255m [48;5;246m▄[48;5;255m [38;5;246m▄ [48;5;246m[38;5;255m▄[48;5;255m [48;5;246m▄[48;5;255m [48;5;246m▄[48;5;255m [48;5;16m▄[48;5;103m[38;5;16m▄[48;5;66m [48;5;24m[38;5;23m▄[48;5;23m[38;5;236m▄[48;5;236m[38;5;233m▄[49m
|
||||
[48;5;235m [48;5;236m[38;5;23m▄[48;5;235m▄[38;5;237m▄▄[48;5;255m▄[38;5;236m▄[38;5;235m▄▄[48;5;246m▄[48;5;255m▄▄▄▄▄[48;5;246m▄[48;5;255m▄▄▄[48;5;246m▄[48;5;255m▄[38;5;236m▄[38;5;237m▄[48;5;235m▄▄[38;5;23m▄ [38;5;234m▄[49m
|
||||
[38;5;235m▀[48;5;23m[38;5;236m▄ [48;5;66m[38;5;24m▄[48;5;67m[38;5;66m▄[48;5;66m [48;5;60m[38;5;67m▄[48;5;24m▄▄▄▄▄▄▄▄▄▄▄▄[48;5;60m▄[48;5;66m [48;5;67m[38;5;66m▄[48;5;66m[38;5;24m▄[48;5;23m [38;5;236m▄[49m[38;5;235m▀
|
||||
▀[48;5;23m[38;5;236m▄ [48;5;24m [38;5;66m▄▄▄[38;5;60m▄▄▄ ▄▄▄[38;5;66m▄▄▄ [48;5;23m [38;5;236m▄[49m[38;5;235m▀
|
||||
▀[48;5;237m[38;5;236m▄[48;5;23m [48;5;24m[38;5;23m▄[48;5;60m▄[48;5;66m[38;5;24m▄[48;5;67m▄▄▄▄▄▄▄▄▄▄▄▄[48;5;66m▄[48;5;60m[38;5;23m▄[48;5;24m▄[48;5;23m [48;5;237m[38;5;236m▄[49m[38;5;235m▀
|
||||
[38;5;236m▀[48;5;23m▄ [48;5;24m[38;5;23m▄▄[48;5;66m[38;5;24m▄▄[48;5;67m[38;5;60m▄▄▄▄▄[38;5;24m▄[48;5;66m▄▄[48;5;24m[38;5;23m▄▄[48;5;23m [38;5;236m▄[49m▀
|
||||
[38;5;235m▀[38;5;236m▀[48;5;23m[38;5;235m▄[38;5;236m▄[38;5;237m▄ [48;5;24m[38;5;23m▄[48;5;23m [38;5;237m▄[38;5;236m▄[38;5;235m▄[49m[38;5;236m▀[38;5;235m▀
|
||||
▀▀▀▀▀▀▀▀
|
||||
[0m
|
||||
RICE
|
||||
}
|
||||
|
||||
coffee() {
|
||||
cat << COFFEE
|
||||
[38;5;231m▄[m[38;5;231m▄[m[38;5;231m▄[m[38;5;195m▄[m[38;5;195m▄[m[38;5;195m▄[m[38;5;195m▄[m[38;5;231m▄[m[38;5;231m▄[m[38;5;231m▄[m
|
||||
[38;5;231m▄[m[48;5;231m [m[48;5;195;38;5;231m▀[m[48;5;52;38;5;195m▀[m[48;5;94;38;5;195m▀[m[48;5;94m [m[48;5;136;38;5;94m▀[m[48;5;94m [m[48;5;94m [m[48;5;94;38;5;195m▀[m[48;5;52;38;5;195m▀[m[48;5;195;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[38;5;231m▄[m
|
||||
[48;5;231m [m[48;5;159;38;5;231m▀[m[48;5;52;38;5;195m▀[m[48;5;52m [m[48;5;52m [m[48;5;94;38;5;136m▀[m[48;5;52;38;5;94m▀[m[48;5;94;38;5;136m▀[m[48;5;94;38;5;136m▀[m[48;5;52m [m[48;5;52m [m[48;5;52m [m[48;5;52m [m[48;5;52m [m[48;5;52m [m[48;5;52;38;5;195m▀[m[48;5;231;38;5;159m▀[m[48;5;231m [m
|
||||
[48;5;231m [m[48;5;159m [m[48;5;195;38;5;231m▀[m[48;5;159;38;5;16m▀[m[48;5;159;38;5;16m▀[m[48;5;231;38;5;52m▀[m[48;5;231;38;5;94m▀[m[48;5;52m [m[48;5;52m [m[48;5;16m [m[48;5;16m [m[48;5;231;38;5;16m▀[m[48;5;231;38;5;16m▀[m[48;5;231;38;5;16m▀[m[48;5;159;38;5;16m▀[m[48;5;195;38;5;231m▀[m[48;5;195;38;5;159m▀[m[48;5;231m [m
|
||||
[48;5;231m [m[48;5;159m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195;38;5;159m▀[m[48;5;195;38;5;159m▀[m[48;5;159;38;5;231m▀[m[48;5;159;38;5;231m▀[m[48;5;159;38;5;231m▀[m[48;5;159;38;5;231m▀[m[48;5;195;38;5;159m▀[m[48;5;195;38;5;159m▀[m[48;5;195;38;5;159m▀[m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[48;5;159m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[38;5;231m▄[m
|
||||
[48;5;231m [m[48;5;159m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;231m [m[38;5;159m▀[m [38;5;195m▀[m[48;5;195m [m[48;5;159;38;5;231m▀[m
|
||||
[48;5;231m [m[48;5;159m [m[48;5;231;38;5;195m▀[m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;195m [m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231m [m [48;5;195m [m[48;5;195;38;5;159m▀[m
|
||||
[48;5;231m [m[48;5;159m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231;38;5;195m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m [48;5;195m [m[48;5;195;38;5;159m▀[m
|
||||
[48;5;231m [m[48;5;159;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m [48;5;195m [m[48;5;195m [m[48;5;159m [m
|
||||
[48;5;231m [m[48;5;231;38;5;159m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;159m [m[48;5;159;38;5;195m▀[m[48;5;231;38;5;195m▀[m[38;5;159m▀[m[38;5;231m▀[m
|
||||
[48;5;231m [m[48;5;159;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[38;5;159m▀[m[38;5;159m▀[m
|
||||
[48;5;37;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;37;38;5;231m▀[m[48;5;37m [m[48;5;37m [m[48;5;37m [m[38;5;37m▄[m[38;5;37m▄[m
|
||||
[38;5;37m▀[m[48;5;37;38;5;231m▀[m[48;5;37;38;5;231m▀[m[48;5;37;38;5;231m▀[m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;231m [m[48;5;37;38;5;231m▀[m[48;5;37;38;5;231m▀[m[48;5;37;38;5;231m▀[m[48;5;37;38;5;231m▀[m[48;5;37m [m[48;5;37m [m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m
|
||||
[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m[38;5;37m▀[m
|
||||
[0m
|
||||
COFFEE
|
||||
}
|
||||
|
||||
steam(){
|
||||
case "$1" in
|
||||
"0")
|
||||
cat << X0
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
X0
|
||||
;;
|
||||
"1")
|
||||
cat << X0
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
X0
|
||||
;;
|
||||
"2")
|
||||
cat << X0
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
X0
|
||||
;;
|
||||
"3")
|
||||
cat << X0
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
: : : : :
|
||||
X0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
hotcoffee() {
|
||||
steam 1
|
||||
coffee
|
||||
|
||||
x=0
|
||||
while :; do
|
||||
cat << X0
|
||||
[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A[A
|
||||
X0
|
||||
steam $x
|
||||
coffee
|
||||
[ "$x" -le "2" ] && x=$((x+1)) || x=0
|
||||
sleep 0.25
|
||||
done
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
*--burger|burger)
|
||||
burger
|
||||
;;
|
||||
*--vburger|vburger)
|
||||
vburger
|
||||
;;
|
||||
*--poptart|poptart)
|
||||
poptart
|
||||
;;
|
||||
*--rice|rice)
|
||||
rice
|
||||
;;
|
||||
*--waffles|waffles)
|
||||
waffles
|
||||
;;
|
||||
*--pancakes|pancakes)
|
||||
pancakes
|
||||
;;
|
||||
*--pizza2|pizza2)
|
||||
pizza2
|
||||
;;
|
||||
*--pizza|pizza)
|
||||
pizza
|
||||
;;
|
||||
*--taco|taco)
|
||||
taco
|
||||
;;
|
||||
*--coffee|coffee)
|
||||
coffee
|
||||
;;
|
||||
*--hotcoffee|hotcoffee)
|
||||
hotcoffee
|
||||
;;
|
||||
*)
|
||||
taco
|
||||
usage
|
||||
;;
|
||||
esac
|
8
.local/bin/format-python
Executable file
8
.local/bin/format-python
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from formatter2.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
24
.local/bin/gap
Executable file
24
.local/bin/gap
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Below command will backup everything inside the project folder
|
||||
git add .
|
||||
|
||||
# Give a comment to the commit if you want
|
||||
echo "####################################"
|
||||
echo "Write your commit comment! $(date +%Y.%m.%d) Update:"
|
||||
echo "####################################"
|
||||
|
||||
read input
|
||||
|
||||
# Committing to the local repository with a message containing the time details and commit text
|
||||
|
||||
git commit -a -m "$(date +%Y.%m.%d) Update $input"
|
||||
|
||||
# Push the local files to github
|
||||
|
||||
git push
|
||||
|
||||
|
||||
echo "################################################################"
|
||||
echo "################### Git Push Done ######################"
|
||||
echo "################################################################"
|
4
.local/bin/gen_cloudripper_defconfig.sh
Normal file
4
.local/bin/gen_cloudripper_defconfig.sh
Normal file
@ -0,0 +1,4 @@
|
||||
KCONFIG_CONFIG=arch/arm64/configs/cloudripper_gki_defconfig \
|
||||
scripts/kconfig/merge_config.sh -m -r \
|
||||
arch/arm64/configs/gki_defconfig \
|
||||
arch/arm64/configs/cloudripper_gki.fragment
|
31
.local/bin/ghosts
Executable file
31
.local/bin/ghosts
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ANSI color scheme script by pfh
|
||||
#
|
||||
# Initializing mod by lolilolicon from Archlinux
|
||||
#
|
||||
|
||||
f=3 b=4
|
||||
for j in f b; do
|
||||
for i in {0..7}; do
|
||||
printf -v $j$i %b "\e[${!j}${i}m"
|
||||
done
|
||||
done
|
||||
bld=$'\e[1m'
|
||||
rst=$'\e[0m'
|
||||
inv=$'\e[7m'
|
||||
cat << EOF
|
||||
|
||||
$f1 ▄▄▄ $f2 ▄▄▄ $f3 ▄▄▄ $f4 ▄▄▄ $f5 ▄▄▄ $f6 ▄▄▄
|
||||
$f1 ▀█▀██ ▄ $f2 ▀█▀██ ▄ $f3 ▀█▀██ ▄ $f4 ▀█▀██ ▄ $f5 ▀█▀██ ▄ $f6 ▀█▀██ ▄
|
||||
$f1 ▀▄██████▀ $f2 ▀▄██████▀ $f3 ▀▄██████▀ $f4 ▀▄██████▀ $f5 ▀▄██████▀ $f6 ▀▄██████▀
|
||||
$f1 ▀█████ $f2 ▀█████ $f3 ▀█████ $f4 ▀█████ $f5 ▀█████ $f6 ▀█████
|
||||
$f1 ▀▀▀▀▄ $f2 ▀▀▀▀▄ $f3 ▀▀▀▀▄ $f4 ▀▀▀▀▄ $f5 ▀▀▀▀▄ $f6 ▀▀▀▀▄
|
||||
$bld
|
||||
$f1 ▄▄▄ $f2 ▄▄▄ $f3 ▄▄▄ $f4 ▄▄▄ $f5 ▄▄▄ $f6 ▄▄▄
|
||||
$f1 ▀█▀██ ▄ $f2 ▀█▀██ ▄ $f3 ▀█▀██ ▄ $f4 ▀█▀██ ▄ $f5 ▀█▀██ ▄ $f6 ▀█▀██ ▄
|
||||
$f1 ▀▄██████▀ $f2 ▀▄██████▀ $f3 ▀▄██████▀ $f4 ▀▄██████▀ $f5 ▀▄██████▀ $f6 ▀▄██████▀
|
||||
$f1 ▀█████ $f2 ▀█████ $f3 ▀█████ $f4 ▀█████ $f5 ▀█████ $f6 ▀█████
|
||||
$f1 ▀▀▀▀▄ $f2 ▀▀▀▀▄ $f3 ▀▀▀▀▄ $f4 ▀▀▀▀▄ $f5 ▀▀▀▀▄ $f6 ▀▀▀▀▄
|
||||
$rst
|
||||
EOF
|
10
.local/bin/gibram
Executable file
10
.local/bin/gibram
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo 'Before:'
|
||||
free -h
|
||||
sleep 1s
|
||||
sync && echo 3 > /proc/sys/vm/drop_caches && swapoff -a && swapon -a && printf '\n%s\n' 'Ram-cache and Swap Cleared'
|
||||
sleep 1s
|
||||
echo 'After:'
|
||||
free -h
|
||||
exit 0
|
5
.local/bin/gitam
Executable file
5
.local/bin/gitam
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
for l in $@; do
|
||||
curl $l.patch | git am -3
|
||||
done
|
87
.local/bin/gitio
Executable file
87
.local/bin/gitio
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ██ ██ ██
|
||||
# █████ ░░ ░██ ░░
|
||||
# ██░░░██ ██ ██████ ██ ██████
|
||||
# ░██ ░██░██░░░██░ ░██ ██░░░░██
|
||||
# ░░██████░██ ░██ ░██░██ ░██
|
||||
# ░░░░░██░██ ░██ ░██░██ ░██
|
||||
# █████ ░██ ░░██ ██░██░░██████
|
||||
# ░░░░░ ░░ ░░ ░░ ░░ ░░░░░░
|
||||
#
|
||||
# create short / vanity github urls
|
||||
# ▟▙
|
||||
# ▟▒░░░░░░░▜▙▜████████████████████████████████▛
|
||||
# ▜▒░░░░░░░▟▛▟▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▛
|
||||
# ▜▛
|
||||
# xero / syntax-samurai <http://git.io/gitio.sh>
|
||||
|
||||
usage () {
|
||||
cat <<EOF
|
||||
|
||||
▟▙
|
||||
▟▒░░░░░░░▜▙▜████████████████████████████████▛
|
||||
▜▒░░░░░░░▟▛▟▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▛
|
||||
▜▛
|
||||
|
||||
create short / vanity github urls
|
||||
usage: $(basename $0) http://github.com/something [-v mini]
|
||||
|
||||
options:
|
||||
-v shortlink
|
||||
-h display this screen
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
err() {
|
||||
echo $1
|
||||
usage
|
||||
}
|
||||
|
||||
optstest() {
|
||||
found=0
|
||||
for arg in "$@"
|
||||
do
|
||||
if echo $arg | awk -F '/' '$3 !~ /github.com|github.io|githubusercontent.com/ { exit 1 }'
|
||||
then
|
||||
GHURL=$arg
|
||||
found=1
|
||||
elif [ $arg = "-h" ]
|
||||
then
|
||||
usage
|
||||
elif [ $arg = "-v" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
VANITY=$arg
|
||||
fi
|
||||
done
|
||||
if [ $found = 0 ]
|
||||
then
|
||||
err " must be a valid github.com url!"
|
||||
fi
|
||||
}
|
||||
|
||||
case $# in
|
||||
1)
|
||||
optstest $1 ;;
|
||||
3)
|
||||
optstest $1 $2 $3 ;;
|
||||
*)
|
||||
err " invalid number of arguments!" ;;
|
||||
esac
|
||||
|
||||
if [ -z "$VANITY" ]
|
||||
then
|
||||
url=`curl -is https://git.io -F "url=$GHURL" | awk '/Location:/ { print $2 }'`
|
||||
else
|
||||
url=`curl -is https://git.io -F "url=$GHURL" -F "code=$VANITY" | awk '/Location:/ { print $2 }'`
|
||||
fi
|
||||
|
||||
if [ -z $url ]
|
||||
then
|
||||
err " must be a valid github.com url!"
|
||||
else
|
||||
echo $url
|
||||
fi
|
132
.local/bin/hex2bin.py
Normal file
132
.local/bin/hex2bin.py
Normal file
@ -0,0 +1,132 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2005-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''Intel HEX file format hex2bin convertor utility.'''
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
|
||||
usage = '''Hex2Bin convertor utility.
|
||||
Usage:
|
||||
python hex2bin.py [options] INFILE [OUTFILE]
|
||||
|
||||
Arguments:
|
||||
INFILE name of hex file for processing.
|
||||
OUTFILE name of output file. If omitted then output
|
||||
will be writing to stdout.
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-p, --pad=FF pad byte for empty spaces (ascii hex value).
|
||||
-r, --range=START:END specify address range for writing output
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
-l, --length=NNNN,
|
||||
-s, --size=NNNN size of output (decimal value).
|
||||
'''
|
||||
|
||||
pad = None
|
||||
start = None
|
||||
end = None
|
||||
size = None
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:l:s:",
|
||||
["help", "version", "pad=", "range=",
|
||||
"length=", "size="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
sys.exit(0)
|
||||
elif o in ("-p", "--pad"):
|
||||
try:
|
||||
pad = int(a, 16) & 0x0FF
|
||||
except:
|
||||
raise getopt.GetoptError('Bad pad value')
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o in ("-l", "--lenght", "-s", "--size"):
|
||||
try:
|
||||
size = int(a, 10)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad size value')
|
||||
|
||||
if start != None and end != None and size != None:
|
||||
raise getopt.GetoptError('Cannot specify START:END and SIZE simultaneously')
|
||||
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
|
||||
if len(args) > 2:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(usage)
|
||||
sys.exit(2)
|
||||
|
||||
fin = args[0]
|
||||
if not os.path.isfile(fin):
|
||||
txt = "ERROR: File not found: %s" % fin # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
sys.exit(1)
|
||||
|
||||
if len(args) == 2:
|
||||
fout = args[1]
|
||||
else:
|
||||
# write to stdout
|
||||
from intelhex import compat
|
||||
fout = compat.get_binary_stdout()
|
||||
|
||||
from intelhex import hex2bin
|
||||
sys.exit(hex2bin(fin, fout, start, end, size, pad))
|
135
.local/bin/hex2dump.py
Normal file
135
.local/bin/hex2dump.py
Normal file
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Show content of hex file as hexdump."""
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
USAGE = '''hex2dump: show content of hex file as hexdump.
|
||||
Usage:
|
||||
python hex2dump.py [options] HEXFILE
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-r, --range=START:END specify address range for dumping
|
||||
(ascii hex value).
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--width=N dump N data bytes per line (default: 16).
|
||||
|
||||
Arguments:
|
||||
HEXFILE name of hex file for processing (use '-' to read
|
||||
from stdin)
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
DEFAULT_WIDTH = 16
|
||||
|
||||
def hex2dump(hexfile, start=None, end=None, width=DEFAULT_WIDTH):
|
||||
import intelhex
|
||||
if hexfile == '-':
|
||||
hexfile = sys.stdin
|
||||
try:
|
||||
ih = intelhex.IntelHex(hexfile)
|
||||
except (IOError, intelhex.IntelHexError):
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Error reading file: %s\n' % e)
|
||||
return 1
|
||||
if not (start is None and end is None):
|
||||
ih = ih[slice(start,end)]
|
||||
ih.dump(tofile=sys.stdout, width=width)
|
||||
return 0
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
|
||||
start = None
|
||||
end = None
|
||||
width = DEFAULT_WIDTH
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvp:r:",
|
||||
["help", "version", "range=", "width="])
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ("-v", "--version"):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except:
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == "--width":
|
||||
try:
|
||||
width = int(a)
|
||||
if width < 1:
|
||||
raise ValueError
|
||||
except:
|
||||
raise getopt.GetoptError('Bad width value (%s)' % a)
|
||||
if not args:
|
||||
raise getopt.GetoptError('Hex file is not specified')
|
||||
if len(args) > 1:
|
||||
raise getopt.GetoptError('Too many arguments')
|
||||
except getopt.GetoptError:
|
||||
msg = sys.exc_info()[1] # current exception
|
||||
txt = 'ERROR: '+str(msg) # that's required to get not-so-dumb result from 2to3 tool
|
||||
print(txt)
|
||||
print(USAGE)
|
||||
return 2
|
||||
|
||||
try:
|
||||
return hex2dump(args[0], start, end, width)
|
||||
except IOError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
import errno
|
||||
if e.errno not in (0, errno.EPIPE):
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(main())
|
90
.local/bin/hexdiff.py
Normal file
90
.local/bin/hexdiff.py
Normal file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2011-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Produce diff for 2 hex files using hex dump as string representation
|
||||
of compared data.
|
||||
"""
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
USAGE = '''hexdiff: diff dumps of 2 hex files.
|
||||
Usage:
|
||||
python hexdiff.py [options] FILE1 FILE2
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) != 2:
|
||||
sys.stderr.write("ERROR: You should specify 2 files to diff.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
fname1, fname2 = args
|
||||
|
||||
from intelhex import IntelHex, diff_dumps
|
||||
ih1 = IntelHex(fname1)
|
||||
ih2 = IntelHex(fname2)
|
||||
diff_dumps(ih1, ih2, name1=fname1, name2=fname2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
108
.local/bin/hexinfo.py
Normal file
108
.local/bin/hexinfo.py
Normal file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2015 Andrew Fernandes <andrew@fernandes.org>
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Summarize the information in a hex file by printing the execution
|
||||
start address (if any), and the address ranges covered by the
|
||||
data (if any), in YAML format.
|
||||
"""
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
USAGE = '''hexinfo: summarize a hex file's contents.
|
||||
Usage:
|
||||
python hexinfo.py [options] FILE [ FILE ... ]
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
INDENT = ' '
|
||||
INLIST = '- '
|
||||
|
||||
def summarize_yaml(fname):
|
||||
print("{:s}file: '{:s}'".format(INLIST, fname))
|
||||
from intelhex import IntelHex
|
||||
ih = IntelHex(fname)
|
||||
if ih.start_addr:
|
||||
keys = sorted(ih.start_addr.keys())
|
||||
if keys == ['CS','IP']:
|
||||
entry = ih.start_addr['CS'] * 65536 + ih.start_addr['IP']
|
||||
elif keys == ['EIP']:
|
||||
entry = ih.start_addr['EIP']
|
||||
else:
|
||||
raise RuntimeError("unknown 'IntelHex.start_addr' found")
|
||||
print("{:s}entry: 0x{:08X}".format(INDENT, entry))
|
||||
segments = ih.segments()
|
||||
if segments:
|
||||
print("{:s}data:".format(INDENT))
|
||||
for s in segments:
|
||||
print("{:s}{:s}{{ first: 0x{:08X}, last: 0x{:08X}, length: 0x{:08X} }}".format(INDENT, INLIST, s[0], s[1]-1, s[1]-s[0]))
|
||||
print("")
|
||||
|
||||
def main(argv=None):
|
||||
import getopt
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(argv, 'hv', ['help', 'version'])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
if len(args) < 1:
|
||||
sys.stderr.write("ERROR: You should specify one or more files to summarize.\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
for fname in args:
|
||||
summarize_yaml(fname)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
178
.local/bin/hexmerge.py
Normal file
178
.local/bin/hexmerge.py
Normal file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (c) 2008-2018 Alexander Belchenko
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms,
|
||||
# with or without modification, are permitted provided
|
||||
# that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce
|
||||
# the above copyright notice, this list of conditions
|
||||
# and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
# * Neither the name of the author nor the names
|
||||
# of its contributors may be used to endorse
|
||||
# or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
"""Merge content of several hex files into one file."""
|
||||
|
||||
VERSION = '2.2'
|
||||
|
||||
USAGE = '''hexmerge: merge content of hex files.
|
||||
Usage:
|
||||
python hexmerge.py [options] FILES...
|
||||
|
||||
Options:
|
||||
-h, --help this help message.
|
||||
-v, --version version info.
|
||||
-o, --output=FILENAME output file name (emit output to stdout
|
||||
if option is not specified)
|
||||
-r, --range=START:END specify address range for output
|
||||
(ascii hex value). Both values are inclusive.
|
||||
Range can be in form 'START:' or ':END'.
|
||||
--no-start-addr Don't write start addr to output file.
|
||||
--overlap=METHOD What to do when data in files overlapped.
|
||||
Supported variants:
|
||||
* error -- stop and show error message (default)
|
||||
* ignore -- keep data from first file that
|
||||
contains data at overlapped address
|
||||
* replace -- use data from last file that
|
||||
contains data at overlapped address
|
||||
|
||||
Arguments:
|
||||
FILES list of hex files for merging
|
||||
(use '-' to read content from stdin)
|
||||
|
||||
You can specify address range for each file in the form:
|
||||
|
||||
filename:START:END
|
||||
|
||||
See description of range option above.
|
||||
|
||||
You can omit START or END, so supported variants are:
|
||||
|
||||
filename:START: read filename and use data starting from START addr
|
||||
filename::END read filename and use data till END addr
|
||||
|
||||
Use entire file content:
|
||||
|
||||
filename
|
||||
or
|
||||
filename::
|
||||
'''
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main(args=None):
|
||||
import getopt
|
||||
|
||||
output = None
|
||||
start = None
|
||||
end = None
|
||||
write_start_addr = True
|
||||
overlap = 'error'
|
||||
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
try:
|
||||
opts, args = getopt.gnu_getopt(args, 'hvo:r:',
|
||||
['help', 'version',
|
||||
'output=', 'range=',
|
||||
'no-start-addr', 'overlap=',
|
||||
])
|
||||
|
||||
for o,a in opts:
|
||||
if o in ('-h', '--help'):
|
||||
print(USAGE)
|
||||
return 0
|
||||
elif o in ('-v', '--version'):
|
||||
print(VERSION)
|
||||
return 0
|
||||
elif o in ('-o', '--output'):
|
||||
output = a
|
||||
elif o in ("-r", "--range"):
|
||||
try:
|
||||
l = a.split(":")
|
||||
if l[0] != '':
|
||||
start = int(l[0], 16)
|
||||
if l[1] != '':
|
||||
end = int(l[1], 16)
|
||||
except (ValueError, IndexError):
|
||||
raise getopt.GetoptError('Bad range value(s)')
|
||||
elif o == '--no-start-addr':
|
||||
write_start_addr = False
|
||||
elif o == '--overlap':
|
||||
if a in ('error', 'ignore', 'replace'):
|
||||
overlap = a
|
||||
else:
|
||||
raise getopt.GetoptError('Bad overlap value')
|
||||
|
||||
if len(args) == 0:
|
||||
raise getopt.GetoptError('You should specify file list')
|
||||
|
||||
except getopt.GetoptError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
|
||||
import intelhex
|
||||
# TODO: move actual merge code into intelhex package as helper function
|
||||
# and write couple of tests for it.
|
||||
res = intelhex.IntelHex()
|
||||
|
||||
def end_addr_inclusive(addr):
|
||||
if addr is not None:
|
||||
return addr + 1
|
||||
return addr
|
||||
|
||||
for f in args:
|
||||
try:
|
||||
fname, fstart, fend = intelhex._get_file_and_addr_range(f)
|
||||
except intelhex._BadFileNotation:
|
||||
sys.stderr.write('Bad argument: "%s"\n' % f)
|
||||
sys.stderr.write(USAGE+"\n")
|
||||
return 1
|
||||
if fname == '-':
|
||||
fname = sys.stdin
|
||||
ih = intelhex.IntelHex(fname)
|
||||
if (fstart, fend) != (None, None):
|
||||
ih = ih[fstart:end_addr_inclusive(fend)]
|
||||
try:
|
||||
res.merge(ih, overlap)
|
||||
except intelhex.AddressOverlapError:
|
||||
e = sys.exc_info()[1] # current exception
|
||||
sys.stderr.write('Merging: '+fname+"\n")
|
||||
sys.stderr.write(str(e)+"\n")
|
||||
return 1
|
||||
|
||||
if (start, end) != (None, None):
|
||||
res = res[start:end_addr_inclusive(end)]
|
||||
if output is None:
|
||||
output = sys.stdout
|
||||
res.write_hex_file(output, write_start_addr)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
1
.local/bin/hintplot
Symbolic link
1
.local/bin/hintplot
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/hintplot
|
36
.local/bin/img2ext4
Executable file
36
.local/bin/img2ext4
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
import sys
|
||||
import mmap
|
||||
|
||||
ext4Magic = '\x53\xEF'
|
||||
ext4MagicOffset = 1080
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("No I/O supplied")
|
||||
exit(1)
|
||||
|
||||
def copyExt4Image(origin, offset, size, dest):
|
||||
with open(origin, 'r') as input:
|
||||
with open(dest, 'w') as output:
|
||||
input.seek(offset - ext4MagicOffset)
|
||||
output.write(input.read(size + ext4MagicOffset))
|
||||
|
||||
def findMagics(input):
|
||||
magics = [0]
|
||||
with open(input, 'r+b') as f:
|
||||
mm = mmap.mmap(f.fileno(), 0)
|
||||
while magics[-1] != -1:
|
||||
magics.append(mm.find(ext4Magic, magics[-1] + ext4MagicOffset))
|
||||
return magics
|
||||
|
||||
systemimg = sys.argv[1]
|
||||
offsets = findMagics(systemimg)
|
||||
if len(offsets[1:]) != 0:
|
||||
for num, offset in enumerate(offsets[1:], start=1):
|
||||
print('ext4 magic number found at byte %d' % offset)
|
||||
name = "{}_part{}.img".format(systemimg, num)
|
||||
print('Creating {}...'.format(name))
|
||||
copyExt4Image(systemimg, offset, offsets[num + 1] - offset, name)
|
||||
else:
|
||||
print("Not ext4 images found")
|
BIN
.local/bin/img2simg
Executable file
BIN
.local/bin/img2simg
Executable file
Binary file not shown.
54
.local/bin/invaders
Executable file
54
.local/bin/invaders
Executable file
@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
# ANSI Color -- use these variables to easily have different color
|
||||
# and format output. Make sure to output the reset sequence after
|
||||
# colors (f = foreground, b = background), and use the 'off'
|
||||
# feature for anything you turn on.
|
||||
|
||||
initializeANSI()
|
||||
{
|
||||
esc=""
|
||||
|
||||
blackf="${esc}[30m"; redf="${esc}[31m"; greenf="${esc}[32m"
|
||||
yellowf="${esc}[33m" bluef="${esc}[34m"; purplef="${esc}[35m"
|
||||
cyanf="${esc}[36m"; whitef="${esc}[37m"
|
||||
|
||||
blackb="${esc}[40m"; redb="${esc}[41m"; greenb="${esc}[42m"
|
||||
yellowb="${esc}[43m" blueb="${esc}[44m"; purpleb="${esc}[45m"
|
||||
cyanb="${esc}[46m"; whiteb="${esc}[47m"
|
||||
|
||||
boldon="${esc}[1m"; boldoff="${esc}[22m"
|
||||
italicson="${esc}[3m"; italicsoff="${esc}[23m"
|
||||
ulon="${esc}[4m"; uloff="${esc}[24m"
|
||||
invon="${esc}[7m"; invoff="${esc}[27m"
|
||||
|
||||
reset="${esc}[0m"
|
||||
}
|
||||
|
||||
# note in this first use that switching colors doesn't require a reset
|
||||
# first - the new color overrides the old one.
|
||||
|
||||
initializeANSI
|
||||
|
||||
cat << EOF
|
||||
|
||||
${boldon}${redf}▀▄ ▄▀ ${reset} ${boldon}${greenf}▄▄▄████▄▄▄ ${reset} ${boldon}${yellowf} ▄██▄ ${reset} ${boldon}${bluef}▀▄ ▄▀ ${reset} ${boldon}${purplef}▄▄▄████▄▄▄ ${reset} ${boldon}${cyanf} ▄██▄ ${reset}
|
||||
${boldon}${redf}▄█▀███▀█▄ ${reset} ${boldon}${greenf}███▀▀██▀▀███${reset} ${boldon}${yellowf}▄█▀██▀█▄${reset} ${boldon}${bluef}▄█▀███▀█▄ ${reset} ${boldon}${purplef}███▀▀██▀▀███${reset} ${boldon}${cyanf}▄█▀██▀█▄${reset}
|
||||
${boldon}${redf}█▀███████▀█${reset} ${boldon}${greenf}▀▀▀██▀▀██▀▀▀${reset} ${boldon}${yellowf}▀▀█▀▀█▀▀${reset} ${boldon}${bluef}█▀███████▀█${reset} ${boldon}${purplef}▀▀▀██▀▀██▀▀▀${reset} ${boldon}${cyanf}▀▀█▀▀█▀▀${reset}
|
||||
${boldon}${redf}▀ ▀▄▄ ▄▄▀ ▀${reset} ${boldon}${greenf}▄▄▀▀ ▀▀ ▀▀▄▄${reset} ${boldon}${yellowf}▄▀▄▀▀▄▀▄${reset} ${boldon}${bluef}▀ ▀▄▄ ▄▄▀ ▀${reset} ${boldon}${purplef}▄▄▀▀ ▀▀ ▀▀▄▄${reset} ${boldon}${cyanf}▄▀▄▀▀▄▀▄${reset}
|
||||
|
||||
${redf}▀▄ ▄▀ ${reset} ${greenf}▄▄▄████▄▄▄ ${reset} ${yellowf} ▄██▄ ${reset} ${bluef}▀▄ ▄▀ ${reset} ${purplef}▄▄▄████▄▄▄ ${reset} ${cyanf} ▄██▄ ${reset}
|
||||
${redf}▄█▀███▀█▄ ${reset} ${greenf}███▀▀██▀▀███${reset} ${yellowf}▄█▀██▀█▄${reset} ${bluef}▄█▀███▀█▄ ${reset} ${purplef}███▀▀██▀▀███${reset} ${cyanf}▄█▀██▀█▄${reset}
|
||||
${redf}█▀███████▀█${reset} ${greenf}▀▀▀██▀▀██▀▀▀${reset} ${yellowf}▀▀█▀▀█▀▀${reset} ${bluef}█▀███████▀█${reset} ${purplef}▀▀▀██▀▀██▀▀▀${reset} ${cyanf}▀▀█▀▀█▀▀${reset}
|
||||
${redf}▀ ▀▄▄ ▄▄▀ ▀${reset} ${greenf}▄▄▀▀ ▀▀ ▀▀▄▄${reset} ${yellowf}▄▀▄▀▀▄▀▄${reset} ${bluef}▀ ▀▄▄ ▄▄▀ ▀${reset} ${purplef}▄▄▀▀ ▀▀ ▀▀▄▄${reset} ${cyanf}▄▀▄▀▀▄▀▄${reset}
|
||||
|
||||
|
||||
${whitef}▌${reset}
|
||||
|
||||
${whitef}▌${reset}
|
||||
${whitef}${reset}
|
||||
${whitef}▄█▄${reset}
|
||||
${whitef}▄█████████▄${reset}
|
||||
${whitef}▀▀▀▀▀▀▀▀▀▀▀${reset}
|
||||
|
||||
EOF
|
561
.local/bin/lineage-build.sh
Executable file
561
.local/bin/lineage-build.sh
Executable file
@ -0,0 +1,561 @@
|
||||
#!/bin/bash
|
||||
# LineageOS build helper script, credit to @AOSPA, @YumeMichi
|
||||
|
||||
# red = errors, cyan = warnings, green = confirmations, blue = informational
|
||||
# plain for generic text, bold for titles, reset flag at each end of line
|
||||
# plain blue should not be used for readability reasons - use plain cyan instead
|
||||
CLR_RST=$(tput sgr0) ## reset flag
|
||||
#CLR_RED=$CLR_RST$(tput setaf 1) # red, plain
|
||||
CLR_GRN=$CLR_RST$(tput setaf 2) # green, plain
|
||||
#CLR_BLU=$CLR_RST$(tput setaf 4) # blue, plain
|
||||
CLR_CYA=$CLR_RST$(tput setaf 6) # cyan, plain
|
||||
CLR_BLD=$(tput bold) ## bold flag
|
||||
CLR_BLD_RED=$CLR_RST$CLR_BLD$(tput setaf 1) # red, bold
|
||||
CLR_BLD_GRN=$CLR_RST$CLR_BLD$(tput setaf 2) # green, bold
|
||||
CLR_BLD_BLU=$CLR_RST$CLR_BLD$(tput setaf 4) # blue, bold
|
||||
#CLR_BLD_CYA=$CLR_RST$CLR_BLD$(tput setaf 6) # cyan, bold
|
||||
|
||||
# Set defaults
|
||||
LINEAGE_BUILD_VARIANT="userdebug"
|
||||
LINEAGE_VERSION_MAJOR="20"
|
||||
LINEAGE_VERSION_MINOR="0"
|
||||
LINEAGE_BUILD_DATE=$(date -u +%Y%m%d)
|
||||
LINEAGE_BUILD_TYPE="X"
|
||||
LINEAGE_EXTRAVERSION=""
|
||||
|
||||
function checkExit() {
|
||||
if [ $? -ne 0 ]; then
|
||||
EXIT_CODE=$?
|
||||
echo "${CLR_BLD_RED}Build failed!${CLR_RST}"
|
||||
echo -e ""
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
}
|
||||
|
||||
# Output usage help
|
||||
function showHelpAndExit {
|
||||
echo -e "${CLR_BLD_BLU}Usage: $0 <device> [options]${CLR_RST}"
|
||||
echo -e ""
|
||||
echo -e "${CLR_BLD_BLU}Options:${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -h, --help Display this help message${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -c, --clean Wipe the tree before building${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -i, --installclean Dirty build - Use 'installclean'${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -r, --repo-sync Sync before building${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -b, --build-id LineageOS unofficial build id${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -t, --build-type Specify build type${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -j, --jobs Specify jobs/threads to use${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -m, --module Build a specific module${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -g, --gms Build with GMS${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -s, --sign-keys Specify path to sign key mappings${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -p, --pwfile Specify path to sign key password file${CLR_RST}"
|
||||
echo -e "${CLR_BLD_BLU} -z, --imgzip Generate fastboot flashable image zip from signed target_files${CLR_RST}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Setup getopt.
|
||||
long_opts="help,clean,installclean,repo-sync,build-id:,build-type:,jobs:,module:,gms,sign-keys:,pwfile:,imgzip"
|
||||
getopt_cmd=$(getopt -o hcir:b:t:j:m:gs:p:z --long "$long_opts" \
|
||||
-n "$(basename "$0")" -- "$@") ||
|
||||
{
|
||||
echo -e "${CLR_BLD_RED}\nError: Getopt failed. Extra args\n${CLR_RST}"
|
||||
showHelpAndExit
|
||||
exit 1
|
||||
}
|
||||
|
||||
eval set -- "$getopt_cmd"
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h | --help | h | help) showHelpAndExit ;;
|
||||
-c | --clean | c | clean) FLAG_CLEAN_BUILD=y ;;
|
||||
-i | --installclean | i | installclean) FLAG_INSTALLCLEAN_BUILD=y ;;
|
||||
-r | --repo-sync | r | repo-sync) FLAG_SYNC=y ;;
|
||||
-b | --build-id | b | build-id)
|
||||
LINEAGE_BUILD_ID="$2"
|
||||
shift
|
||||
;;
|
||||
-t | --build-type | t | build-type)
|
||||
LINEAGE_BUILD_VARIANT="$2"
|
||||
shift
|
||||
;;
|
||||
-j | --jobs | j | jobs)
|
||||
JOBS="$2"
|
||||
shift
|
||||
;;
|
||||
-m | --module | m | module)
|
||||
MODULES+=("$2")
|
||||
echo "$2"
|
||||
shift
|
||||
;;
|
||||
-g | --gms | g | gms) FLAG_GMS="y" ;;
|
||||
-s | --sign-keys | s | sign-keys)
|
||||
KEY_MAPPINGS="$2"
|
||||
shift
|
||||
;;
|
||||
-p | --pwfile | p | pwfile)
|
||||
PWFILE="$2"
|
||||
shift
|
||||
;;
|
||||
-z | --imgzip | img | imgzip) FLAG_IMG_ZIP=y ;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Mandatory argument
|
||||
if [ $# -eq 0 ]; then
|
||||
echo -e "${CLR_BLD_RED}Error: No device specified${CLR_RST}"
|
||||
showHelpAndExit
|
||||
fi
|
||||
export DEVICE="$1"
|
||||
shift
|
||||
|
||||
# Make sure we are running on 64-bit before carrying on with anything
|
||||
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
|
||||
if [ "$ARCH" != "64" ]; then
|
||||
echo -e "${CLR_BLD_RED}error: unsupported arch (expected: 64, found: $ARCH)${CLR_RST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up paths
|
||||
#cd $(dirname $0)
|
||||
DIR_ROOT=$(pwd)
|
||||
|
||||
# Make sure everything looks sane so far
|
||||
if [ ! -d "$DIR_ROOT/vendor/lineage" ]; then
|
||||
echo -e "${CLR_BLD_RED}error: insane root directory ($DIR_ROOT)${CLR_RST}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Setup LineageOS build id if specified
|
||||
if [ "$LINEAGE_BUILD_ID" ]; then
|
||||
LINEAGE_EXTRAVERSION="-$LINEAGE_BUILD_ID"
|
||||
export TARGET_UNOFFICIAL_BUILD_ID=$LINEAGE_BUILD_ID
|
||||
fi
|
||||
|
||||
# Initializationizing!
|
||||
echo -e "${CLR_BLD_BLU}Setting up the environment${CLR_RST}"
|
||||
echo -e ""
|
||||
# shellcheck source=/dev/null
|
||||
. build/envsetup.sh
|
||||
echo -e ""
|
||||
|
||||
# Use the thread count specified by user
|
||||
CMD=""
|
||||
if [ "$JOBS" ]; then
|
||||
CMD+="-j$JOBS"
|
||||
fi
|
||||
|
||||
# Pick the default thread count (allow overrides from the environment)
|
||||
if [ -z "$JOBS" ]; then
|
||||
if [ "$(uname -s)" = 'Darwin' ]; then
|
||||
JOBS=$(sysctl -n machdep.cpu.core_count)
|
||||
else
|
||||
JOBS=$(grep </proc/cpuinfo -c '^processor')
|
||||
fi
|
||||
fi
|
||||
|
||||
# Grab the build version
|
||||
LINEAGE_VERSION_SUFFIX=$LINEAGE_BUILD_DATE-$LINEAGE_BUILD_TYPE$LINEAGE_EXTRAVERSION-$DEVICE
|
||||
LINEAGE_VERSION=lineage-$LINEAGE_VERSION_MAJOR.$LINEAGE_VERSION_MINOR-$LINEAGE_VERSION_SUFFIX
|
||||
|
||||
# Prep for a clean build, if requested so
|
||||
if [ "$FLAG_CLEAN_BUILD" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Cleaning output files left from old builds${CLR_RST}"
|
||||
echo -e ""
|
||||
m clobber "$CMD"
|
||||
fi
|
||||
|
||||
# Sync up, if asked to
|
||||
if [ "$FLAG_SYNC" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Downloading the latest source files${CLR_RST}"
|
||||
echo -e ""
|
||||
repo sync -j"$JOBS" -c --no-clone-bundle --current-branch --no-tags
|
||||
fi
|
||||
|
||||
# GMS
|
||||
if [ "$FLAG_GMS" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Building with GMS${CLR_RST}"
|
||||
echo -e ""
|
||||
export WITH_GMS=true
|
||||
fi
|
||||
|
||||
# Check the starting time (of the real build process)
|
||||
TIME_START=$(date +%s.%N)
|
||||
|
||||
# Friendly logging to tell the user everything is working fine is always nice
|
||||
echo -e "${CLR_BLD_GRN}Building LineageOS $LINEAGE_VERSION for $DEVICE${CLR_RST}"
|
||||
echo -e "${CLR_GRN}Start time: $(date)${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
# Lunch-time!
|
||||
echo -e "${CLR_BLD_BLU}Lunching $DEVICE${CLR_RST} ${CLR_CYA}(Including dependencies sync)${CLR_RST}"
|
||||
echo -e ""
|
||||
lunch "lineage_$DEVICE-$LINEAGE_BUILD_VARIANT"
|
||||
checkExit
|
||||
echo -e ""
|
||||
|
||||
# Perform installclean, if requested so
|
||||
if [ "$FLAG_INSTALLCLEAN_BUILD" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Cleaning compiled image files left from old builds${CLR_RST}"
|
||||
echo -e ""
|
||||
m installclean "$CMD"
|
||||
fi
|
||||
|
||||
# Build away!
|
||||
echo -e "${CLR_BLD_BLU}Starting compilation${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
# Build a specific module(s)
|
||||
if [ "${MODULES[*]}" ]; then
|
||||
m "${MODULES[@]}" "$CMD"
|
||||
checkExit
|
||||
|
||||
# Build signed rom package if specified
|
||||
elif [ "${KEY_MAPPINGS}" ]; then
|
||||
# Set sign key password file if specified
|
||||
if [ "${PWFILE}" ]; then
|
||||
export ANDROID_PW_FILE=$PWFILE
|
||||
fi
|
||||
|
||||
# Make target-files-package
|
||||
m otatools target-files-package "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
echo -e "${CLR_BLD_BLU}Signing target files apks${CLR_RST}"
|
||||
# sign_target_files_apks -o -d $KEY_MAPPINGS \
|
||||
# "$OUT/obj/PACKAGING/target_files_intermediates/lineage_$DEVICE-target_files-eng.nobody.zip" \
|
||||
# signed-target_files.zip
|
||||
|
||||
if [ "$FLAG_GMS" = 'y' ]; then
|
||||
SIGNING_FLAGS="-e Gallery2.apk= -e GoogleCalendarSyncAdapter.apk= -e GoogleContactsSyncAdapter.apk=
|
||||
-e LocalContactsBackup.apk= -e MarkupGoogle.apk= -e ModuleMetadata.apk= -e PhotoTable.apk=
|
||||
-e PixelCameraServicesC10.apk=
|
||||
-e PrebuiltExchange3Google.apk=
|
||||
-e Recorder.apk=
|
||||
-e SpeechServicesByGoogle.apk=
|
||||
-e ThemesStub.apk=
|
||||
-e VZWAPNLib.apk=
|
||||
-e messaging.apk=
|
||||
-e talkback.apk=
|
||||
-e DisplayCutoutEmulationCornerOverlay.apk=
|
||||
-e DisplayCutoutEmulationDoubleOverlay.apk=
|
||||
-e DisplayCutoutEmulationHoleOverlay.apk=
|
||||
-e DisplayCutoutEmulationTallOverlay.apk=
|
||||
-e DisplayCutoutEmulationWaterfallOverlay.apk=
|
||||
-e NoCutoutOverlay.apk=
|
||||
-e DocumentsUIOverlay.apk=
|
||||
-e EuiccSupportPixelOverlay.apk=
|
||||
-e FontLatoOverlay.apk=
|
||||
-e FontNotoSerifSourceOverlay.apk=
|
||||
-e FontRubikOverlay.apk=
|
||||
-e GmsOverlay.apk=
|
||||
-e GmsSettingsProviderOverlay.apk=
|
||||
-e GoogleParts__auto_generated_rro_product.apk=
|
||||
-e IconPackCircularAndroidOverlay.apk=
|
||||
-e IconPackCircularLauncherOverlay.apk=
|
||||
-e IconPackCircularSettingsOverlay.apk=
|
||||
-e IconPackCircularSystemUIOverlay.apk=
|
||||
-e IconPackFilledAndroidOverlay.apk=
|
||||
-e IconPackFilledLauncherOverlay.apk=
|
||||
-e IconPackFilledSettingsOverlay.apk=
|
||||
-e IconPackFilledSystemUIOverlay.apk=
|
||||
-e IconPackKaiAndroidOverlay.apk=
|
||||
-e IconPackKaiLauncherOverlay.apk=
|
||||
-e IconPackKaiSettingsOverlay.apk=
|
||||
-e IconPackKaiSystemUIOverlay.apk=
|
||||
-e IconPackRoundedAndroidOverlay.apk=
|
||||
-e IconPackRoundedLauncherOverlay.apk=
|
||||
-e IconPackRoundedSettingsOverlay.apk=
|
||||
-e IconPackRoundedSystemUIOverlay.apk=
|
||||
-e IconPackSamAndroidOverlay.apk=
|
||||
-e IconPackSamLauncherOverlay.apk=
|
||||
-e IconPackSamSettingsOverlay.apk=
|
||||
-e IconPackSamSystemUIOverlay.apk=
|
||||
-e IconPackVictorAndroidOverlay.apk=
|
||||
-e IconPackVictorLauncherOverlay.apk=
|
||||
-e IconPackVictorSettingsOverlay.apk=
|
||||
-e IconPackVictorSystemUIOverlay.apk=
|
||||
-e IconShapePebbleOverlay.apk=
|
||||
-e IconShapeRoundedRectOverlay.apk=
|
||||
-e IconShapeSquareOverlay.apk=
|
||||
-e IconShapeSquircleOverlay.apk=
|
||||
-e IconShapeTaperedRectOverlay.apk=
|
||||
-e IconShapeTeardropOverlay.apk=
|
||||
-e IconShapeVesselOverlay.apk=
|
||||
-e ImsServiceEntitlement__auto_generated_rro_product.apk=
|
||||
-e LineageBlackTheme.apk=
|
||||
-e LineageNavigationBarNoHint.apk=
|
||||
-e LineageParts__auto_generated_rro_product.apk=
|
||||
-e LineageSettingsProvider__auto_generated_rro_product.apk=
|
||||
-e LineageSetupWizard__auto_generated_rro_product.apk=
|
||||
-e ManagedProvisioning__auto_generated_rro_product.apk=
|
||||
-e NavigationBarMode3ButtonOverlay.apk=
|
||||
-e NavigationBarModeGesturalOverlay.apk=
|
||||
-e NavigationBarModeGesturalOverlayExtraWideBack.apk=
|
||||
-e NavigationBarModeGesturalOverlayNarrowBack.apk=
|
||||
-e NavigationBarModeGesturalOverlayWideBack.apk=
|
||||
-e NetworkStackOverlay.apk=
|
||||
-e SettingsOverlayGE2AE.apk=
|
||||
-e SettingsOverlayGFE4J.apk=
|
||||
-e SettingsOverlayGP4BC.apk=
|
||||
-e SettingsProvider__auto_generated_rro_product.apk=
|
||||
-e Settings__auto_generated_rro_product.apk=
|
||||
-e SimpleDeviceConfig__auto_generated_rro_product.apk=
|
||||
-e StorageManager__auto_generated_rro_product.apk=
|
||||
-e SystemUI__auto_generated_rro_product.apk=
|
||||
-e TrebuchetOverlay.apk=
|
||||
-e TrebuchetQuickStep__auto_generated_rro_product.apk=
|
||||
-e WifiOverlay2022_C10.apk=
|
||||
-e framework-res__auto_generated_rro_product.apk=
|
||||
-e org.lineageos.platform-res__auto_generated_rro_product.apk=
|
||||
-e DCMO.apk=
|
||||
-e DMService.apk=
|
||||
-e DeviceIntelligenceNetworkPrebuilt.apk=
|
||||
-e DevicePersonalizationPrebuiltPixel2022.apk=
|
||||
-e DiagMon.apk=
|
||||
-e Dialer.apk=
|
||||
-e EuiccGoogle.apk=
|
||||
-e GmsCore.apk=
|
||||
-e GooglePartnerSetup.apk=
|
||||
-e GoogleRestore.apk=
|
||||
-e HardwareInfo.apk=
|
||||
-e HotwordEnrollmentOKGoogleFUSIONPro.apk=
|
||||
-e HotwordEnrollmentXGoogleFUSIONPro.apk=
|
||||
-e ImsServiceEntitlement.apk=
|
||||
-e OemDmTrigger.apk=
|
||||
-e OneTimeInitializer.apk=
|
||||
-e Phonesky.apk=
|
||||
-e SettingsIntelligence.apk=
|
||||
-e TetheringEntitlement.apk=
|
||||
-e Velvet.apk=
|
||||
-e WfcActivation.apk=
|
||||
-e EasterEgg.apk=
|
||||
-e ExtShared.apk=
|
||||
-e KeyChain.apk=
|
||||
-e NfcNci.apk=
|
||||
-e PacProcessor.apk=
|
||||
-e PartnerBookmarksProvider.apk=
|
||||
-e PrintRecommendationService.apk=
|
||||
-e PrintSpooler.apk=
|
||||
-e SecureElement.apk=
|
||||
-e SimAppDialog.apk=
|
||||
-e Stk.apk=
|
||||
-e WallpaperBackup.apk=
|
||||
-e BuildManifest.apk=
|
||||
-e framework-res.apk=
|
||||
-e org.lineageos.platform-res.apk=
|
||||
-e DocumentsUI.apk=
|
||||
-e DownloadProvider.apk=
|
||||
-e DownloadProviderUi.apk=
|
||||
-e DynamicSystemInstallationService.apk=
|
||||
-e ExternalStorageProvider.apk=
|
||||
-e FusedLocation.apk=
|
||||
-e InputDevices.apk=
|
||||
-e IntentResolver.apk=
|
||||
-e LiveWallpapersPicker.apk=
|
||||
-e LocalTransport.apk=
|
||||
-e ManagedProvisioning.apk=
|
||||
-e MediaProviderLegacy.apk=
|
||||
-e MmsService.apk=
|
||||
-e MtpService.apk=
|
||||
-e NetworkStack.apk=
|
||||
-e NetworkStackNext.apk=
|
||||
-e ONS.apk=
|
||||
-e PackageInstaller.apk=
|
||||
-e ProxyHandler.apk=
|
||||
-e SettingsProvider.apk=
|
||||
-e SharedStorageBackup.apk=
|
||||
-e Shell.apk=
|
||||
-e SoundPicker.apk=
|
||||
-e StatementService.apk=
|
||||
-e Tag.apk=
|
||||
-e TeleService.apk=
|
||||
-e Telecom.apk=
|
||||
-e TelephonyProvider.apk=
|
||||
-e UserDictionaryProvider.apk=
|
||||
-e VpnDialogs.apk=
|
||||
-e OemRilHookService.apk=
|
||||
-e Profiles.apk=
|
||||
-e EuiccGoogleOverlay.apk=
|
||||
-e EuiccSupportPixel.apk=
|
||||
-e EuiccSupportPixelPermissions.apk=
|
||||
-e GoogleFeedback.apk=
|
||||
-e GoogleParts.apk=
|
||||
-e GoogleServicesFramework.apk=
|
||||
-e HbmSVManager.apk=
|
||||
-e Iwlan.apk=
|
||||
-e LLKAgent.apk=
|
||||
-e LineageParts.apk=
|
||||
-e LineageSettingsProvider.apk=
|
||||
-e LineageSetupWizard.apk=
|
||||
-e MyVerizonServices.apk=
|
||||
-e OemRilService.apk=
|
||||
-e PixelNfc.apk=
|
||||
-e QualifiedNetworksService.apk=
|
||||
-e QuickAccessWallet.apk=
|
||||
-e RemoteProvisioner.apk=
|
||||
-e RilConfigService.apk=
|
||||
-e Seedvault.apk=
|
||||
-e Settings.apk=
|
||||
-e SetupWizard.apk=
|
||||
-e ShannonIms.apk=
|
||||
-e ShannonRcs.apk=
|
||||
-e SimpleDeviceConfig.apk=
|
||||
-e StorageManager.apk=
|
||||
-e SystemUI.apk=
|
||||
-e ThemePicker.apk=
|
||||
-e TrebuchetQuickStep.apk=
|
||||
-e UwbVendorService.apk=
|
||||
-e grilservice.apk=
|
||||
-e GoogleParts__auto_generated_rro_vendor.apk=
|
||||
-e LineageParts__auto_generated_rro_vendor.apk=
|
||||
-e LineageSetupWizard__auto_generated_rro_vendor.apk=
|
||||
-e NfcNci__auto_generated_rro_vendor.apk=
|
||||
-e ONS__auto_generated_rro_vendor.apk=
|
||||
-e SettingsProvider__auto_generated_rro_vendor.apk=
|
||||
-e Settings__auto_generated_rro_vendor.apk=
|
||||
-e SimpleDeviceConfig__auto_generated_rro_vendor.apk=
|
||||
-e StorageManager__auto_generated_rro_vendor.apk=
|
||||
-e SystemUI__auto_generated_rro_vendor.apk=
|
||||
-e TeleService__auto_generated_rro_vendor.apk=
|
||||
-e framework-res__auto_generated_rro_vendor.apk=
|
||||
-e org.lineageos.platform-res__auto_generated_rro_vendor.apk=
|
||||
--extra_apks com.android.adbd.apex=$KEY_MAPPINGS/com.android.adbd
|
||||
--extra_apex_payload_key com.android.adbd.apex=$KEY_MAPPINGS/com.android.adbd.pem
|
||||
--extra_apks com.android.adservices.apex=$KEY_MAPPINGS/com.android.adservices
|
||||
--extra_apex_payload_key com.android.adservices.apex=$KEY_MAPPINGS/com.android.adservices.pem
|
||||
--extra_apks com.android.adservices.api.apex=$KEY_MAPPINGS/com.android.adservices.api
|
||||
--extra_apex_payload_key com.android.adservices.api.apex=$KEY_MAPPINGS/com.android.adservices.api.pem
|
||||
--extra_apks com.android.appsearch.apex=$KEY_MAPPINGS/com.android.appsearch
|
||||
--extra_apex_payload_key com.android.appsearch.apex=$KEY_MAPPINGS/com.android.appsearch.pem
|
||||
--extra_apks com.android.art.apex=$KEY_MAPPINGS/com.android.art
|
||||
--extra_apex_payload_key com.android.art.apex=$KEY_MAPPINGS/com.android.art.pem
|
||||
--extra_apks com.android.bluetooth.apex=$KEY_MAPPINGS/com.android.bluetooth
|
||||
--extra_apex_payload_key com.android.bluetooth.apex=$KEY_MAPPINGS/com.android.bluetooth.pem
|
||||
--extra_apks com.android.btservices.apex=$KEY_MAPPINGS/com.android.btservices
|
||||
--extra_apex_payload_key com.android.btservices.apex=$KEY_MAPPINGS/com.android.btservices.pem
|
||||
--extra_apks com.android.cellbroadcast.apex=$KEY_MAPPINGS/com.android.cellbroadcast
|
||||
--extra_apex_payload_key com.android.cellbroadcast.apex=$KEY_MAPPINGS/com.android.cellbroadcast.pem
|
||||
--extra_apks com.android.compos.apex=$KEY_MAPPINGS/com.android.compos
|
||||
--extra_apex_payload_key com.android.compos.apex=$KEY_MAPPINGS/com.android.compos.pem
|
||||
--extra_apks com.android.connectivity.resources.apex=$KEY_MAPPINGS/com.android.connectivity.resources
|
||||
--extra_apex_payload_key com.android.connectivity.resources.apex=$KEY_MAPPINGS/com.android.connectivity.resources.pem
|
||||
--extra_apks com.android.conscrypt.apex=$KEY_MAPPINGS/com.android.conscrypt
|
||||
--extra_apex_payload_key com.android.conscrypt.apex=$KEY_MAPPINGS/com.android.conscrypt.pem
|
||||
--extra_apks com.android.extservices.apex=$KEY_MAPPINGS/com.android.extservices
|
||||
--extra_apex_payload_key com.android.extservices.apex=$KEY_MAPPINGS/com.android.extservices.pem
|
||||
--extra_apks com.android.hotspot2.osulogin.apex=$KEY_MAPPINGS/com.android.hotspot2.osulogin
|
||||
--extra_apex_payload_key com.android.hotspot2.osulogin.apex=$KEY_MAPPINGS/com.android.hotspot2.osulogin.pem
|
||||
--extra_apks com.android.i18n.apex=$KEY_MAPPINGS/com.android.i18n
|
||||
--extra_apex_payload_key com.android.i18n.apex=$KEY_MAPPINGS/com.android.i18n.pem
|
||||
--extra_apks com.android.ipsec.apex=$KEY_MAPPINGS/com.android.ipsec
|
||||
--extra_apex_payload_key com.android.ipsec.apex=$KEY_MAPPINGS/com.android.ipsec.pem
|
||||
--extra_apks com.android.media.apex=$KEY_MAPPINGS/com.android.media
|
||||
--extra_apex_payload_key com.android.media.apex=$KEY_MAPPINGS/com.android.media.pem
|
||||
--extra_apks com.android.media.swcodec.apex=$KEY_MAPPINGS/com.android.media.swcodec
|
||||
--extra_apex_payload_key com.android.media.swcodec.apex=$KEY_MAPPINGS/com.android.media.swcodec.pem
|
||||
--extra_apks com.android.mediaprovider.apex=$KEY_MAPPINGS/com.android.mediaprovider
|
||||
--extra_apex_payload_key com.android.mediaprovider.apex=$KEY_MAPPINGS/com.android.mediaprovider.pem
|
||||
--extra_apks com.android.nearby.halfsheet.apex=$KEY_MAPPINGS/com.android.nearby.halfsheet
|
||||
--extra_apex_payload_key com.android.nearby.halfsheet.apex=$KEY_MAPPINGS/com.android.nearby.halfsheet.pem
|
||||
--extra_apks com.android.neuralnetworks.apex=$KEY_MAPPINGS/com.android.neuralnetworks
|
||||
--extra_apex_payload_key com.android.neuralnetworks.apex=$KEY_MAPPINGS/com.android.neuralnetworks.pem
|
||||
--extra_apks com.android.ondevicepersonalization.apex=$KEY_MAPPINGS/com.android.ondevicepersonalization
|
||||
--extra_apex_payload_key com.android.ondevicepersonalization.apex=$KEY_MAPPINGS/com.android.ondevicepersonalization.pem
|
||||
--extra_apks com.android.os.statsd.apex=$KEY_MAPPINGS/com.android.os.statsd
|
||||
--extra_apex_payload_key com.android.os.statsd.apex=$KEY_MAPPINGS/com.android.os.statsd.pem
|
||||
--extra_apks com.android.permission.apex=$KEY_MAPPINGS/com.android.permission
|
||||
--extra_apex_payload_key com.android.permission.apex=$KEY_MAPPINGS/com.android.permission.pem
|
||||
--extra_apks com.android.resolv.apex=$KEY_MAPPINGS/com.android.resolv
|
||||
--extra_apex_payload_key com.android.resolv.apex=$KEY_MAPPINGS/com.android.resolv.pem
|
||||
--extra_apks com.android.runtime.apex=$KEY_MAPPINGS/com.android.runtime
|
||||
--extra_apex_payload_key com.android.runtime.apex=$KEY_MAPPINGS/com.android.runtime.pem
|
||||
--extra_apks com.android.safetycenter.resources.apex=$KEY_MAPPINGS/com.android.safetycenter.resources
|
||||
--extra_apex_payload_key com.android.safetycenter.resources.apex=$KEY_MAPPINGS/com.android.safetycenter.resources.pem
|
||||
--extra_apks com.android.scheduling.apex=$KEY_MAPPINGS/com.android.scheduling
|
||||
--extra_apex_payload_key com.android.scheduling.apex=$KEY_MAPPINGS/com.android.scheduling.pem
|
||||
--extra_apks com.android.sdkext.apex=$KEY_MAPPINGS/com.android.sdkext
|
||||
--extra_apex_payload_key com.android.sdkext.apex=$KEY_MAPPINGS/com.android.sdkext.pem
|
||||
--extra_apks com.android.support.apexer.apex=$KEY_MAPPINGS/com.android.support.apexer
|
||||
--extra_apex_payload_key com.android.support.apexer.apex=$KEY_MAPPINGS/com.android.support.apexer.pem
|
||||
--extra_apks com.android.telephony.apex=$KEY_MAPPINGS/com.android.telephony
|
||||
--extra_apex_payload_key com.android.telephony.apex=$KEY_MAPPINGS/com.android.telephony.pem
|
||||
--extra_apks com.android.tethering.apex=$KEY_MAPPINGS/com.android.tethering
|
||||
--extra_apex_payload_key com.android.tethering.apex=$KEY_MAPPINGS/com.android.tethering.pem
|
||||
--extra_apks com.android.tzdata.apex=$KEY_MAPPINGS/com.android.tzdata
|
||||
--extra_apex_payload_key com.android.tzdata.apex=$KEY_MAPPINGS/com.android.tzdata.pem
|
||||
--extra_apks com.android.uwb.apex=$KEY_MAPPINGS/com.android.uwb
|
||||
--extra_apex_payload_key com.android.uwb.apex=$KEY_MAPPINGS/com.android.uwb.pem
|
||||
--extra_apks com.android.uwb.resources.apex=$KEY_MAPPINGS/com.android.uwb.resources
|
||||
--extra_apex_payload_key com.android.uwb.resources.apex=$KEY_MAPPINGS/com.android.uwb.resources.pem
|
||||
--extra_apks com.android.virt.apex=$KEY_MAPPINGS/com.android.virt
|
||||
--extra_apex_payload_key com.android.virt.apex=$KEY_MAPPINGS/com.android.virt.pem
|
||||
--extra_apks com.android.vndk.current.apex=$KEY_MAPPINGS/com.android.vndk.current
|
||||
--extra_apex_payload_key com.android.vndk.current.apex=$KEY_MAPPINGS/com.android.vndk.current.pem
|
||||
--extra_apks com.android.wifi.apex=$KEY_MAPPINGS/com.android.wifi
|
||||
--extra_apex_payload_key com.android.wifi.apex=$KEY_MAPPINGS/com.android.wifi.pem
|
||||
--extra_apks com.android.wifi.dialog.apex=$KEY_MAPPINGS/com.android.wifi.dialog
|
||||
--extra_apex_payload_key com.android.wifi.dialog.apex=$KEY_MAPPINGS/com.android.wifi.dialog.pem
|
||||
--extra_apks com.android.wifi.resources.apex=$KEY_MAPPINGS/com.android.wifi.resources
|
||||
--extra_apex_payload_key com.android.wifi.resources.apex=$KEY_MAPPINGS/com.android.wifi.resources.pem
|
||||
--extra_apks com.qorvo.uwb.apex=$KEY_MAPPINGS/com.qorvo.uwb
|
||||
--extra_apex_payload_key com.qorvo.uwb.apex=$KEY_MAPPINGS/com.qorvo.uwb.pem"
|
||||
fi
|
||||
|
||||
sign_target_files_apks -o -d "$KEY_MAPPINGS" \
|
||||
$OUT/obj/PACKAGING/target_files_intermediates/lineage_$DEVICE-target_files-eng.nobody.zip \
|
||||
signed-target_files.zip
|
||||
|
||||
checkExit
|
||||
|
||||
if [ "$FLAG_IMG_ZIP" = 'y' ]; then
|
||||
echo -e "${CLR_BLD_BLU}Generating signed fastboot package${CLR_RST}"
|
||||
img_from_target_files \
|
||||
signed-target_files.zip \
|
||||
"$LINEAGE_VERSION-image.zip"
|
||||
checkExit
|
||||
else
|
||||
echo -e "${CLR_BLD_BLU}Generating signed install package${CLR_RST}"
|
||||
ota_from_target_files -k $KEY_MAPPINGS/releasekey \
|
||||
--block --backup=true \
|
||||
signed-target_files.zip \
|
||||
"$LINEAGE_VERSION.zip"
|
||||
checkExit
|
||||
fi
|
||||
|
||||
# Build rom package
|
||||
elif [ "$FLAG_IMG_ZIP" = 'y' ]; then
|
||||
m otatools target-files-package "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
echo -e "${CLR_BLD_BLU}Generating fastboot package${CLR_RST}"
|
||||
img_from_target_files \
|
||||
"$OUT/obj/PACKAGING/target_files_intermediates/lineage_$DEVICE-target_files-eng.nobody.zip" \
|
||||
"$LINEAGE_VERSION-image.zip"
|
||||
|
||||
checkExit
|
||||
|
||||
else
|
||||
m otapackage "$CMD"
|
||||
|
||||
checkExit
|
||||
|
||||
mv -f "$OUT/lineage_$DEVICE-ota-eng.nobody.zip" "$LINEAGE_VERSION.zip"
|
||||
echo "Package Complete: $LINEAGE_VERSION.zip"
|
||||
fi
|
||||
echo -e ""
|
||||
|
||||
# Check the finishing time
|
||||
TIME_END=$(date +%s.%N)
|
||||
|
||||
# Log those times at the end as a fun fact of the day
|
||||
echo -e "${CLR_BLD_GRN}Total time elapsed:${CLR_RST} ${CLR_GRN}$(echo "($TIME_END - $TIME_START) / 60" | bc) minutes ($(echo "$TIME_END - $TIME_START" | bc) seconds)${CLR_RST}"
|
||||
echo -e ""
|
||||
|
||||
exit 0
|
262
.local/bin/linux-stable.sh
Executable file
262
.local/bin/linux-stable.sh
Executable file
@ -0,0 +1,262 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pull in linux-stable updates to a kernel tree
|
||||
#
|
||||
# Copyright (C) 2017-2018 Nathan Chancellor
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
|
||||
# Colors for script
|
||||
BOLD="\033[1m"
|
||||
GRN="\033[01;32m"
|
||||
RED="\033[01;31m"
|
||||
RST="\033[0m"
|
||||
YLW="\033[01;33m"
|
||||
|
||||
|
||||
# Alias for echo to handle escape codes like colors
|
||||
function echo() {
|
||||
command echo -e "$@"
|
||||
}
|
||||
|
||||
|
||||
# Prints a formatted header to point out what is being done to the user
|
||||
function header() {
|
||||
if [[ -n ${2} ]]; then
|
||||
COLOR=${2}
|
||||
else
|
||||
COLOR=${RED}
|
||||
fi
|
||||
echo "${COLOR}"
|
||||
# shellcheck disable=SC2034
|
||||
echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
|
||||
echo "== ${1} =="
|
||||
# shellcheck disable=SC2034
|
||||
echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
|
||||
echo "${RST}"
|
||||
}
|
||||
|
||||
|
||||
# Prints an error in bold red
|
||||
function die() {
|
||||
echo
|
||||
echo "${RED}${1}${RST}"
|
||||
[[ ${2} = "-h" ]] && ${0} -h
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
# Prints a statement in bold green
|
||||
function success() {
|
||||
echo
|
||||
echo "${GRN}${1}${RST}"
|
||||
[[ -z ${2} ]] && echo
|
||||
}
|
||||
|
||||
|
||||
# Prints a warning in bold yellow
|
||||
function warn() {
|
||||
echo
|
||||
echo "${YLW}${1}${RST}"
|
||||
[[ -z ${2} ]] && echo
|
||||
}
|
||||
|
||||
|
||||
# Parse the provided parameters
|
||||
function parse_parameters() {
|
||||
while [[ $# -ge 1 ]]; do
|
||||
case ${1} in
|
||||
# Use git cherry-pick
|
||||
"-c"|"--cherry-pick")
|
||||
UPDATE_METHOD=cherry-pick ;;
|
||||
|
||||
# Only update the linux-stable remote
|
||||
"-f"|"--fetch-only")
|
||||
FETCH_REMOTE_ONLY=true ;;
|
||||
|
||||
# Help menu
|
||||
"-h"|"--help")
|
||||
echo
|
||||
echo "${BOLD}Command:${RST} ./$(basename "${0}") <options>"
|
||||
echo
|
||||
echo "${BOLD}Script description:${RST} Merges/cherry-picks Linux upstream into a kernel tree"
|
||||
echo
|
||||
echo "${BOLD}Required parameters:${RST}"
|
||||
echo " -c | --cherry-pick"
|
||||
echo " -m | --merge"
|
||||
echo " Call either git cherry-pick or git merge when updating from upstream"
|
||||
echo
|
||||
echo "${BOLD}Optional parameters:${RST}"
|
||||
echo " -f | --fetch-only"
|
||||
echo " Simply fetches the tags from linux-stable then exits"
|
||||
echo
|
||||
echo " -k | --kernel-folder"
|
||||
echo " The device's kernel source's location; this can either be a full path or relative to where the script is being executed."
|
||||
echo
|
||||
echo " -l | --latest"
|
||||
echo " Updates to the latest version available for the current kernel tree"
|
||||
echo
|
||||
echo " -p | --print-latest"
|
||||
echo " Prints the latest version available for the current kernel tree then exits"
|
||||
echo
|
||||
echo " -v | --version"
|
||||
echo " Updates to the specified version (e.g. -v 3.18.78)"
|
||||
echo
|
||||
echo "${BOLD}Defaults:${RST}"
|
||||
echo " If -l or -v are not specified, ONE version is picked at a time (e.g. 3.18.31 to 3.18.32)"
|
||||
echo
|
||||
echo " If -k is not specified, the script assumes it is in the kernel source folder already"
|
||||
echo
|
||||
exit 1 ;;
|
||||
|
||||
# Kernel source location
|
||||
"-k"|"--kernel-folder")
|
||||
shift
|
||||
[[ $# -lt 1 ]] && die "Please specify a kernel source location!"
|
||||
|
||||
KERNEL_FOLDER=${1} ;;
|
||||
|
||||
# Update to the latest version upstream unconditionally
|
||||
"-l"|"--latest")
|
||||
UPDATE_MODE=1 ;;
|
||||
|
||||
# Use git merge
|
||||
"-m"|"--merge")
|
||||
UPDATE_METHOD=merge ;;
|
||||
|
||||
# Print the latest version from kernel.org
|
||||
"-p"|"--print-latest")
|
||||
PRINT_LATEST=true ;;
|
||||
|
||||
# Update to the specified version
|
||||
"-v"|"--version")
|
||||
shift
|
||||
[[ $# -lt 1 ]] && die "Please specify a version to update!"
|
||||
|
||||
TARGET_VERSION=${1} ;;
|
||||
|
||||
*)
|
||||
die "Invalid parameter!" ;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
# If kernel source isn't specified, assume we're there
|
||||
[[ -z ${KERNEL_FOLDER} ]] && KERNEL_FOLDER=$(pwd)
|
||||
|
||||
# Sanity checks
|
||||
[[ ! ${UPDATE_METHOD} ]] && die "Neither cherry-pick nor merge were specified, please supply one!" -h
|
||||
[[ ! -d ${KERNEL_FOLDER} ]] && die "Invalid kernel source location specified! Folder does not exist" -h
|
||||
[[ ! -f ${KERNEL_FOLDER}/Makefile ]] && die "Invalid kernel source location specified! No Makefile present" -h
|
||||
|
||||
# Default update mode is one version at a time
|
||||
[[ -z ${UPDATE_MODE} && -z ${TARGET_VERSION} ]] && UPDATE_MODE=0
|
||||
}
|
||||
|
||||
|
||||
# Update the linux-stable remote (and add it if it doesn't exist)
|
||||
function update_remote() {
|
||||
header "Updating linux-stable"
|
||||
|
||||
# Add remote if it isn't already present
|
||||
cd "${KERNEL_FOLDER}" || die "Could not change into ${KERNEL_FOLDER}!"
|
||||
|
||||
if git fetch --tags https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/; then
|
||||
success "linux-stable updated successfully!"
|
||||
else
|
||||
die "linux-stable update failed!"
|
||||
fi
|
||||
|
||||
[[ ${FETCH_REMOTE_ONLY} ]] && exit 0
|
||||
}
|
||||
|
||||
|
||||
# Generate versions
|
||||
function generate_versions() {
|
||||
header "Calculating versions"
|
||||
|
||||
# Full kernel version
|
||||
CURRENT_VERSION=$(make -s CC=gcc CROSS_COMPILE="" kernelversion)
|
||||
# First two numbers (3.4 | 3.10 | 3.18 | 4.4)
|
||||
CURRENT_MAJOR_VERSION=$(echo "${CURRENT_VERSION}" | cut -f 1,2 -d .)
|
||||
# Last number
|
||||
CURRENT_SUBLEVEL=$(echo "${CURRENT_VERSION}" | cut -d . -f 3)
|
||||
|
||||
# Get latest update from upstream
|
||||
LATEST_VERSION=$(git tag --sort=-taggerdate -l "v${CURRENT_MAJOR_VERSION}"* | head -n 1 | sed s/v//)
|
||||
LATEST_SUBLEVEL=$(echo "${LATEST_VERSION}" | cut -d . -f 3)
|
||||
|
||||
# Print the current/latest version and exit if requested
|
||||
echo "${BOLD}Current kernel version:${RST} ${CURRENT_VERSION}"
|
||||
echo
|
||||
echo "${BOLD}Latest kernel version:${RST} ${LATEST_VERSION}"
|
||||
if [[ ${PRINT_LATEST} ]]; then
|
||||
echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# UPDATE_MODES:
|
||||
# 0. Update one version
|
||||
# 1. Update to the latest version
|
||||
case ${UPDATE_MODE} in
|
||||
0)
|
||||
TARGET_SUBLEVEL=$((CURRENT_SUBLEVEL + 1))
|
||||
TARGET_VERSION=${CURRENT_MAJOR_VERSION}.${TARGET_SUBLEVEL} ;;
|
||||
1)
|
||||
TARGET_VERSION=${LATEST_VERSION} ;;
|
||||
esac
|
||||
|
||||
# Make sure target version is between current version and latest version
|
||||
TARGET_SUBLEVEL=$(echo "${TARGET_VERSION}" | cut -d . -f 3)
|
||||
[[ ${TARGET_SUBLEVEL} -le ${CURRENT_SUBLEVEL} ]] && die "${TARGET_VERSION} is already present in ${CURRENT_VERSION}!"
|
||||
[[ ${TARGET_SUBLEVEL} -gt ${LATEST_SUBLEVEL} ]] && die "${CURRENT_VERSION} is the latest!"
|
||||
[[ ${CURRENT_SUBLEVEL} -eq 0 ]] && CURRENT_VERSION=${CURRENT_MAJOR_VERSION}
|
||||
|
||||
RANGE=v${CURRENT_VERSION}..v${TARGET_VERSION}
|
||||
|
||||
echo
|
||||
echo "${BOLD}Target kernel version:${RST} ${TARGET_VERSION}"
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
function update_to_target_version() {
|
||||
case ${UPDATE_METHOD} in
|
||||
"cherry-pick")
|
||||
if ! git cherry-pick "${RANGE}"; then
|
||||
die "Cherry-pick needs manual intervention! Resolve conflicts then run:
|
||||
|
||||
git add . && git cherry-pick --continue"
|
||||
else
|
||||
header "${TARGET_VERSION} PICKED CLEANLY!" "${GRN}"
|
||||
fi ;;
|
||||
|
||||
"merge")
|
||||
if ! GIT_MERGE_VERBOSITY=1 git merge --no-edit "v${TARGET_VERSION}"; then
|
||||
die "Merge needs manual intervention!
|
||||
|
||||
Resolve conflicts then run git commit!"
|
||||
else
|
||||
header "${TARGET_VERSION} MERGED CLEANLY!" "${GRN}"
|
||||
fi ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
parse_parameters "$@"
|
||||
update_remote
|
||||
generate_versions
|
||||
update_to_target_version
|
1
.local/bin/makeinstancesufo
Symbolic link
1
.local/bin/makeinstancesufo
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/makeinstancesufo
|
1
.local/bin/makeotf
Symbolic link
1
.local/bin/makeotf
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/makeotf
|
1
.local/bin/makeotfexe
Symbolic link
1
.local/bin/makeotfexe
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/makeotfexe
|
95
.local/bin/merge-aosp-tag.sh
Executable file
95
.local/bin/merge-aosp-tag.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# AOSP tag merge script for ArrowOS
|
||||
# Author: Adithya R (ghostrider-reborn)
|
||||
#
|
||||
# Usage (from source root):
|
||||
# ./manifest/merge-tag.sh <TAG>
|
||||
|
||||
# Colors
|
||||
red=$'\e[1;31m'
|
||||
grn=$'\e[1;32m'
|
||||
blu=$'\e[1;34m'
|
||||
end=$'\e[0m'
|
||||
|
||||
read -p "Tag to merge: " TAG
|
||||
read -p "Remote name: " REMOTE
|
||||
read -p "Remote branch: " BRANCH
|
||||
|
||||
BLACKLIST="packages/apps/DeskClock"
|
||||
|
||||
# verify tag
|
||||
if ! wget -q --spider https://android.googlesource.com/platform/manifest/+/refs/tags/$TAG; then
|
||||
echo "Invalid tag: $TAG!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# fetch all existing repos
|
||||
echo "${blu}Fetching list of repos to be merged...$end"
|
||||
REPOS=$(repo forall -v -c "if [ \"\$REPO_REMOTE\" = \"$REMOTE\" ]; then echo \$REPO_PATH; fi")
|
||||
echo $REPOS
|
||||
|
||||
# save root dir
|
||||
src_root=$(pwd)
|
||||
|
||||
# initialize some files
|
||||
for file in failed success unchanged; do
|
||||
rm -f $file
|
||||
touch $file
|
||||
done
|
||||
|
||||
# main
|
||||
for repo in $REPOS; do echo;
|
||||
if [[ $BLACKLIST =~ $repo ]]; then
|
||||
echo -e "$repo is in blacklist, skipped"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! grep -q -e "path=\"$repo\"" -e "name=\"$repo\"" manifest/default.xml; then
|
||||
echo "${red}$repo not found in AOSP manifest, skipping..."
|
||||
continue
|
||||
fi
|
||||
|
||||
# this is where the fun begins
|
||||
echo "${blu}Merging ${repo}..."
|
||||
name=$(grep "path=\"$repo\"" manifest/default.xml | sed -e 's/.*name="//' -e 's/".*//')
|
||||
if [[ -z $name ]]; then
|
||||
name=$(grep "name=\"$repo\"" manifest/default.xml | sed -e 's/.*name="//' -e 's/".*//')
|
||||
fi
|
||||
|
||||
git -C $repo checkout -q $BRANCH &> /dev/null || echo "${red}$repo checkout failed!"
|
||||
|
||||
if ! git -C $repo fetch -q https://android.googlesource.com/$name $TAG &> /dev/null; then
|
||||
echo "${red}$repo fetch failed!"
|
||||
else
|
||||
if ! git -C $repo merge FETCH_HEAD -q -m "Merge tag '$TAG' into $BRANCH" &> /dev/null; then
|
||||
echo "$repo" >> $src_root/failed
|
||||
echo "${red}$repo merge failed!"
|
||||
else
|
||||
if [[ $(git -C $repo rev-parse HEAD) != $(git -C $repo rev-parse $REMOTE/$BRANCH) ]] && [[ $(git -C $repo diff HEAD $REMOTE/$BRANCH) ]]; then
|
||||
echo "$repo" >> $src_root/success
|
||||
echo "${grn}$repo merged succesfully!"
|
||||
else
|
||||
echo "${end}$repo unchanged"
|
||||
echo "$repo" >> $src_root/unchanged
|
||||
git -C $repo reset --hard $REMOTE/$BRANCH &> /dev/null
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -s success ]; then
|
||||
#echo -e "${grn}\nPushing succeeded repos:$end"
|
||||
echo -e "${grn}\nMerge succeeded in:$end"
|
||||
for repo in $(cat success); do
|
||||
echo $repo
|
||||
#git -C $repo push -q &> /dev/null || echo "${red}$repo push failed!"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -s failed ]; then
|
||||
echo -e "$red \nThese repos failed merging:$end"
|
||||
cat failed
|
||||
fi
|
||||
|
||||
echo $end
|
1
.local/bin/mergefonts
Symbolic link
1
.local/bin/mergefonts
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/mergefonts
|
114
.local/bin/metroid
Executable file
114
.local/bin/metroid
Executable file
@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# metroid: a metroid ascii banner generator
|
||||
# MMXVI xero (http://xero.nu)
|
||||
|
||||
usage() {
|
||||
printf "usage: `basename $0` \n\
|
||||
[-m --mini mini] \n\
|
||||
[-s --super super] \n\
|
||||
[-t --text text] \n\
|
||||
[-n --normal normal] \n\
|
||||
[-h --help help]\n"
|
||||
}
|
||||
|
||||
text() {
|
||||
printf "\n .___.\n / @ \ \n \ @ @ /\n {'^'}\n\n"
|
||||
}
|
||||
|
||||
mini() {
|
||||
cat << METROID
|
||||
|
||||
[38;5;16m▄[m[38;5;16m▄[m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[38;5;16m▄[m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[38;5;16m▄[m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[38;5;16m▄[m
|
||||
[38;5;16m▄[m[48;5;16m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;16m [m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;77m [m[48;5;16m [m[38;5;16m▄[m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196m [m[48;5;196m [m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;196m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;16m [m
|
||||
[38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;196m [m[48;5;196m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196m [m[48;5;196m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[48;5;16m [m[48;5;223m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;223m [m[48;5;16m [m[38;5;16m▀[m[38;5;16m▀[m
|
||||
[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;223;38;5;196m▀[m[48;5;196m [m[48;5;16m [m[48;5;16m [m [48;5;16m [m[48;5;223m [m[48;5;223;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;16m [m [48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;223;38;5;196m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m
|
||||
[38;5;16m▀[m[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;223m [m[48;5;16m [m [48;5;16m [m[48;5;223m [m[48;5;16m [m[48;5;16m [m [38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m [48;5;16m [m[48;5;16m [m[48;5;223m [m[48;5;16m [m [48;5;16m [m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16m [m[38;5;16m▀[m
|
||||
[38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m [38;5;16m▀[m[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16m [m[38;5;16m▀[m [38;5;16m▀[m[38;5;16m▀[m[38;5;16m▀[m
|
||||
|
||||
METROID
|
||||
}
|
||||
|
||||
super() {
|
||||
cat << METROID
|
||||
|
||||
[38;5;28m▄[m[38;5;64m▄[m[38;5;106m▄[m[48;5;112;38;5;22m▀[m[48;5;113;38;5;22m▀[m[48;5;107;38;5;22m▀[m[48;5;107;38;5;22m▀[m[48;5;107;38;5;22m▀[m[48;5;107;38;5;22m▀[m[48;5;113;38;5;22m▀[m[48;5;112;38;5;22m▀[m[38;5;106m▄[m[38;5;64m▄[m[38;5;28m▄[m
|
||||
[38;5;22m▄[m[38;5;70m▄[m[48;5;150;38;5;28m▀[m[48;5;106;38;5;107m▀[m[48;5;28;38;5;113m▀[m[48;5;16;38;5;107m▀[m[48;5;22;38;5;70m▀[m[48;5;70;38;5;64m▀[m[48;5;113;38;5;28m▀[m[48;5;113;38;5;28m▀[m[48;5;149;38;5;28m▀[m[48;5;149;38;5;28m▀[m[48;5;113;38;5;28m▀[m[48;5;113;38;5;28m▀[m[48;5;70;38;5;64m▀[m[48;5;22;38;5;70m▀[m[48;5;16;38;5;107m▀[m[48;5;28;38;5;113m▀[m[48;5;106;38;5;107m▀[m[48;5;150;38;5;28m▀[m[38;5;70m▄[m[38;5;22m▄[m
|
||||
[38;5;22m▄[m[48;5;113;38;5;22m▀[m[48;5;148;38;5;113m▀[m[48;5;70;38;5;148m▀[m[48;5;22;38;5;70m▀[m[48;5;101;38;5;64m▀[m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;101;38;5;64m▀[m[48;5;22;38;5;70m▀[m[48;5;70;38;5;148m▀[m[48;5;148;38;5;113m▀[m[48;5;113;38;5;22m▀[m[38;5;22m▄[m
|
||||
[48;5;64;38;5;22m▀[m[48;5;150;38;5;107m▀[m[48;5;70;38;5;150m▀[m[48;5;28;38;5;70m▀[m[48;5;22m [m[48;5;16;38;5;22m▀[m[48;5;52;38;5;22m▀[m[48;5;52;38;5;16m▀[m[48;5;52;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;197;38;5;88m▀[m[48;5;197;38;5;88m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;52;38;5;16m▀[m[48;5;52;38;5;16m▀[m[48;5;52;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;22m [m[48;5;28;38;5;70m▀[m[48;5;70;38;5;150m▀[m[48;5;150;38;5;107m▀[m[48;5;64;38;5;22m▀[m
|
||||
[48;5;28;38;5;22m▀[m[48;5;148;38;5;113m▀[m[48;5;34;38;5;106m▀[m[48;5;22;38;5;28m▀[m[48;5;16;38;5;22m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;52m▀[m[48;5;88;38;5;160m▀[m[48;5;88;38;5;160m▀[m[48;5;88;38;5;52m▀[m[48;5;52;38;5;16m▀[m[48;5;16m [m[48;5;124;38;5;52m▀[m[48;5;124m [m[48;5;124m [m[48;5;124;38;5;52m▀[m[48;5;16m [m[48;5;52;38;5;16m▀[m[48;5;88;38;5;52m▀[m[48;5;88;38;5;160m▀[m[48;5;88;38;5;160m▀[m[48;5;16;38;5;52m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;22m▀[m[48;5;22;38;5;28m▀[m[48;5;34;38;5;106m▀[m[48;5;148;38;5;113m▀[m[48;5;28;38;5;22m▀[m
|
||||
[48;5;22m [m[48;5;113;38;5;107m▀[m[48;5;149m [m[48;5;107;38;5;28m▀[m[48;5;64;38;5;22m▀[m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;16m [m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;52m [m[48;5;52;38;5;88m▀[m[48;5;52;38;5;124m▀[m[48;5;124;38;5;168m▀[m[48;5;124;38;5;168m▀[m[48;5;52;38;5;124m▀[m[48;5;52;38;5;88m▀[m[48;5;52m [m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;16m [m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;64;38;5;22m▀[m[48;5;107;38;5;28m▀[m[48;5;149m [m[48;5;113;38;5;107m▀[m[48;5;22m [m
|
||||
[48;5;70;38;5;28m▀[m[48;5;149;38;5;148m▀[m[48;5;34;38;5;70m▀[m[48;5;28;38;5;71m▀[m[48;5;64;38;5;22m▀[m[48;5;16;38;5;22m▀[m[48;5;16m [m[48;5;16m [m[48;5;88;38;5;16m▀[m[48;5;160;38;5;16m▀[m[48;5;88;38;5;16m▀[m[48;5;52;38;5;16m▀[m[48;5;52m [m[48;5;52;38;5;124m▀[m[48;5;52;38;5;88m▀[m[48;5;124;38;5;88m▀[m[48;5;124;38;5;88m▀[m[48;5;52;38;5;88m▀[m[48;5;52;38;5;124m▀[m[48;5;52m [m[48;5;52;38;5;16m▀[m[48;5;88;38;5;16m▀[m[48;5;160;38;5;16m▀[m[48;5;88;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;22m▀[m[48;5;64;38;5;22m▀[m[48;5;28;38;5;71m▀[m[48;5;34;38;5;70m▀[m[48;5;149;38;5;148m▀[m[48;5;70;38;5;28m▀[m
|
||||
[48;5;22;38;5;70m▀[m[48;5;149m [m[48;5;28m [m[48;5;22;38;5;16m▀[m[48;5;16;38;5;22m▀[m[48;5;22;38;5;64m▀[m[48;5;124;38;5;16m▀[m[48;5;88;38;5;52m▀[m[48;5;124;38;5;160m▀[m[48;5;88;38;5;197m▀[m[48;5;52;38;5;124m▀[m[48;5;160;38;5;88m▀[m[48;5;124;38;5;160m▀[m[48;5;52m [m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;52m [m[48;5;124;38;5;160m▀[m[48;5;160;38;5;88m▀[m[48;5;52;38;5;124m▀[m[48;5;88;38;5;197m▀[m[48;5;124;38;5;160m▀[m[48;5;88;38;5;52m▀[m[48;5;124;38;5;16m▀[m[48;5;22;38;5;64m▀[m[48;5;16;38;5;22m▀[m[48;5;22;38;5;16m▀[m[48;5;28m [m[48;5;149m [m[48;5;22;38;5;70m▀[m
|
||||
[48;5;16;38;5;22m▀[m[48;5;113;38;5;149m▀[m[48;5;112;38;5;70m▀[m[48;5;22m [m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;16;38;5;88m▀[m[48;5;22;38;5;52m▀[m[48;5;28;38;5;88m▀[m[48;5;28;38;5;16m▀[m[48;5;28;38;5;52m▀[m[48;5;22;38;5;124m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;52;38;5;16m▀[m[48;5;124m [m[48;5;124m [m[48;5;52;38;5;16m▀[m[48;5;16;38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;22;38;5;124m▀[m[48;5;28;38;5;52m▀[m[48;5;28;38;5;16m▀[m[48;5;28;38;5;88m▀[m[48;5;22;38;5;52m▀[m[48;5;16;38;5;88m▀[m[48;5;22;38;5;16m▀[m[48;5;22;38;5;16m▀[m[48;5;22m [m[48;5;112;38;5;70m▀[m[48;5;113;38;5;149m▀[m[48;5;16;38;5;22m▀[m
|
||||
[48;5;28;38;5;70m▀[m[48;5;150;38;5;149m▀[m[48;5;112;38;5;34m▀[m[48;5;70;38;5;28m▀[m[48;5;149;38;5;28m▀[m[48;5;112;38;5;107m▀[m[48;5;64;38;5;149m▀[m[48;5;28;38;5;150m▀[m[48;5;64;38;5;149m▀[m[48;5;28;38;5;150m▀[m[48;5;106;38;5;112m▀[m[48;5;112;38;5;28m▀[m[48;5;70;38;5;22m▀[m[48;5;22;38;5;88m▀[m[48;5;22;38;5;52m▀[m[48;5;22;38;5;52m▀[m[48;5;22;38;5;88m▀[m[48;5;70;38;5;22m▀[m[48;5;112;38;5;28m▀[m[48;5;106;38;5;112m▀[m[48;5;28;38;5;150m▀[m[48;5;64;38;5;149m▀[m[48;5;28;38;5;150m▀[m[48;5;64;38;5;149m▀[m[48;5;112;38;5;107m▀[m[48;5;149;38;5;28m▀[m[48;5;70;38;5;28m▀[m[48;5;112;38;5;34m▀[m[48;5;150;38;5;149m▀[m[48;5;28;38;5;70m▀[m
|
||||
[48;5;22;38;5;70m▀[m[48;5;70;38;5;150m▀[m[48;5;22;38;5;149m▀[m[48;5;16;38;5;70m▀[m[48;5;52;38;5;22m▀[m[48;5;94;38;5;101m▀[m[48;5;94;38;5;101m▀[m[48;5;143;38;5;94m▀[m[48;5;137;38;5;94m▀[m[48;5;52;38;5;22m▀[m[48;5;22;38;5;70m▀[m[48;5;70;38;5;148m▀[m[48;5;112;38;5;70m▀[m[48;5;106;38;5;28m▀[m[48;5;106;38;5;28m▀[m[48;5;112;38;5;70m▀[m[48;5;70;38;5;148m▀[m[48;5;22;38;5;70m▀[m[48;5;52;38;5;22m▀[m[48;5;137;38;5;94m▀[m[48;5;143;38;5;94m▀[m[48;5;94;38;5;101m▀[m[48;5;94;38;5;101m▀[m[48;5;52;38;5;22m▀[m[48;5;16;38;5;70m▀[m[48;5;22;38;5;149m▀[m[48;5;70;38;5;150m▀[m[48;5;22;38;5;70m▀[m
|
||||
[48;5;16m [m[48;5;94;38;5;16m▀[m[48;5;187;38;5;94m▀[m[48;5;223;38;5;137m▀[m[48;5;94;38;5;52m▀[m[48;5;52m [m[48;5;16;38;5;52m▀[m[48;5;52;38;5;94m▀[m[48;5;180;38;5;94m▀[m[48;5;187;38;5;101m▀[m[48;5;52m [m[48;5;16;38;5;22m▀[m[38;5;113m▀[m[38;5;113m▀[m[48;5;16;38;5;22m▀[m[48;5;52m [m[48;5;187;38;5;101m▀[m[48;5;180;38;5;94m▀[m[48;5;52;38;5;94m▀[m[48;5;16;38;5;52m▀[m[48;5;52m [m[48;5;94;38;5;52m▀[m[48;5;223;38;5;137m▀[m[48;5;187;38;5;94m▀[m[48;5;94;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;94;38;5;52m▀[m[48;5;186;38;5;144m▀[m[48;5;223;38;5;230m▀[m[48;5;101;38;5;180m▀[m[48;5;16;38;5;52m▀[m[38;5;52m▀[m [48;5;94m [m[48;5;180;38;5;186m▀[m[48;5;52;38;5;101m▀[m[38;5;52m▀[m [38;5;52m▀[m[48;5;52;38;5;101m▀[m[48;5;180;38;5;186m▀[m[48;5;94m [m [38;5;52m▀[m[48;5;16;38;5;52m▀[m[48;5;101;38;5;180m▀[m[48;5;223;38;5;230m▀[m[48;5;186;38;5;144m▀[m[48;5;94;38;5;52m▀[m
|
||||
[48;5;58;38;5;94m▀[m[48;5;180;38;5;186m▀[m[48;5;180;38;5;222m▀[m[48;5;52m [m [38;5;52m▀[m[48;5;52;38;5;101m▀[m[48;5;52m [m [48;5;52m [m[48;5;52;38;5;101m▀[m[38;5;52m▀[m [48;5;52m [m[48;5;180;38;5;222m▀[m[48;5;180;38;5;186m▀[m[48;5;58;38;5;94m▀[m
|
||||
[38;5;52m▀[m[48;5;94;38;5;143m▀[m[48;5;143;38;5;180m▀[m[48;5;58;38;5;52m▀[m [48;5;58;38;5;52m▀[m[48;5;143;38;5;180m▀[m[48;5;94;38;5;143m▀[m[38;5;52m▀[m
|
||||
[38;5;94m▀[m[48;5;52m [m[48;5;52;38;5;16m▀[m [48;5;52;38;5;16m▀[m[48;5;52m [m[38;5;94m▀[m
|
||||
|
||||
METROID
|
||||
}
|
||||
|
||||
normal() {
|
||||
cat << METROID
|
||||
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;223m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;223m [m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;223m [m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;196;38;5;223m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m[48;5;16m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;77m [m[48;5;77m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;196;38;5;16m▀[m[48;5;196;38;5;16m▀[m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77;38;5;16m▀[m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;196m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;223m [m[48;5;223m [m[48;5;196m [m[48;5;196m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;16m [m[38;5;16m▀[m[38;5;16m▀[m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m[38;5;16m▀[m[38;5;16m▀[m[48;5;16m [m[48;5;16;38;5;196m▀[m[48;5;16;38;5;196m▀[m[48;5;196m [m[48;5;196m [m[48;5;223m [m[48;5;223m [m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;16m [m[48;5;16m [m[48;5;16m [m [48;5;16m [m[48;5;223m [m[48;5;223m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m[48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;77m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;223m [m[48;5;223m [m[48;5;16m [m [48;5;16m [m[48;5;16m [m[48;5;16m [m[48;5;223;38;5;196m▀[m[48;5;223;38;5;196m▀[m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m [48;5;16m [m[48;5;223m [m[48;5;223m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16;38;5;77m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;223m [m[48;5;223m [m[48;5;16m [m [48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16m [m [48;5;16m [m[48;5;223;38;5;16m▀[m[48;5;223;38;5;16m▀[m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m
|
||||
[48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m [48;5;16m [m[48;5;16;38;5;223m▀[m[48;5;16;38;5;223m▀[m[48;5;16m [m
|
||||
|
||||
METROID
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
*-m|--mini|mini*)
|
||||
mini
|
||||
;;
|
||||
*-s|--super|super*)
|
||||
super
|
||||
;;
|
||||
*-n|--normal|normal)
|
||||
normal
|
||||
;;
|
||||
*-t|--text|text)
|
||||
text
|
||||
;;
|
||||
*)
|
||||
text
|
||||
usage
|
||||
;;
|
||||
esac
|
976
.local/bin/miniterm.py
Normal file
976
.local/bin/miniterm.py
Normal file
@ -0,0 +1,976 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Very simple serial terminal
|
||||
#
|
||||
# This file is part of pySerial. https://github.com/pyserial/pyserial
|
||||
# (C)2002-2015 Chris Liechti <cliechti@gmx.net>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import codecs
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
|
||||
import serial
|
||||
from serial.tools.list_ports import comports
|
||||
from serial.tools import hexlify_codec
|
||||
|
||||
# pylint: disable=wrong-import-order,wrong-import-position
|
||||
|
||||
codecs.register(lambda c: hexlify_codec.getregentry() if c == 'hexlify' else None)
|
||||
|
||||
try:
|
||||
raw_input
|
||||
except NameError:
|
||||
# pylint: disable=redefined-builtin,invalid-name
|
||||
raw_input = input # in python3 it's "raw"
|
||||
unichr = chr
|
||||
|
||||
|
||||
def key_description(character):
|
||||
"""generate a readable description for a key"""
|
||||
ascii_code = ord(character)
|
||||
if ascii_code < 32:
|
||||
return 'Ctrl+{:c}'.format(ord('@') + ascii_code)
|
||||
else:
|
||||
return repr(character)
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
class ConsoleBase(object):
|
||||
"""OS abstraction for console (input/output codec, no echo)"""
|
||||
|
||||
def __init__(self):
|
||||
if sys.version_info >= (3, 0):
|
||||
self.byte_output = sys.stdout.buffer
|
||||
else:
|
||||
self.byte_output = sys.stdout
|
||||
self.output = sys.stdout
|
||||
|
||||
def setup(self):
|
||||
"""Set console to read single characters, no echo"""
|
||||
|
||||
def cleanup(self):
|
||||
"""Restore default console settings"""
|
||||
|
||||
def getkey(self):
|
||||
"""Read a single key from the console"""
|
||||
return None
|
||||
|
||||
def write_bytes(self, byte_string):
|
||||
"""Write bytes (already encoded)"""
|
||||
self.byte_output.write(byte_string)
|
||||
self.byte_output.flush()
|
||||
|
||||
def write(self, text):
|
||||
"""Write string"""
|
||||
self.output.write(text)
|
||||
self.output.flush()
|
||||
|
||||
def cancel(self):
|
||||
"""Cancel getkey operation"""
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
# context manager:
|
||||
# switch terminal temporary to normal mode (e.g. to get user input)
|
||||
|
||||
def __enter__(self):
|
||||
self.cleanup()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
self.setup()
|
||||
|
||||
|
||||
if os.name == 'nt': # noqa
|
||||
import msvcrt
|
||||
import ctypes
|
||||
|
||||
class Out(object):
|
||||
"""file-like wrapper that uses os.write"""
|
||||
|
||||
def __init__(self, fd):
|
||||
self.fd = fd
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def write(self, s):
|
||||
os.write(self.fd, s)
|
||||
|
||||
class Console(ConsoleBase):
|
||||
def __init__(self):
|
||||
super(Console, self).__init__()
|
||||
self._saved_ocp = ctypes.windll.kernel32.GetConsoleOutputCP()
|
||||
self._saved_icp = ctypes.windll.kernel32.GetConsoleCP()
|
||||
ctypes.windll.kernel32.SetConsoleOutputCP(65001)
|
||||
ctypes.windll.kernel32.SetConsoleCP(65001)
|
||||
self.output = codecs.getwriter('UTF-8')(Out(sys.stdout.fileno()), 'replace')
|
||||
# the change of the code page is not propagated to Python, manually fix it
|
||||
sys.stderr = codecs.getwriter('UTF-8')(Out(sys.stderr.fileno()), 'replace')
|
||||
sys.stdout = self.output
|
||||
self.output.encoding = 'UTF-8' # needed for input
|
||||
|
||||
def __del__(self):
|
||||
ctypes.windll.kernel32.SetConsoleOutputCP(self._saved_ocp)
|
||||
ctypes.windll.kernel32.SetConsoleCP(self._saved_icp)
|
||||
|
||||
def getkey(self):
|
||||
while True:
|
||||
z = msvcrt.getwch()
|
||||
if z == unichr(13):
|
||||
return unichr(10)
|
||||
elif z in (unichr(0), unichr(0x0e)): # functions keys, ignore
|
||||
msvcrt.getwch()
|
||||
else:
|
||||
return z
|
||||
|
||||
def cancel(self):
|
||||
# CancelIo, CancelSynchronousIo do not seem to work when using
|
||||
# getwch, so instead, send a key to the window with the console
|
||||
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
|
||||
ctypes.windll.user32.PostMessageA(hwnd, 0x100, 0x0d, 0)
|
||||
|
||||
elif os.name == 'posix':
|
||||
import atexit
|
||||
import termios
|
||||
import fcntl
|
||||
|
||||
class Console(ConsoleBase):
|
||||
def __init__(self):
|
||||
super(Console, self).__init__()
|
||||
self.fd = sys.stdin.fileno()
|
||||
self.old = termios.tcgetattr(self.fd)
|
||||
atexit.register(self.cleanup)
|
||||
if sys.version_info < (3, 0):
|
||||
self.enc_stdin = codecs.getreader(sys.stdin.encoding)(sys.stdin)
|
||||
else:
|
||||
self.enc_stdin = sys.stdin
|
||||
|
||||
def setup(self):
|
||||
new = termios.tcgetattr(self.fd)
|
||||
new[3] = new[3] & ~termios.ICANON & ~termios.ECHO & ~termios.ISIG
|
||||
new[6][termios.VMIN] = 1
|
||||
new[6][termios.VTIME] = 0
|
||||
termios.tcsetattr(self.fd, termios.TCSANOW, new)
|
||||
|
||||
def getkey(self):
|
||||
c = self.enc_stdin.read(1)
|
||||
if c == unichr(0x7f):
|
||||
c = unichr(8) # map the BS key (which yields DEL) to backspace
|
||||
return c
|
||||
|
||||
def cancel(self):
|
||||
fcntl.ioctl(self.fd, termios.TIOCSTI, b'\0')
|
||||
|
||||
def cleanup(self):
|
||||
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old)
|
||||
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
'Sorry no implementation for your platform ({}) available.'.format(sys.platform))
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
class Transform(object):
|
||||
"""do-nothing: forward all data unchanged"""
|
||||
def rx(self, text):
|
||||
"""text received from serial port"""
|
||||
return text
|
||||
|
||||
def tx(self, text):
|
||||
"""text to be sent to serial port"""
|
||||
return text
|
||||
|
||||
def echo(self, text):
|
||||
"""text to be sent but displayed on console"""
|
||||
return text
|
||||
|
||||
|
||||
class CRLF(Transform):
|
||||
"""ENTER sends CR+LF"""
|
||||
|
||||
def tx(self, text):
|
||||
return text.replace('\n', '\r\n')
|
||||
|
||||
|
||||
class CR(Transform):
|
||||
"""ENTER sends CR"""
|
||||
|
||||
def rx(self, text):
|
||||
return text.replace('\r', '\n')
|
||||
|
||||
def tx(self, text):
|
||||
return text.replace('\n', '\r')
|
||||
|
||||
|
||||
class LF(Transform):
|
||||
"""ENTER sends LF"""
|
||||
|
||||
|
||||
class NoTerminal(Transform):
|
||||
"""remove typical terminal control codes from input"""
|
||||
|
||||
REPLACEMENT_MAP = dict((x, 0x2400 + x) for x in range(32) if unichr(x) not in '\r\n\b\t')
|
||||
REPLACEMENT_MAP.update(
|
||||
{
|
||||
0x7F: 0x2421, # DEL
|
||||
0x9B: 0x2425, # CSI
|
||||
})
|
||||
|
||||
def rx(self, text):
|
||||
return text.translate(self.REPLACEMENT_MAP)
|
||||
|
||||
echo = rx
|
||||
|
||||
|
||||
class NoControls(NoTerminal):
|
||||
"""Remove all control codes, incl. CR+LF"""
|
||||
|
||||
REPLACEMENT_MAP = dict((x, 0x2400 + x) for x in range(32))
|
||||
REPLACEMENT_MAP.update(
|
||||
{
|
||||
0x20: 0x2423, # visual space
|
||||
0x7F: 0x2421, # DEL
|
||||
0x9B: 0x2425, # CSI
|
||||
})
|
||||
|
||||
|
||||
class Printable(Transform):
|
||||
"""Show decimal code for all non-ASCII characters and replace most control codes"""
|
||||
|
||||
def rx(self, text):
|
||||
r = []
|
||||
for c in text:
|
||||
if ' ' <= c < '\x7f' or c in '\r\n\b\t':
|
||||
r.append(c)
|
||||
elif c < ' ':
|
||||
r.append(unichr(0x2400 + ord(c)))
|
||||
else:
|
||||
r.extend(unichr(0x2080 + ord(d) - 48) for d in '{:d}'.format(ord(c)))
|
||||
r.append(' ')
|
||||
return ''.join(r)
|
||||
|
||||
echo = rx
|
||||
|
||||
|
||||
class Colorize(Transform):
|
||||
"""Apply different colors for received and echo"""
|
||||
|
||||
def __init__(self):
|
||||
# XXX make it configurable, use colorama?
|
||||
self.input_color = '\x1b[37m'
|
||||
self.echo_color = '\x1b[31m'
|
||||
|
||||
def rx(self, text):
|
||||
return self.input_color + text
|
||||
|
||||
def echo(self, text):
|
||||
return self.echo_color + text
|
||||
|
||||
|
||||
class DebugIO(Transform):
|
||||
"""Print what is sent and received"""
|
||||
|
||||
def rx(self, text):
|
||||
sys.stderr.write(' [RX:{}] '.format(repr(text)))
|
||||
sys.stderr.flush()
|
||||
return text
|
||||
|
||||
def tx(self, text):
|
||||
sys.stderr.write(' [TX:{}] '.format(repr(text)))
|
||||
sys.stderr.flush()
|
||||
return text
|
||||
|
||||
|
||||
# other ideas:
|
||||
# - add date/time for each newline
|
||||
# - insert newline after: a) timeout b) packet end character
|
||||
|
||||
EOL_TRANSFORMATIONS = {
|
||||
'crlf': CRLF,
|
||||
'cr': CR,
|
||||
'lf': LF,
|
||||
}
|
||||
|
||||
TRANSFORMATIONS = {
|
||||
'direct': Transform, # no transformation
|
||||
'default': NoTerminal,
|
||||
'nocontrol': NoControls,
|
||||
'printable': Printable,
|
||||
'colorize': Colorize,
|
||||
'debug': DebugIO,
|
||||
}
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
def ask_for_port():
|
||||
"""\
|
||||
Show a list of ports and ask the user for a choice. To make selection
|
||||
easier on systems with long device names, also allow the input of an
|
||||
index.
|
||||
"""
|
||||
sys.stderr.write('\n--- Available ports:\n')
|
||||
ports = []
|
||||
for n, (port, desc, hwid) in enumerate(sorted(comports()), 1):
|
||||
sys.stderr.write('--- {:2}: {:20} {!r}\n'.format(n, port, desc))
|
||||
ports.append(port)
|
||||
while True:
|
||||
port = raw_input('--- Enter port index or full name: ')
|
||||
try:
|
||||
index = int(port) - 1
|
||||
if not 0 <= index < len(ports):
|
||||
sys.stderr.write('--- Invalid index!\n')
|
||||
continue
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
port = ports[index]
|
||||
return port
|
||||
|
||||
|
||||
class Miniterm(object):
|
||||
"""\
|
||||
Terminal application. Copy data from serial port to console and vice versa.
|
||||
Handle special keys from the console to show menu etc.
|
||||
"""
|
||||
|
||||
def __init__(self, serial_instance, echo=False, eol='crlf', filters=()):
|
||||
self.console = Console()
|
||||
self.serial = serial_instance
|
||||
self.echo = echo
|
||||
self.raw = False
|
||||
self.input_encoding = 'UTF-8'
|
||||
self.output_encoding = 'UTF-8'
|
||||
self.eol = eol
|
||||
self.filters = filters
|
||||
self.update_transformations()
|
||||
self.exit_character = 0x1d # GS/CTRL+]
|
||||
self.menu_character = 0x14 # Menu: CTRL+T
|
||||
self.alive = None
|
||||
self._reader_alive = None
|
||||
self.receiver_thread = None
|
||||
self.rx_decoder = None
|
||||
self.tx_decoder = None
|
||||
|
||||
def _start_reader(self):
|
||||
"""Start reader thread"""
|
||||
self._reader_alive = True
|
||||
# start serial->console thread
|
||||
self.receiver_thread = threading.Thread(target=self.reader, name='rx')
|
||||
self.receiver_thread.daemon = True
|
||||
self.receiver_thread.start()
|
||||
|
||||
def _stop_reader(self):
|
||||
"""Stop reader thread only, wait for clean exit of thread"""
|
||||
self._reader_alive = False
|
||||
if hasattr(self.serial, 'cancel_read'):
|
||||
self.serial.cancel_read()
|
||||
self.receiver_thread.join()
|
||||
|
||||
def start(self):
|
||||
"""start worker threads"""
|
||||
self.alive = True
|
||||
self._start_reader()
|
||||
# enter console->serial loop
|
||||
self.transmitter_thread = threading.Thread(target=self.writer, name='tx')
|
||||
self.transmitter_thread.daemon = True
|
||||
self.transmitter_thread.start()
|
||||
self.console.setup()
|
||||
|
||||
def stop(self):
|
||||
"""set flag to stop worker threads"""
|
||||
self.alive = False
|
||||
|
||||
def join(self, transmit_only=False):
|
||||
"""wait for worker threads to terminate"""
|
||||
self.transmitter_thread.join()
|
||||
if not transmit_only:
|
||||
if hasattr(self.serial, 'cancel_read'):
|
||||
self.serial.cancel_read()
|
||||
self.receiver_thread.join()
|
||||
|
||||
def close(self):
|
||||
self.serial.close()
|
||||
|
||||
def update_transformations(self):
|
||||
"""take list of transformation classes and instantiate them for rx and tx"""
|
||||
transformations = [EOL_TRANSFORMATIONS[self.eol]] + [TRANSFORMATIONS[f]
|
||||
for f in self.filters]
|
||||
self.tx_transformations = [t() for t in transformations]
|
||||
self.rx_transformations = list(reversed(self.tx_transformations))
|
||||
|
||||
def set_rx_encoding(self, encoding, errors='replace'):
|
||||
"""set encoding for received data"""
|
||||
self.input_encoding = encoding
|
||||
self.rx_decoder = codecs.getincrementaldecoder(encoding)(errors)
|
||||
|
||||
def set_tx_encoding(self, encoding, errors='replace'):
|
||||
"""set encoding for transmitted data"""
|
||||
self.output_encoding = encoding
|
||||
self.tx_encoder = codecs.getincrementalencoder(encoding)(errors)
|
||||
|
||||
def dump_port_settings(self):
|
||||
"""Write current settings to sys.stderr"""
|
||||
sys.stderr.write("\n--- Settings: {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits}\n".format(
|
||||
p=self.serial))
|
||||
sys.stderr.write('--- RTS: {:8} DTR: {:8} BREAK: {:8}\n'.format(
|
||||
('active' if self.serial.rts else 'inactive'),
|
||||
('active' if self.serial.dtr else 'inactive'),
|
||||
('active' if self.serial.break_condition else 'inactive')))
|
||||
try:
|
||||
sys.stderr.write('--- CTS: {:8} DSR: {:8} RI: {:8} CD: {:8}\n'.format(
|
||||
('active' if self.serial.cts else 'inactive'),
|
||||
('active' if self.serial.dsr else 'inactive'),
|
||||
('active' if self.serial.ri else 'inactive'),
|
||||
('active' if self.serial.cd else 'inactive')))
|
||||
except serial.SerialException:
|
||||
# on RFC 2217 ports, it can happen if no modem state notification was
|
||||
# yet received. ignore this error.
|
||||
pass
|
||||
sys.stderr.write('--- software flow control: {}\n'.format('active' if self.serial.xonxoff else 'inactive'))
|
||||
sys.stderr.write('--- hardware flow control: {}\n'.format('active' if self.serial.rtscts else 'inactive'))
|
||||
sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
|
||||
sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
|
||||
sys.stderr.write('--- EOL: {}\n'.format(self.eol.upper()))
|
||||
sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
|
||||
|
||||
def reader(self):
|
||||
"""loop and copy serial->console"""
|
||||
try:
|
||||
while self.alive and self._reader_alive:
|
||||
# read all that is there or wait for one byte
|
||||
data = self.serial.read(self.serial.in_waiting or 1)
|
||||
if data:
|
||||
if self.raw:
|
||||
self.console.write_bytes(data)
|
||||
else:
|
||||
text = self.rx_decoder.decode(data)
|
||||
for transformation in self.rx_transformations:
|
||||
text = transformation.rx(text)
|
||||
self.console.write(text)
|
||||
except serial.SerialException:
|
||||
self.alive = False
|
||||
self.console.cancel()
|
||||
raise # XXX handle instead of re-raise?
|
||||
|
||||
def writer(self):
|
||||
"""\
|
||||
Loop and copy console->serial until self.exit_character character is
|
||||
found. When self.menu_character is found, interpret the next key
|
||||
locally.
|
||||
"""
|
||||
menu_active = False
|
||||
try:
|
||||
while self.alive:
|
||||
try:
|
||||
c = self.console.getkey()
|
||||
except KeyboardInterrupt:
|
||||
c = '\x03'
|
||||
if not self.alive:
|
||||
break
|
||||
if menu_active:
|
||||
self.handle_menu_key(c)
|
||||
menu_active = False
|
||||
elif c == self.menu_character:
|
||||
menu_active = True # next char will be for menu
|
||||
elif c == self.exit_character:
|
||||
self.stop() # exit app
|
||||
break
|
||||
else:
|
||||
#~ if self.raw:
|
||||
text = c
|
||||
for transformation in self.tx_transformations:
|
||||
text = transformation.tx(text)
|
||||
self.serial.write(self.tx_encoder.encode(text))
|
||||
if self.echo:
|
||||
echo_text = c
|
||||
for transformation in self.tx_transformations:
|
||||
echo_text = transformation.echo(echo_text)
|
||||
self.console.write(echo_text)
|
||||
except:
|
||||
self.alive = False
|
||||
raise
|
||||
|
||||
def handle_menu_key(self, c):
|
||||
"""Implement a simple menu / settings"""
|
||||
if c == self.menu_character or c == self.exit_character:
|
||||
# Menu/exit character again -> send itself
|
||||
self.serial.write(self.tx_encoder.encode(c))
|
||||
if self.echo:
|
||||
self.console.write(c)
|
||||
elif c == '\x15': # CTRL+U -> upload file
|
||||
self.upload_file()
|
||||
elif c in '\x08hH?': # CTRL+H, h, H, ? -> Show help
|
||||
sys.stderr.write(self.get_help_text())
|
||||
elif c == '\x12': # CTRL+R -> Toggle RTS
|
||||
self.serial.rts = not self.serial.rts
|
||||
sys.stderr.write('--- RTS {} ---\n'.format('active' if self.serial.rts else 'inactive'))
|
||||
elif c == '\x04': # CTRL+D -> Toggle DTR
|
||||
self.serial.dtr = not self.serial.dtr
|
||||
sys.stderr.write('--- DTR {} ---\n'.format('active' if self.serial.dtr else 'inactive'))
|
||||
elif c == '\x02': # CTRL+B -> toggle BREAK condition
|
||||
self.serial.break_condition = not self.serial.break_condition
|
||||
sys.stderr.write('--- BREAK {} ---\n'.format('active' if self.serial.break_condition else 'inactive'))
|
||||
elif c == '\x05': # CTRL+E -> toggle local echo
|
||||
self.echo = not self.echo
|
||||
sys.stderr.write('--- local echo {} ---\n'.format('active' if self.echo else 'inactive'))
|
||||
elif c == '\x06': # CTRL+F -> edit filters
|
||||
self.change_filter()
|
||||
elif c == '\x0c': # CTRL+L -> EOL mode
|
||||
modes = list(EOL_TRANSFORMATIONS) # keys
|
||||
eol = modes.index(self.eol) + 1
|
||||
if eol >= len(modes):
|
||||
eol = 0
|
||||
self.eol = modes[eol]
|
||||
sys.stderr.write('--- EOL: {} ---\n'.format(self.eol.upper()))
|
||||
self.update_transformations()
|
||||
elif c == '\x01': # CTRL+A -> set encoding
|
||||
self.change_encoding()
|
||||
elif c == '\x09': # CTRL+I -> info
|
||||
self.dump_port_settings()
|
||||
#~ elif c == '\x01': # CTRL+A -> cycle escape mode
|
||||
#~ elif c == '\x0c': # CTRL+L -> cycle linefeed mode
|
||||
elif c in 'pP': # P -> change port
|
||||
self.change_port()
|
||||
elif c in 'sS': # S -> suspend / open port temporarily
|
||||
self.suspend_port()
|
||||
elif c in 'bB': # B -> change baudrate
|
||||
self.change_baudrate()
|
||||
elif c == '8': # 8 -> change to 8 bits
|
||||
self.serial.bytesize = serial.EIGHTBITS
|
||||
self.dump_port_settings()
|
||||
elif c == '7': # 7 -> change to 8 bits
|
||||
self.serial.bytesize = serial.SEVENBITS
|
||||
self.dump_port_settings()
|
||||
elif c in 'eE': # E -> change to even parity
|
||||
self.serial.parity = serial.PARITY_EVEN
|
||||
self.dump_port_settings()
|
||||
elif c in 'oO': # O -> change to odd parity
|
||||
self.serial.parity = serial.PARITY_ODD
|
||||
self.dump_port_settings()
|
||||
elif c in 'mM': # M -> change to mark parity
|
||||
self.serial.parity = serial.PARITY_MARK
|
||||
self.dump_port_settings()
|
||||
elif c in 'sS': # S -> change to space parity
|
||||
self.serial.parity = serial.PARITY_SPACE
|
||||
self.dump_port_settings()
|
||||
elif c in 'nN': # N -> change to no parity
|
||||
self.serial.parity = serial.PARITY_NONE
|
||||
self.dump_port_settings()
|
||||
elif c == '1': # 1 -> change to 1 stop bits
|
||||
self.serial.stopbits = serial.STOPBITS_ONE
|
||||
self.dump_port_settings()
|
||||
elif c == '2': # 2 -> change to 2 stop bits
|
||||
self.serial.stopbits = serial.STOPBITS_TWO
|
||||
self.dump_port_settings()
|
||||
elif c == '3': # 3 -> change to 1.5 stop bits
|
||||
self.serial.stopbits = serial.STOPBITS_ONE_POINT_FIVE
|
||||
self.dump_port_settings()
|
||||
elif c in 'xX': # X -> change software flow control
|
||||
self.serial.xonxoff = (c == 'X')
|
||||
self.dump_port_settings()
|
||||
elif c in 'rR': # R -> change hardware flow control
|
||||
self.serial.rtscts = (c == 'R')
|
||||
self.dump_port_settings()
|
||||
else:
|
||||
sys.stderr.write('--- unknown menu character {} --\n'.format(key_description(c)))
|
||||
|
||||
def upload_file(self):
|
||||
"""Ask user for filenname and send its contents"""
|
||||
sys.stderr.write('\n--- File to upload: ')
|
||||
sys.stderr.flush()
|
||||
with self.console:
|
||||
filename = sys.stdin.readline().rstrip('\r\n')
|
||||
if filename:
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
sys.stderr.write('--- Sending file {} ---\n'.format(filename))
|
||||
while True:
|
||||
block = f.read(1024)
|
||||
if not block:
|
||||
break
|
||||
self.serial.write(block)
|
||||
# Wait for output buffer to drain.
|
||||
self.serial.flush()
|
||||
sys.stderr.write('.') # Progress indicator.
|
||||
sys.stderr.write('\n--- File {} sent ---\n'.format(filename))
|
||||
except IOError as e:
|
||||
sys.stderr.write('--- ERROR opening file {}: {} ---\n'.format(filename, e))
|
||||
|
||||
def change_filter(self):
|
||||
"""change the i/o transformations"""
|
||||
sys.stderr.write('\n--- Available Filters:\n')
|
||||
sys.stderr.write('\n'.join(
|
||||
'--- {:<10} = {.__doc__}'.format(k, v)
|
||||
for k, v in sorted(TRANSFORMATIONS.items())))
|
||||
sys.stderr.write('\n--- Enter new filter name(s) [{}]: '.format(' '.join(self.filters)))
|
||||
with self.console:
|
||||
new_filters = sys.stdin.readline().lower().split()
|
||||
if new_filters:
|
||||
for f in new_filters:
|
||||
if f not in TRANSFORMATIONS:
|
||||
sys.stderr.write('--- unknown filter: {}\n'.format(repr(f)))
|
||||
break
|
||||
else:
|
||||
self.filters = new_filters
|
||||
self.update_transformations()
|
||||
sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
|
||||
|
||||
def change_encoding(self):
|
||||
"""change encoding on the serial port"""
|
||||
sys.stderr.write('\n--- Enter new encoding name [{}]: '.format(self.input_encoding))
|
||||
with self.console:
|
||||
new_encoding = sys.stdin.readline().strip()
|
||||
if new_encoding:
|
||||
try:
|
||||
codecs.lookup(new_encoding)
|
||||
except LookupError:
|
||||
sys.stderr.write('--- invalid encoding name: {}\n'.format(new_encoding))
|
||||
else:
|
||||
self.set_rx_encoding(new_encoding)
|
||||
self.set_tx_encoding(new_encoding)
|
||||
sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
|
||||
sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
|
||||
|
||||
def change_baudrate(self):
|
||||
"""change the baudrate"""
|
||||
sys.stderr.write('\n--- Baudrate: ')
|
||||
sys.stderr.flush()
|
||||
with self.console:
|
||||
backup = self.serial.baudrate
|
||||
try:
|
||||
self.serial.baudrate = int(sys.stdin.readline().strip())
|
||||
except ValueError as e:
|
||||
sys.stderr.write('--- ERROR setting baudrate: {} ---\n'.format(e))
|
||||
self.serial.baudrate = backup
|
||||
else:
|
||||
self.dump_port_settings()
|
||||
|
||||
def change_port(self):
|
||||
"""Have a conversation with the user to change the serial port"""
|
||||
with self.console:
|
||||
try:
|
||||
port = ask_for_port()
|
||||
except KeyboardInterrupt:
|
||||
port = None
|
||||
if port and port != self.serial.port:
|
||||
# reader thread needs to be shut down
|
||||
self._stop_reader()
|
||||
# save settings
|
||||
settings = self.serial.getSettingsDict()
|
||||
try:
|
||||
new_serial = serial.serial_for_url(port, do_not_open=True)
|
||||
# restore settings and open
|
||||
new_serial.applySettingsDict(settings)
|
||||
new_serial.rts = self.serial.rts
|
||||
new_serial.dtr = self.serial.dtr
|
||||
new_serial.open()
|
||||
new_serial.break_condition = self.serial.break_condition
|
||||
except Exception as e:
|
||||
sys.stderr.write('--- ERROR opening new port: {} ---\n'.format(e))
|
||||
new_serial.close()
|
||||
else:
|
||||
self.serial.close()
|
||||
self.serial = new_serial
|
||||
sys.stderr.write('--- Port changed to: {} ---\n'.format(self.serial.port))
|
||||
# and restart the reader thread
|
||||
self._start_reader()
|
||||
|
||||
def suspend_port(self):
|
||||
"""\
|
||||
open port temporarily, allow reconnect, exit and port change to get
|
||||
out of the loop
|
||||
"""
|
||||
# reader thread needs to be shut down
|
||||
self._stop_reader()
|
||||
self.serial.close()
|
||||
sys.stderr.write('\n--- Port closed: {} ---\n'.format(self.serial.port))
|
||||
do_change_port = False
|
||||
while not self.serial.is_open:
|
||||
sys.stderr.write('--- Quit: {exit} | p: port change | any other key to reconnect ---\n'.format(
|
||||
exit=key_description(self.exit_character)))
|
||||
k = self.console.getkey()
|
||||
if k == self.exit_character:
|
||||
self.stop() # exit app
|
||||
break
|
||||
elif k in 'pP':
|
||||
do_change_port = True
|
||||
break
|
||||
try:
|
||||
self.serial.open()
|
||||
except Exception as e:
|
||||
sys.stderr.write('--- ERROR opening port: {} ---\n'.format(e))
|
||||
if do_change_port:
|
||||
self.change_port()
|
||||
else:
|
||||
# and restart the reader thread
|
||||
self._start_reader()
|
||||
sys.stderr.write('--- Port opened: {} ---\n'.format(self.serial.port))
|
||||
|
||||
def get_help_text(self):
|
||||
"""return the help text"""
|
||||
# help text, starts with blank line!
|
||||
return """
|
||||
--- pySerial ({version}) - miniterm - help
|
||||
---
|
||||
--- {exit:8} Exit program
|
||||
--- {menu:8} Menu escape key, followed by:
|
||||
--- Menu keys:
|
||||
--- {menu:7} Send the menu character itself to remote
|
||||
--- {exit:7} Send the exit character itself to remote
|
||||
--- {info:7} Show info
|
||||
--- {upload:7} Upload file (prompt will be shown)
|
||||
--- {repr:7} encoding
|
||||
--- {filter:7} edit filters
|
||||
--- Toggles:
|
||||
--- {rts:7} RTS {dtr:7} DTR {brk:7} BREAK
|
||||
--- {echo:7} echo {eol:7} EOL
|
||||
---
|
||||
--- Port settings ({menu} followed by the following):
|
||||
--- p change port
|
||||
--- 7 8 set data bits
|
||||
--- N E O S M change parity (None, Even, Odd, Space, Mark)
|
||||
--- 1 2 3 set stop bits (1, 2, 1.5)
|
||||
--- b change baud rate
|
||||
--- x X disable/enable software flow control
|
||||
--- r R disable/enable hardware flow control
|
||||
""".format(version=getattr(serial, 'VERSION', 'unknown version'),
|
||||
exit=key_description(self.exit_character),
|
||||
menu=key_description(self.menu_character),
|
||||
rts=key_description('\x12'),
|
||||
dtr=key_description('\x04'),
|
||||
brk=key_description('\x02'),
|
||||
echo=key_description('\x05'),
|
||||
info=key_description('\x09'),
|
||||
upload=key_description('\x15'),
|
||||
repr=key_description('\x01'),
|
||||
filter=key_description('\x06'),
|
||||
eol=key_description('\x0c'))
|
||||
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
# default args can be used to override when calling main() from an other script
|
||||
# e.g to create a miniterm-my-device.py
|
||||
def main(default_port=None, default_baudrate=9600, default_rts=None, default_dtr=None):
|
||||
"""Command line tool, entry point"""
|
||||
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Miniterm - A simple terminal program for the serial port.")
|
||||
|
||||
parser.add_argument(
|
||||
"port",
|
||||
nargs='?',
|
||||
help="serial port name ('-' to show port list)",
|
||||
default=default_port)
|
||||
|
||||
parser.add_argument(
|
||||
"baudrate",
|
||||
nargs='?',
|
||||
type=int,
|
||||
help="set baud rate, default: %(default)s",
|
||||
default=default_baudrate)
|
||||
|
||||
group = parser.add_argument_group("port settings")
|
||||
|
||||
group.add_argument(
|
||||
"--parity",
|
||||
choices=['N', 'E', 'O', 'S', 'M'],
|
||||
type=lambda c: c.upper(),
|
||||
help="set parity, one of {N E O S M}, default: N",
|
||||
default='N')
|
||||
|
||||
group.add_argument(
|
||||
"--rtscts",
|
||||
action="store_true",
|
||||
help="enable RTS/CTS flow control (default off)",
|
||||
default=False)
|
||||
|
||||
group.add_argument(
|
||||
"--xonxoff",
|
||||
action="store_true",
|
||||
help="enable software flow control (default off)",
|
||||
default=False)
|
||||
|
||||
group.add_argument(
|
||||
"--rts",
|
||||
type=int,
|
||||
help="set initial RTS line state (possible values: 0, 1)",
|
||||
default=default_rts)
|
||||
|
||||
group.add_argument(
|
||||
"--dtr",
|
||||
type=int,
|
||||
help="set initial DTR line state (possible values: 0, 1)",
|
||||
default=default_dtr)
|
||||
|
||||
group.add_argument(
|
||||
"--ask",
|
||||
action="store_true",
|
||||
help="ask again for port when open fails",
|
||||
default=False)
|
||||
|
||||
group = parser.add_argument_group("data handling")
|
||||
|
||||
group.add_argument(
|
||||
"-e", "--echo",
|
||||
action="store_true",
|
||||
help="enable local echo (default off)",
|
||||
default=False)
|
||||
|
||||
group.add_argument(
|
||||
"--encoding",
|
||||
dest="serial_port_encoding",
|
||||
metavar="CODEC",
|
||||
help="set the encoding for the serial port (e.g. hexlify, Latin1, UTF-8), default: %(default)s",
|
||||
default='UTF-8')
|
||||
|
||||
group.add_argument(
|
||||
"-f", "--filter",
|
||||
action="append",
|
||||
metavar="NAME",
|
||||
help="add text transformation",
|
||||
default=[])
|
||||
|
||||
group.add_argument(
|
||||
"--eol",
|
||||
choices=['CR', 'LF', 'CRLF'],
|
||||
type=lambda c: c.upper(),
|
||||
help="end of line mode",
|
||||
default='CRLF')
|
||||
|
||||
group.add_argument(
|
||||
"--raw",
|
||||
action="store_true",
|
||||
help="Do no apply any encodings/transformations",
|
||||
default=False)
|
||||
|
||||
group = parser.add_argument_group("hotkeys")
|
||||
|
||||
group.add_argument(
|
||||
"--exit-char",
|
||||
type=int,
|
||||
metavar='NUM',
|
||||
help="Unicode of special character that is used to exit the application, default: %(default)s",
|
||||
default=0x1d) # GS/CTRL+]
|
||||
|
||||
group.add_argument(
|
||||
"--menu-char",
|
||||
type=int,
|
||||
metavar='NUM',
|
||||
help="Unicode code of special character that is used to control miniterm (menu), default: %(default)s",
|
||||
default=0x14) # Menu: CTRL+T
|
||||
|
||||
group = parser.add_argument_group("diagnostics")
|
||||
|
||||
group.add_argument(
|
||||
"-q", "--quiet",
|
||||
action="store_true",
|
||||
help="suppress non-error messages",
|
||||
default=False)
|
||||
|
||||
group.add_argument(
|
||||
"--develop",
|
||||
action="store_true",
|
||||
help="show Python traceback on error",
|
||||
default=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.menu_char == args.exit_char:
|
||||
parser.error('--exit-char can not be the same as --menu-char')
|
||||
|
||||
if args.filter:
|
||||
if 'help' in args.filter:
|
||||
sys.stderr.write('Available filters:\n')
|
||||
sys.stderr.write('\n'.join(
|
||||
'{:<10} = {.__doc__}'.format(k, v)
|
||||
for k, v in sorted(TRANSFORMATIONS.items())))
|
||||
sys.stderr.write('\n')
|
||||
sys.exit(1)
|
||||
filters = args.filter
|
||||
else:
|
||||
filters = ['default']
|
||||
|
||||
while True:
|
||||
# no port given on command line -> ask user now
|
||||
if args.port is None or args.port == '-':
|
||||
try:
|
||||
args.port = ask_for_port()
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write('\n')
|
||||
parser.error('user aborted and port is not given')
|
||||
else:
|
||||
if not args.port:
|
||||
parser.error('port is not given')
|
||||
try:
|
||||
serial_instance = serial.serial_for_url(
|
||||
args.port,
|
||||
args.baudrate,
|
||||
parity=args.parity,
|
||||
rtscts=args.rtscts,
|
||||
xonxoff=args.xonxoff,
|
||||
do_not_open=True)
|
||||
|
||||
if not hasattr(serial_instance, 'cancel_read'):
|
||||
# enable timeout for alive flag polling if cancel_read is not available
|
||||
serial_instance.timeout = 1
|
||||
|
||||
if args.dtr is not None:
|
||||
if not args.quiet:
|
||||
sys.stderr.write('--- forcing DTR {}\n'.format('active' if args.dtr else 'inactive'))
|
||||
serial_instance.dtr = args.dtr
|
||||
if args.rts is not None:
|
||||
if not args.quiet:
|
||||
sys.stderr.write('--- forcing RTS {}\n'.format('active' if args.rts else 'inactive'))
|
||||
serial_instance.rts = args.rts
|
||||
|
||||
serial_instance.open()
|
||||
except serial.SerialException as e:
|
||||
sys.stderr.write('could not open port {}: {}\n'.format(repr(args.port), e))
|
||||
if args.develop:
|
||||
raise
|
||||
if not args.ask:
|
||||
sys.exit(1)
|
||||
else:
|
||||
args.port = '-'
|
||||
else:
|
||||
break
|
||||
|
||||
miniterm = Miniterm(
|
||||
serial_instance,
|
||||
echo=args.echo,
|
||||
eol=args.eol.lower(),
|
||||
filters=filters)
|
||||
miniterm.exit_character = unichr(args.exit_char)
|
||||
miniterm.menu_character = unichr(args.menu_char)
|
||||
miniterm.raw = args.raw
|
||||
miniterm.set_rx_encoding(args.serial_port_encoding)
|
||||
miniterm.set_tx_encoding(args.serial_port_encoding)
|
||||
|
||||
if not args.quiet:
|
||||
sys.stderr.write('--- Miniterm on {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} ---\n'.format(
|
||||
p=miniterm.serial))
|
||||
sys.stderr.write('--- Quit: {} | Menu: {} | Help: {} followed by {} ---\n'.format(
|
||||
key_description(miniterm.exit_character),
|
||||
key_description(miniterm.menu_character),
|
||||
key_description(miniterm.menu_character),
|
||||
key_description('\x08')))
|
||||
|
||||
miniterm.start()
|
||||
try:
|
||||
miniterm.join(True)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
if not args.quiet:
|
||||
sys.stderr.write("\n--- exit ---\n")
|
||||
miniterm.join()
|
||||
miniterm.close()
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
if __name__ == '__main__':
|
||||
main()
|
BIN
.local/bin/miniterm.pyc
Normal file
BIN
.local/bin/miniterm.pyc
Normal file
Binary file not shown.
8
.local/bin/mk-android-certs
Executable file
8
.local/bin/mk-android-certs
Executable file
@ -0,0 +1,8 @@
|
||||
subject='/C=US/ST=Texas/L=Fort Worth/O=Android/OU=Android/CN=Android/emailAddress=me@xstefen.dev'
|
||||
mkdir ~/.android-certs
|
||||
for cert in bluetooth cyngn-app media networkstack platform releasekey sdk_sandbox shared testcert testkey verity; do \
|
||||
./development/tools/make_key ~/.android-certs/$cert "$subject"; \
|
||||
done
|
||||
for apex in com.android.adbd com.android.adservices com.android.adservices.api com.android.appsearch com.android.art com.android.bluetooth com.android.btservices com.android.cellbroadcast com.android.compos com.android.connectivity.resources com.android.conscrypt com.android.extservices com.android.hotspot2.osulogin com.android.i18n com.android.ipsec com.android.media com.android.media.swcodec com.android.mediaprovider com.android.nearby.halfsheet com.android.neuralnetworks com.android.ondevicepersonalization com.android.os.statsd com.android.permission com.android.resolv com.android.runtime com.android.safetycenter.resources com.android.scheduling com.android.sdkext com.android.support.apexer com.android.telephony com.android.tethering com.android.tzdata com.android.uwb com.android.uwb.resources com.android.virt com.android.wifi com.android.wifi.dialog com.android.wifi.resources com.qorvo.uwb; do \
|
||||
./development/tools/make_key ~/.android-certs/$apex "$subject"; \
|
||||
done
|
8
.local/bin/mkaur
Executable file
8
.local/bin/mkaur
Executable file
@ -0,0 +1,8 @@
|
||||
# Builds a package from the Arch User Repository
|
||||
function mkaur() {
|
||||
git clone https://aur.archlinux.org/"${1}"
|
||||
cd "${1}" || return
|
||||
makepkg -si "${2}"
|
||||
cd - || return
|
||||
rm -rf "${1}"
|
||||
}
|
316
.local/bin/mkbootimg
Executable file
316
.local/bin/mkbootimg
Executable file
@ -0,0 +1,316 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2015, The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from argparse import ArgumentParser, FileType, Action
|
||||
from hashlib import sha1
|
||||
from os import fstat
|
||||
import re
|
||||
from struct import pack
|
||||
|
||||
|
||||
BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
|
||||
|
||||
def filesize(f):
|
||||
if f is None:
|
||||
return 0
|
||||
try:
|
||||
return fstat(f.fileno()).st_size
|
||||
except OSError:
|
||||
return 0
|
||||
|
||||
|
||||
def update_sha(sha, f):
|
||||
if f:
|
||||
sha.update(f.read())
|
||||
f.seek(0)
|
||||
sha.update(pack('I', filesize(f)))
|
||||
else:
|
||||
sha.update(pack('I', 0))
|
||||
|
||||
|
||||
def pad_file(f, padding):
|
||||
pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)
|
||||
f.write(pack(str(pad) + 'x'))
|
||||
|
||||
|
||||
def get_number_of_pages(image_size, page_size):
|
||||
"""calculates the number of pages required for the image"""
|
||||
return (image_size + page_size - 1) / page_size
|
||||
|
||||
|
||||
def get_recovery_dtbo_offset(args):
|
||||
"""calculates the offset of recovery_dtbo image in the boot image"""
|
||||
num_header_pages = 1 # header occupies a page
|
||||
num_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize)
|
||||
num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk), args.pagesize)
|
||||
num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize)
|
||||
dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages +
|
||||
num_ramdisk_pages + num_second_pages)
|
||||
return dtbo_offset
|
||||
|
||||
|
||||
def write_header_v3(args):
|
||||
BOOT_IMAGE_HEADER_V3_SIZE = 1596
|
||||
BOOT_MAGIC = 'ANDROID!'.encode()
|
||||
|
||||
args.output.write(pack('8s', BOOT_MAGIC))
|
||||
args.output.write(pack(
|
||||
'4I',
|
||||
filesize(args.kernel), # kernel size in bytes
|
||||
filesize(args.ramdisk), # ramdisk size in bytes
|
||||
(args.os_version << 11) | args.os_patch_level, # os version and patch level
|
||||
BOOT_IMAGE_HEADER_V3_SIZE))
|
||||
|
||||
args.output.write(pack('4I', 0, 0, 0, 0)) # reserved
|
||||
|
||||
args.output.write(pack('I', args.header_version)) # version of bootimage header
|
||||
args.output.write(pack('1536s', args.cmdline.encode()))
|
||||
pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)
|
||||
|
||||
def write_vendor_boot_header(args):
|
||||
VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
|
||||
BOOT_MAGIC = 'VNDRBOOT'.encode()
|
||||
|
||||
args.vendor_boot.write(pack('8s', BOOT_MAGIC))
|
||||
args.vendor_boot.write(pack(
|
||||
'5I',
|
||||
args.header_version, # version of header
|
||||
args.pagesize, # flash page size we assume
|
||||
args.base + args.kernel_offset, # kernel physical load addr
|
||||
args.base + args.ramdisk_offset, # ramdisk physical load addr
|
||||
filesize(args.vendor_ramdisk))) # vendor ramdisk size in bytes
|
||||
args.vendor_boot.write(pack('2048s', args.vendor_cmdline.encode()))
|
||||
args.vendor_boot.write(pack('I', args.base + args.tags_offset)) # physical addr for kernel tags
|
||||
args.vendor_boot.write(pack('16s', args.board.encode())) # asciiz product name
|
||||
args.vendor_boot.write(pack('I', VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) # header size in bytes
|
||||
if filesize(args.dtb) == 0:
|
||||
raise ValueError("DTB image must not be empty.")
|
||||
args.vendor_boot.write(pack('I', filesize(args.dtb))) # size in bytes
|
||||
args.vendor_boot.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
|
||||
pad_file(args.vendor_boot, args.pagesize)
|
||||
|
||||
def write_header(args):
|
||||
BOOT_IMAGE_HEADER_V1_SIZE = 1648
|
||||
BOOT_IMAGE_HEADER_V2_SIZE = 1660
|
||||
BOOT_MAGIC = 'ANDROID!'.encode()
|
||||
|
||||
if args.header_version > 3:
|
||||
raise ValueError('Boot header version %d not supported' % args.header_version)
|
||||
elif args.header_version == 3:
|
||||
return write_header_v3(args)
|
||||
|
||||
args.output.write(pack('8s', BOOT_MAGIC))
|
||||
final_ramdisk_offset = (args.base + args.ramdisk_offset) if filesize(args.ramdisk) > 0 else 0
|
||||
final_second_offset = (args.base + args.second_offset) if filesize(args.second) > 0 else 0
|
||||
args.output.write(pack(
|
||||
'10I',
|
||||
filesize(args.kernel), # size in bytes
|
||||
args.base + args.kernel_offset, # physical load addr
|
||||
filesize(args.ramdisk), # size in bytes
|
||||
final_ramdisk_offset, # physical load addr
|
||||
filesize(args.second), # size in bytes
|
||||
final_second_offset, # physical load addr
|
||||
args.base + args.tags_offset, # physical addr for kernel tags
|
||||
args.pagesize, # flash page size we assume
|
||||
args.header_version, # version of bootimage header
|
||||
(args.os_version << 11) | args.os_patch_level)) # os version and patch level
|
||||
args.output.write(pack('16s', args.board.encode())) # asciiz product name
|
||||
args.output.write(pack('512s', args.cmdline[:512].encode()))
|
||||
|
||||
sha = sha1()
|
||||
update_sha(sha, args.kernel)
|
||||
update_sha(sha, args.ramdisk)
|
||||
update_sha(sha, args.second)
|
||||
|
||||
if args.header_version > 0:
|
||||
update_sha(sha, args.recovery_dtbo)
|
||||
if args.header_version > 1:
|
||||
update_sha(sha, args.dtb)
|
||||
|
||||
img_id = pack('32s', sha.digest())
|
||||
|
||||
args.output.write(img_id)
|
||||
args.output.write(pack('1024s', args.cmdline[512:].encode()))
|
||||
|
||||
if args.header_version > 0:
|
||||
args.output.write(pack('I', filesize(args.recovery_dtbo))) # size in bytes
|
||||
if args.recovery_dtbo:
|
||||
args.output.write(pack('Q', get_recovery_dtbo_offset(args))) # recovery dtbo offset
|
||||
else:
|
||||
args.output.write(pack('Q', 0)) # Will be set to 0 for devices without a recovery dtbo
|
||||
|
||||
# Populate boot image header size for header versions 1 and 2.
|
||||
if args.header_version == 1:
|
||||
args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE))
|
||||
elif args.header_version == 2:
|
||||
args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE))
|
||||
|
||||
if args.header_version > 1:
|
||||
|
||||
if filesize(args.dtb) == 0:
|
||||
raise ValueError("DTB image must not be empty.")
|
||||
|
||||
args.output.write(pack('I', filesize(args.dtb))) # size in bytes
|
||||
args.output.write(pack('Q', args.base + args.dtb_offset)) # dtb physical load address
|
||||
pad_file(args.output, args.pagesize)
|
||||
return img_id
|
||||
|
||||
|
||||
class ValidateStrLenAction(Action):
|
||||
def __init__(self, option_strings, dest, nargs=None, **kwargs):
|
||||
if 'maxlen' not in kwargs:
|
||||
raise ValueError('maxlen must be set')
|
||||
self.maxlen = int(kwargs['maxlen'])
|
||||
del kwargs['maxlen']
|
||||
super(ValidateStrLenAction, self).__init__(option_strings, dest, **kwargs)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
if len(values) > self.maxlen:
|
||||
raise ValueError(
|
||||
'String argument too long: max {0:d}, got {1:d}'.format(self.maxlen, len(values)))
|
||||
setattr(namespace, self.dest, values)
|
||||
|
||||
|
||||
def write_padded_file(f_out, f_in, padding):
|
||||
if f_in is None:
|
||||
return
|
||||
f_out.write(f_in.read())
|
||||
pad_file(f_out, padding)
|
||||
|
||||
|
||||
def parse_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
|
||||
def parse_os_version(x):
|
||||
match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)
|
||||
if match:
|
||||
a = int(match.group(1))
|
||||
b = c = 0
|
||||
if match.lastindex >= 2:
|
||||
b = int(match.group(2))
|
||||
if match.lastindex == 3:
|
||||
c = int(match.group(3))
|
||||
# 7 bits allocated for each field
|
||||
assert a < 128
|
||||
assert b < 128
|
||||
assert c < 128
|
||||
return (a << 14) | (b << 7) | c
|
||||
return 0
|
||||
|
||||
|
||||
def parse_os_patch_level(x):
|
||||
match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x)
|
||||
if match:
|
||||
y = int(match.group(1)) - 2000
|
||||
m = int(match.group(2))
|
||||
# 7 bits allocated for the year, 4 bits for the month
|
||||
assert 0 <= y < 128
|
||||
assert 0 < m <= 12
|
||||
return (y << 4) | m
|
||||
return 0
|
||||
|
||||
|
||||
def parse_cmdline():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))
|
||||
parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
|
||||
parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
|
||||
parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))
|
||||
recovery_dtbo_group = parser.add_mutually_exclusive_group()
|
||||
recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',
|
||||
type=FileType('rb'))
|
||||
recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',
|
||||
type=FileType('rb'), metavar='RECOVERY_ACPIO',
|
||||
dest='recovery_dtbo')
|
||||
parser.add_argument('--cmdline', help='extra arguments to be passed on the '
|
||||
'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
|
||||
parser.add_argument('--vendor_cmdline',
|
||||
help='kernel command line arguments contained in vendor boot',
|
||||
default='', action=ValidateStrLenAction, maxlen=2048)
|
||||
parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
|
||||
parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
|
||||
parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,
|
||||
default=0x01000000)
|
||||
parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
|
||||
default=0x00f00000)
|
||||
parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)
|
||||
|
||||
parser.add_argument('--os_version', help='operating system version', type=parse_os_version,
|
||||
default=0)
|
||||
parser.add_argument('--os_patch_level', help='operating system patch level',
|
||||
type=parse_os_patch_level, default=0)
|
||||
parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)
|
||||
parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
|
||||
maxlen=16)
|
||||
parser.add_argument('--pagesize', help='page size', type=parse_int,
|
||||
choices=[2**i for i in range(11, 15)], default=2048)
|
||||
parser.add_argument('--id', help='print the image ID on standard output',
|
||||
action='store_true')
|
||||
parser.add_argument('--header_version', help='boot image header version', type=parse_int,
|
||||
default=0)
|
||||
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))
|
||||
parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))
|
||||
parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def write_data(args, pagesize):
|
||||
write_padded_file(args.output, args.kernel, pagesize)
|
||||
write_padded_file(args.output, args.ramdisk, pagesize)
|
||||
write_padded_file(args.output, args.second, pagesize)
|
||||
|
||||
if args.header_version > 0 and args.header_version < 3:
|
||||
write_padded_file(args.output, args.recovery_dtbo, pagesize)
|
||||
if args.header_version == 2:
|
||||
write_padded_file(args.output, args.dtb, pagesize)
|
||||
|
||||
|
||||
def write_vendor_boot_data(args):
|
||||
write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)
|
||||
write_padded_file(args.vendor_boot, args.dtb, args.pagesize)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_cmdline()
|
||||
if args.vendor_boot is not None:
|
||||
if args.header_version < 3:
|
||||
raise ValueError('--vendor_boot not compatible with given header version')
|
||||
if args.vendor_ramdisk is None:
|
||||
raise ValueError('--vendor_ramdisk missing or invalid')
|
||||
write_vendor_boot_header(args)
|
||||
write_vendor_boot_data(args)
|
||||
if args.output is not None:
|
||||
if args.kernel is None:
|
||||
raise ValueError('kernel must be supplied when creating a boot image')
|
||||
if args.second is not None and args.header_version > 2:
|
||||
raise ValueError('--second not compatible with given header version')
|
||||
img_id = write_header(args)
|
||||
if args.header_version > 2:
|
||||
write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)
|
||||
else:
|
||||
write_data(args, args.pagesize)
|
||||
if args.id and img_id is not None:
|
||||
# Python 2's struct.pack returns a string, but py3 returns bytes.
|
||||
if isinstance(img_id, str):
|
||||
img_id = [ord(x) for x in img_id]
|
||||
print('0x' + ''.join('{:02x}'.format(c) for c in img_id))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
8
.local/bin/nimporter
Executable file
8
.local/bin/nimporter
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from nimporter_cli import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
1
.local/bin/normalizer
Symbolic link
1
.local/bin/normalizer
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/aospdtgen/bin/normalizer
|
1
.local/bin/otc2otf
Symbolic link
1
.local/bin/otc2otf
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/otc2otf
|
1
.local/bin/otf2otc
Symbolic link
1
.local/bin/otf2otc
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/otf2otc
|
1
.local/bin/otf2ttf
Symbolic link
1
.local/bin/otf2ttf
Symbolic link
@ -0,0 +1 @@
|
||||
/home/xstefen/.local/pipx/venvs/afdko/bin/otf2ttf
|
61
.local/bin/packedstruct.py
Normal file
61
.local/bin/packedstruct.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright 2021 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
import struct
|
||||
|
||||
|
||||
class PackedStruct(object):
|
||||
"""Class representing a C style packed structure
|
||||
|
||||
Derived classes need to provide a dictionary with key will be the attributes and the values are
|
||||
the format characters for each field. e.g.
|
||||
|
||||
class Foo(PackedStruct):
|
||||
_FIELDS = {
|
||||
x: 'I',
|
||||
name: '64s',
|
||||
}
|
||||
|
||||
In this case Foo.x will represent an "unsigned int" C value, while Foo.name will be a "char[64]"
|
||||
C value
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._fmt = '<' + ''.join(fmt for fmt in self._FIELDS.values())
|
||||
for name in self._FIELDS:
|
||||
setattr(self, name, None)
|
||||
|
||||
for name, val in zip(self._FIELDS.keys(), args):
|
||||
setattr(self, name, val)
|
||||
for name, val in kwargs.items():
|
||||
setattr(self, name, val)
|
||||
|
||||
def __repr__(self):
|
||||
return '{} {{\n'.format(self.__class__.__name__) + ',\n'.join(
|
||||
' {!r}: {!r}'.format(k, getattr(self, k)) for k in self._FIELDS) + '\n}'
|
||||
|
||||
def __str__(self):
|
||||
return struct.pack(self._fmt, *(getattr(self, x) for x in self._FIELDS))
|
||||
|
||||
def __bytes__(self):
|
||||
return struct.pack(self._fmt, *(getattr(self, x) for x in self._FIELDS))
|
||||
|
||||
def __len__(self):
|
||||
return struct.calcsize(self._fmt)
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, data):
|
||||
fmt_str = '<' + ''.join(fmt for fmt in cls._FIELDS.values())
|
||||
return cls(*struct.unpack(fmt_str, data))
|
BIN
.local/bin/payload-dumper-go
Executable file
BIN
.local/bin/payload-dumper-go
Executable file
Binary file not shown.
8
.local/bin/pep8
Executable file
8
.local/bin/pep8
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pep8 import _main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(_main())
|
1830
.local/bin/pfetch
Executable file
1830
.local/bin/pfetch
Executable file
File diff suppressed because it is too large
Load Diff
4
.local/bin/pimg
Executable file
4
.local/bin/pimg
Executable file
@ -0,0 +1,4 @@
|
||||
#! /bin/sh
|
||||
|
||||
placeholder=$1
|
||||
curl -F"file=@$placeholder" http://0x0.st
|
136
.local/bin/pipes
Executable file
136
.local/bin/pipes
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
# pipes.sh: Animated pipes terminal screensaver.
|
||||
#
|
||||
# This modified version is maintained at:
|
||||
#
|
||||
# https://github.com/pipeseroni/pipes.sh
|
||||
|
||||
VERSION=1.2.0
|
||||
|
||||
M=32768
|
||||
p=1
|
||||
f=75 s=13 r=2000 t=0
|
||||
w=80 h=24
|
||||
|
||||
resize() {
|
||||
w=$(tput cols) h=$(tput lines)
|
||||
}
|
||||
|
||||
# ab -> idx = a*4 + b
|
||||
# 0: up, 1: right, 2: down, 3: left
|
||||
# 00 means going up , then going up -> ┃
|
||||
# 12 means going right, then going down -> ┓
|
||||
sets=(
|
||||
"┃┏ ┓┛━┓ ┗┃┛┗ ┏━"
|
||||
"│╭ ╮╯─╮ ╰│╯╰ ╭─"
|
||||
"│┌ ┐┘─┐ └│┘└ ┌─"
|
||||
"║╔ ╗╝═╗ ╚║╝╚ ╔═"
|
||||
"|+ ++-+ +|++ +-"
|
||||
"|/ \/-\ \|/\ /-"
|
||||
".. .... .... .."
|
||||
".o oo.o o.oo o."
|
||||
"-\ /\|/ /-\/ \|" # railway
|
||||
"╿┍ ┑┚╼┒ ┕╽┙┖ ┎╾" # knobby pipe
|
||||
)
|
||||
v=()
|
||||
RNDSTART=0
|
||||
BOLD=1
|
||||
NOCOLOR=0
|
||||
|
||||
OPTIND=1
|
||||
while getopts "p:t:f:s:r:RBChv" arg; do
|
||||
case $arg in
|
||||
p) ((p=(OPTARG>0)?OPTARG:p));;
|
||||
t)
|
||||
if [[ "$OPTARG" = c???????????????? ]]; then
|
||||
V+=(${#sets[@]})
|
||||
sets+=("${OPTARG:1}")
|
||||
else
|
||||
((OPTARG>=0 && OPTARG<${#sets[@]})) && V+=($OPTARG)
|
||||
fi
|
||||
;;
|
||||
f) ((f=(OPTARG>19 && OPTARG<101)?OPTARG:f));;
|
||||
s) ((s=(OPTARG>4 && OPTARG<16 )?OPTARG:s));;
|
||||
r) ((r=(OPTARG>=0)?OPTARG:r));;
|
||||
R) RNDSTART=1;;
|
||||
B) BOLD=0;;
|
||||
C) NOCOLOR=1;;
|
||||
h) echo -e "Usage: $(basename $0) [OPTION]..."
|
||||
echo -e "Animated pipes terminal screensaver.\n"
|
||||
echo -e " -p [1-]\tnumber of pipes (D=1)."
|
||||
echo -e " -t [0-$((${#sets[@]} - 1))]\ttype of pipes, can be used more than once (D=0)."
|
||||
echo -e " -t c[16 chars]\tcustom type of pipes."
|
||||
echo -e " -f [20-100]\tframerate (D=75)."
|
||||
echo -e " -s [5-15]\tprobability of a straight fitting (D=13)."
|
||||
echo -e " -r LIMIT\treset after x characters, 0 if no limit (D=2000)."
|
||||
echo -e " -R \t\trandom starting point."
|
||||
echo -e " -B \t\tno bold effect."
|
||||
echo -e " -C \t\tno color."
|
||||
echo -e " -h\t\thelp (this screen)."
|
||||
echo -e " -v\t\tprint version number.\n"
|
||||
exit 0;;
|
||||
v) echo "$(basename -- "$0") $VERSION"
|
||||
exit 0
|
||||
esac
|
||||
done
|
||||
|
||||
# set default values if not by options
|
||||
((${#V[@]})) || V=(0)
|
||||
|
||||
cleanup() {
|
||||
# clear up standard input
|
||||
read -t 0.001 && cat </dev/stdin>/dev/null
|
||||
|
||||
# terminal has no smcup and rmcup capabilities
|
||||
((FORCE_RESET)) && reset && exit 0
|
||||
|
||||
tput rmcup
|
||||
tput cnorm
|
||||
stty echo
|
||||
((NOCOLOR)) && echo -ne '\x1b[0m'
|
||||
exit 0
|
||||
}
|
||||
trap resize SIGWINCH
|
||||
trap cleanup HUP TERM
|
||||
trap 'break 2' INT
|
||||
|
||||
resize
|
||||
|
||||
for (( i=1; i<=p; i++ )); do
|
||||
c[i]=$((i%8)) n[i]=0 l[i]=0
|
||||
((x[i]=RNDSTART==1?RANDOM*w/32768:w/2))
|
||||
((y[i]=RNDSTART==1?RANDOM*h/32768:h/2))
|
||||
v[i]=${V[${#V[@]} * RANDOM / M]}
|
||||
done
|
||||
|
||||
stty -echo
|
||||
tput smcup || FORCE_RESET=1
|
||||
tput civis
|
||||
tput clear
|
||||
# any key press exits the loop and this script
|
||||
while REPLY=; read -t 0.0$((1000/f)) -n 1 2>/dev/null; [[ -z $REPLY ]] ; do
|
||||
for (( i=1; i<=p; i++ )); do
|
||||
# New position:
|
||||
((${l[i]}%2)) && ((x[i]+=-${l[i]}+2,1)) || ((y[i]+=${l[i]}-1))
|
||||
|
||||
# Loop on edges (change color on loop):
|
||||
((${x[i]}>=w||${x[i]}<0||${y[i]}>=h||${y[i]}<0)) && ((c[i]=RANDOM%8, v[i]=V[${#V[@]}*RANDOM/M]))
|
||||
((x[i]=(x[i]+w)%w))
|
||||
((y[i]=(y[i]+h)%h))
|
||||
|
||||
# New random direction:
|
||||
((n[i]=RANDOM%s-1))
|
||||
((n[i]=(${n[i]}>1||${n[i]}==0)?${l[i]}:${l[i]}+${n[i]}))
|
||||
((n[i]=(${n[i]}<0)?3:${n[i]}%4))
|
||||
|
||||
# Print:
|
||||
tput cup ${y[i]} ${x[i]}
|
||||
echo -ne "\x1b[${BOLD}m"
|
||||
[[ $NOCOLOR == 0 ]] && echo -ne "\x1b[3${c[i]}m"
|
||||
echo -n "${sets[v[i]]:l[i]*4+n[i]:1}"
|
||||
l[i]=${n[i]}
|
||||
done
|
||||
((r>0 && t*p>=r)) && tput reset && tput civis && t=0 || ((t++))
|
||||
done
|
||||
|
||||
cleanup
|
207
.local/bin/pipesx
Executable file
207
.local/bin/pipesx
Executable file
@ -0,0 +1,207 @@
|
||||
#!/bin/bash
|
||||
# Animated pipes.sh terminal screensaver at an angle.
|
||||
# Copyright (c) 2013-2015 Yu-Jie Lin
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
# Website: https://github.com/pipeseroni/pipesX.sh
|
||||
|
||||
VERSION=1.1.0
|
||||
|
||||
W=$(tput cols) H=$(tput lines)
|
||||
# maximal random value + 1
|
||||
M=32768
|
||||
|
||||
SETS=('╱╲' '/\' '..' 'oo' '\/')
|
||||
COLORS=(31 32 33 34 35 36 37)
|
||||
|
||||
# default values
|
||||
N=1
|
||||
T=()
|
||||
I=0.05
|
||||
P=25
|
||||
R=$((W * H / 4))
|
||||
|
||||
HELP="Usage: $(basename $0) [OPTIONS]
|
||||
Animated pipes.sh terminal screensaver at an angle.
|
||||
|
||||
Options:
|
||||
|
||||
-n [1-] number of pipes. (Default: $N)
|
||||
-t [0-$((${#SETS[@]} - 1))] types of pipes, can be used more than once. (Default: $T)
|
||||
-t c[2chs] custom type of pipes.
|
||||
-i [float] piping interval or maze generation interval. (Default: $I)
|
||||
-P [0-100] probability of a turning pipe or of \\ in maze generation. (Default: $P)
|
||||
-r [LIMIT] reset after x characters, 0 if no limit. (Default: $R)
|
||||
-R random starting point.
|
||||
-C no color.
|
||||
-X maze generation.
|
||||
-h this help message.
|
||||
-v print version number.
|
||||
"
|
||||
|
||||
while getopts "n:t:i:P:r:RCXhv" arg; do
|
||||
case $arg in
|
||||
n)
|
||||
((N = OPTARG > 0 ? OPTARG : N))
|
||||
;;
|
||||
t)
|
||||
if [[ "$OPTARG" = c?? ]]; then
|
||||
T+=(${#SETS[@]})
|
||||
SETS+=("${OPTARG:1}")
|
||||
else
|
||||
T+=($(((OPTARG >= 0 && OPTARG < ${#SETS[@]}) ? OPTARG : T)))
|
||||
fi
|
||||
;;
|
||||
i)
|
||||
I=$OPTARG
|
||||
;;
|
||||
P)
|
||||
((P = (OPTARG >= 0 && OPTARG <= 100) ? OPTARG : P))
|
||||
;;
|
||||
r)
|
||||
((R = OPTARG >= 0 ? OPTARG : R))
|
||||
;;
|
||||
R)
|
||||
RNDSTART=1
|
||||
;;
|
||||
C)
|
||||
NOCOLOR=1
|
||||
;;
|
||||
X)
|
||||
MAZE=1
|
||||
;;
|
||||
h)
|
||||
echo -e "$HELP"
|
||||
exit 0
|
||||
;;
|
||||
v)
|
||||
echo "$(basename -- "$0") $VERSION"
|
||||
exit 0
|
||||
esac
|
||||
done
|
||||
|
||||
# set to default values if not by options
|
||||
((${#T[@]})) || T=(0)
|
||||
|
||||
do_exit() {
|
||||
# clear up standard input
|
||||
read -t 0.001 && cat </dev/stdin>/dev/null
|
||||
|
||||
# terminal has no smcup and rmcup capabilities
|
||||
((FORCE_RESET)) && reset && exit 0
|
||||
|
||||
tput rmcup
|
||||
tput cnorm
|
||||
stty echo
|
||||
((NOCOLOR)) && echo -ne '\e[0m'
|
||||
exit 0
|
||||
}
|
||||
trap do_exit HUP TERM
|
||||
trap 'break 2' INT
|
||||
|
||||
# No echo stdin and hide the cursor
|
||||
stty -echo
|
||||
tput smcup || FORCE_RESET=1
|
||||
tput civis
|
||||
tput clear
|
||||
|
||||
# maze geneartion
|
||||
while [[ $MAZE ]] && clear; do
|
||||
[[ $NOCOLOR ]] || echo -ne "\e[1;${COLORS[${#COLORS[@]} * RANDOM / M]}m"
|
||||
for ((i = 0; i < W * H; i++ )); do
|
||||
echo -ne ${SETS[T]:100 * RANDOM / M < P:1}
|
||||
done
|
||||
read -t $I -n 1 && [[ $REPLY =~ q|Q ]] && do_exit
|
||||
done
|
||||
|
||||
# initialze values
|
||||
for ((n = 0; n < N; n++)); do
|
||||
((X[n] = RNDSTART ? (W + 2) * RANDOM / M : W / 2))
|
||||
((Y[n] = RNDSTART ? (H + 2) * RANDOM / M : H / 2))
|
||||
D[n]=$((4 * RANDOM / M))
|
||||
C[n]=${COLORS[${#COLORS[@]} * RANDOM / M]}
|
||||
t[n]=${T[${#T[@]} * RANDOM / M]}
|
||||
done
|
||||
|
||||
clear
|
||||
while REPLY=; read -t $I -n 1; [[ -z $REPLY ]] ; do
|
||||
for ((n = 0; n < N; n++, CC = 0)); do
|
||||
x=${X[n]} y=${Y[n]}
|
||||
d=${D[n]} c=${C[n]}
|
||||
|
||||
# calculate new direction `d`
|
||||
# 1 0
|
||||
# \/ 4 directions 0 to 3
|
||||
# /\
|
||||
# 2 3
|
||||
# valid directions: d: dd', d' is the new direction
|
||||
# d
|
||||
# 0: / 00 \ 01 03
|
||||
# / / /\
|
||||
# 1: / 10 \ 11 12
|
||||
# \ \ /\
|
||||
# 2: \/ 21 / 22 / 23
|
||||
# / \
|
||||
# 3: \/ 30 \ 32 \ 33
|
||||
# / \
|
||||
((d = (100 * RANDOM / M) < P ? ((d + 1) + 2 * (RANDOM % 2)) % 4 : d))
|
||||
((e = (d + 1) % 4))
|
||||
|
||||
# calculate new position
|
||||
# d' x' y'
|
||||
# 0: x+1 y-1
|
||||
# 1: x-1 y-1
|
||||
# 2: x-1 y+1
|
||||
# 3: x+1 y+1
|
||||
((xn = e < 2 ? x + 1 : x - 1))
|
||||
((yn = d < 2 ? y - 1 : y + 1))
|
||||
|
||||
# adjust position and change color?
|
||||
((d < 2 && y == 0)) && ((yn--, CC=1))
|
||||
((e > 1 && x == 0)) && ((xn--, CC=1))
|
||||
((d > 1 && y == H)) && ((yn++, CC=1))
|
||||
((e < 2 && x == W)) && ((xn++, CC=1))
|
||||
((CC)) && c=${COLORS[${#COLORS[@]} * RANDOM / M]}
|
||||
((CC)) && t[n]=${T[${#T[@]} * RANDOM / M]}
|
||||
|
||||
# warp pipe
|
||||
((xn = (xn + W + 1) % (W + 1)))
|
||||
((yn = (yn + H + 1) % (H + 1)))
|
||||
|
||||
# calculate position in terminal
|
||||
# d' xt yt
|
||||
# 0: x' y'+1
|
||||
# 1: x'+1 y'+1
|
||||
# 2: x'+1 y'
|
||||
# 3: x' y'
|
||||
((xt = e < 2 ? xn : xn + 1))
|
||||
((yt = d < 2 ? yn + 1 : yn))
|
||||
|
||||
echo -ne "\e[${yt};${xt}H"
|
||||
[[ $NOCOLOR ]] || echo -ne "\e[1;${c}m"
|
||||
echo -n "${SETS[t[n]]:d%2:1}"
|
||||
|
||||
X[n]=$xn Y[n]=$yn
|
||||
D[n]=$d C[n]=$c
|
||||
done
|
||||
((R)) && ((r += N, r >= R)) && r=0 && clear
|
||||
done
|
||||
|
||||
do_exit
|
15
.local/bin/pst
Executable file
15
.local/bin/pst
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
url="https://bin.xstefen.dev"
|
||||
filepath="$1"
|
||||
filename=$(basename -- "$filepath")
|
||||
extension="${filename##*.}"
|
||||
|
||||
response=$(curl --data-binary @${filepath:-/dev/stdin} --url $url)
|
||||
|
||||
#echo "$url$response"".""$extension" | tee >(xclip -selection clipboard)
|
||||
|
||||
pastelink="$url$response"
|
||||
[ -z "$extension" ] && \
|
||||
echo "$pastelink" || \
|
||||
echo "$pastelink.$extension"
|
16
.local/bin/push
Executable file
16
.local/bin/push
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
function push_impl() {
|
||||
adb shell rm -rf /system/$1
|
||||
adb push $1 /system/$1
|
||||
adb shell restorecon -R /system/$1
|
||||
}
|
||||
|
||||
adb wait-for-device root && adb wait-for-device remount
|
||||
for blob in $@; do
|
||||
if [ -f $blob ] || [ -d $blob ]; then
|
||||
push_impl $blob
|
||||
else
|
||||
find -name $blob | xargs push
|
||||
fi
|
||||
done
|
21
.local/bin/push_custom.sh
Executable file
21
.local/bin/push_custom.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# For all repos with custom branch below, add a git remote and push to said remote
|
||||
# @xstefen
|
||||
|
||||
BRANCH=lineage-20.0-x
|
||||
LIST=$(repo status | grep "$BRANCH" | awk '{print $2}' | sed 's/.$//')
|
||||
TOP=$(pwd)
|
||||
|
||||
for REPO in $LIST
|
||||
do
|
||||
DEST=android_"$(echo "$REPO" | sed 's/\//_/g')".git
|
||||
cd "$REPO" || exit
|
||||
git remote remove xstefen
|
||||
git remote add xstefen git@git.xstefen.dev:xstefen/"$DEST"
|
||||
echo
|
||||
echo pushing "$BRANCH" to "$DEST"
|
||||
echo
|
||||
git push -u xstefen "$BRANCH"
|
||||
sleep 2
|
||||
cd "$TOP" || exit
|
||||
done
|
8
.local/bin/pykwalify
Executable file
8
.local/bin/pykwalify
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pykwalify.cli import cli_entrypoint
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(cli_entrypoint())
|
8
.local/bin/python-formatter
Executable file
8
.local/bin/python-formatter
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from formatter2.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
BIN
.local/bin/qc_image_unpacker
Executable file
BIN
.local/bin/qc_image_unpacker
Executable file
Binary file not shown.
100
.local/bin/rain
Executable file
100
.local/bin/rain
Executable file
@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
RAINS=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿")
|
||||
COLORS=("\e[37m" "\e[37;1m")
|
||||
# More from 256 color mode
|
||||
for i in {244..255}; do
|
||||
COLORS=("${COLORS[@]}" "\e[38;5;${i}m")
|
||||
done
|
||||
NRAINS=${#RAINS[@]}
|
||||
NCOLORS=${#COLORS[@]}
|
||||
NUM_RAIN_METADATA=5
|
||||
|
||||
|
||||
sigwinch() {
|
||||
TERM_WIDTH=$(tput cols)
|
||||
TERM_HEIGHT=$(tput lines)
|
||||
STEP_DURATION=0.025
|
||||
((MAX_RAINS = TERM_WIDTH * TERM_HEIGHT / 4))
|
||||
((MAX_RAIN_LENGTH = TERM_HEIGHT < 10 ? 1 : TERM_HEIGHT / 10))
|
||||
# In percentage
|
||||
((NEW_RAIN_ODD = TERM_HEIGHT > 50 ? 100 : TERM_HEIGHT * 2))
|
||||
((NEW_RAIN_ODD = NEW_RAIN_ODD * 75 / 100))
|
||||
((FALLING_ODD = TERM_HEIGHT > 25 ? 100 : TERM_HEIGHT * 4))
|
||||
((FALLING_ODD = FALLING_ODD * 90 / 100))
|
||||
}
|
||||
|
||||
do_exit() {
|
||||
echo -ne "\e[${TERM_HEIGHT};1H\e[0K"
|
||||
|
||||
# Show cursor and echo stdin
|
||||
echo -ne "\e[?25h"
|
||||
stty echo
|
||||
exit 0
|
||||
}
|
||||
|
||||
do_render() {
|
||||
# Clean screen first
|
||||
for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do
|
||||
X=${rains[idx]}
|
||||
Y=${rains[idx + 1]}
|
||||
LENGTH=${rains[idx + 4]}
|
||||
for ((y = Y; y < Y + LENGTH; y++)); do
|
||||
(( y < 1 || y > TERM_HEIGHT )) && continue
|
||||
echo -ne "\e[${y};${X}H "
|
||||
done
|
||||
done
|
||||
|
||||
for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do
|
||||
if ((100 * RANDOM / 32768 < FALLING_ODD)); then
|
||||
# Falling
|
||||
if ((++rains[idx + 1] > TERM_HEIGHT)); then
|
||||
# Out of screen, bye sweet <3
|
||||
rains=("${rains[@]:0:idx}"
|
||||
"${rains[@]:idx+NUM_RAIN_METADATA:num_rains*NUM_RAIN_METADATA}")
|
||||
((num_rains--))
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
X=${rains[idx]}
|
||||
Y=${rains[idx + 1]}
|
||||
RAIN=${rains[idx + 2]}
|
||||
COLOR=${rains[idx + 3]}
|
||||
LENGTH=${rains[idx + 4]}
|
||||
for ((y = Y; y < Y + LENGTH; y++)); do
|
||||
(( y < 1 || y > TERM_HEIGHT )) && continue
|
||||
echo -ne "\e[${y};${X}H${COLOR}${RAIN}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
trap do_exit TERM INT
|
||||
trap sigwinch WINCH
|
||||
# No echo stdin and hide the cursor
|
||||
stty -echo
|
||||
echo -ne "\e[?25l"
|
||||
|
||||
echo -ne "\e[2J"
|
||||
rains=()
|
||||
sigwinch
|
||||
while :; do
|
||||
read -n 1 -t $STEP_DURATION ch
|
||||
case "$ch" in
|
||||
q|Q)
|
||||
do_exit
|
||||
;;
|
||||
esac
|
||||
|
||||
if ((num_rains < MAX_RAINS)) && ((100 * RANDOM / 32768 < NEW_RAIN_ODD)); then
|
||||
# Need new |, 1-based
|
||||
RAIN="${RAINS[NRAINS * RANDOM / 32768]}"
|
||||
COLOR="${COLORS[NCOLORS * RANDOM / 32768]}"
|
||||
LENGTH=$((MAX_RAIN_LENGTH * RANDOM / 32768 + 1))
|
||||
X=$((TERM_WIDTH * RANDOM / 32768 + 1))
|
||||
Y=$((1 - LENGTH))
|
||||
rains=("${rains[@]}" "$X" "$Y" "$RAIN" "$COLOR" "$LENGTH")
|
||||
((num_rains++))
|
||||
fi
|
||||
|
||||
# Let rain fall!
|
||||
do_render
|
||||
done
|
1798
.local/bin/readelf.py
Executable file
1798
.local/bin/readelf.py
Executable file
File diff suppressed because it is too large
Load Diff
1549
.local/bin/repo
Executable file
1549
.local/bin/repo
Executable file
File diff suppressed because it is too large
Load Diff
95
.local/bin/rofi_run
Executable file
95
.local/bin/rofi_run
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/bash
|
||||
|
||||
NAME="${0##*/}"
|
||||
VER="0.8"
|
||||
OPTS=(
|
||||
-padding 50
|
||||
-line-padding 4
|
||||
-hide-scrollbar
|
||||
)
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
|
||||
USAGE: $NAME [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
|
||||
-h,--help Display this message
|
||||
|
||||
-v,--version Display script version
|
||||
|
||||
-r,--run Run launcher
|
||||
|
||||
-d,--drun Desktop application launcher
|
||||
|
||||
-w,--window Switch between windows
|
||||
|
||||
-l,--logout System logout dialog
|
||||
|
||||
-b,--browser Browser search by keyword (requires surfraw)
|
||||
|
||||
-q,--qalculate Persistant calculator dialog (requires libqalculate)
|
||||
|
||||
-c,--clipboard Select previous clipboard entries (requires greenclip)
|
||||
|
||||
|
||||
Without any options the run dialog will be opened.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
if (( $# == 0 )); then
|
||||
rofi -show run -columns 2 "${OPTS[@]}"
|
||||
else
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-v|--version)
|
||||
echo -e "$NAME -- Version $VER"
|
||||
exit 0
|
||||
;;
|
||||
-d|--drun)
|
||||
rofi -modi drun -show drun -columns 2 "${OPTS[@]}" -show-icons -drun-icon-theme "ArchLabs-Dark"
|
||||
;;
|
||||
-r|--run)
|
||||
rofi -show run -columns 2 "${OPTS[@]}"
|
||||
;;
|
||||
-w|--window)
|
||||
rofi -show window "${OPTS[@]}"
|
||||
;;
|
||||
-q|--qalculate)
|
||||
hash qalc >/dev/null 2>&1 || { echo "Requires 'libqalculate' installed"; exit 1; }
|
||||
rofi -modi "calc:qalc +u8 -nocurrencies" -show "calc:qalc +u8 -nocurrencies" "${OPTS[@]}"
|
||||
;;
|
||||
-c|--clipboard)
|
||||
hash greenclip >/dev/null 2>&1 || { echo "Requires 'greenclip' installed"; exit 1; }
|
||||
rofi -modi "clipboard:greenclip print" -show "clipboard:greenclip print" "${OPTS[@]}"
|
||||
;;
|
||||
-b|--browser)
|
||||
hash surfraw >/dev/null 2>&1 || { echo "Requires 'surfraw' installed"; exit 1; }
|
||||
surfraw -browser="$BROWSER" "$(sr -elvi | awk -F'-' '{print $1}' | sed '/:/d' | awk '{$1=$1};1' |
|
||||
rofi -hide-scrollbar -kb-row-select 'Tab' -kb-row-tab 'Control+space' \
|
||||
-dmenu -mesg 'Tab for Autocomplete' -i -p 'Web Search')"
|
||||
;;
|
||||
-l|--logout)
|
||||
case "$(rofi -sep "|" -dmenu -i -p 'System' -width 20 -hide-scrollbar \
|
||||
-line-padding 4 -padding 20 -lines 4 <<< " Lock| Logout| Reboot| Shutdown")" in
|
||||
*Lock) i3lock-fancy ;;
|
||||
*Reboot) systemctl reboot ;;
|
||||
*Shutdown) systemctl -i poweroff ;;
|
||||
*Logout) session-logout >/dev/null 2>&1 || pkill -15 -t tty"$XDG_VTNR" Xorg ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
printf "\nOption does not exist: %s\n\n" "$arg"
|
||||
exit 2
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user