]> git.ale.wales Git - mbin.git/commitdiff
226FS.56988-Blossom
authorTu Puta Madre <chinga@tu.madre>
Sun, 28 Jun 2026 19:40:38 +0000 (13:40 -0600)
committerTu Puta Madre <chinga@tu.madre>
Sun, 28 Jun 2026 19:40:38 +0000 (13:40 -0600)
15 files changed:
code666 [new file with mode: 0755]
gram_namer [new file with mode: 0755]
gu [new file with mode: 0755]
hbk_anime [new file with mode: 0755]
miniPDF [new file with mode: 0755]
nsi [new file with mode: 0755]
onePiece [new file with mode: 0755]
piedradura [new file with mode: 0755]
roll [new file with mode: 0755]
rpatool [new file with mode: 0755]
tiempo [new file with mode: 0755]
up [new file with mode: 0755]
v [new file with mode: 0755]
vv [new file with mode: 0755]
wallpapers [new file with mode: 0755]

diff --git a/code666 b/code666
new file mode 100755 (executable)
index 0000000..b49c64b
--- /dev/null
+++ b/code666
@@ -0,0 +1,51 @@
+#!/bin/zsh
+
+# ARRAY ALFABETICO PARA SU POSTERIOR EVALUACIÓN
+minusculas=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z")
+mayusculas=("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z")
+
+# FUNCIONES INTERNAS
+getIndexMin(){
+       value=$1
+       i=0
+       while [ $i -le ${#minusculas} ]; do
+               if [[ "$minusculas[$i]" =~ "$value" ]]; then
+                       echo $i
+                       break
+               fi
+       i=$((i+1))
+       done
+}
+getIndexMay(){
+       value=$1
+       i=0
+       while [ $i -le ${#mayusculas} ]; do
+               if [[ "$mayusculas[$i]" =~ "$value" ]]; then
+                       echo $i
+                       break
+               fi
+       i=$((i+1))
+       done
+}
+
+# DECLARACIÓN DEL ARRAY LETRAS; ESTE ARRAY SERÁ USADO POR TODAS LAS ITERACIONES DEL CÓDICE
+declare -a letras
+
+# LECTURA DEL STDIN. OCUPA EL SCRIPT `nsi` QUE EN TEORÍA DEBERÍA ESTAR EN /mbin/
+entrada=$(nsi $@)
+
+# LOOP QUE AGREGA CADA LETRA DEL STRING COMO UN ELEMENTO DE UN ARRAY
+letras=($(i=0; while [ $i -lt ${#entrada} ]; do echo ${entrada:$i:1}; i=$((i+1)); done))
+
+# FUNCIÓN FINAL DONDE EL ARRAY ::Letras:: SE EVALUA LETRA POR LETRA Y SE SUMA EL VALOR DE TODAS
+declare -a suma
+for letra in ${letras[*]}; do
+       if [[ " ${minusculas[*]} " =~ " ${letra} " ]]; then
+               let suma+=$(getIndexMin $letra)
+       elif [[ " ${mayusculas[*]} " =~ " ${letra} " ]]; then
+               let suma+=$(getIndexMay $letra)
+       else
+               let suma+=0
+       fi
+done
+echo $suma
diff --git a/gram_namer b/gram_namer
new file mode 100755 (executable)
index 0000000..4cdb32a
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/zsh
+
+# OBTENER INFORMACIÓN DE STDIN Y GUARDARLA EN VARIABLES
+#      fname: nombre del archivo
+#      dname: nombre del directorio que lo contiene. Para que salga bien debe ser el nombre de usuario en instagram
+#      fext:  extensión del archivo. Porque a veces varea entre jpg, jpeg y webp
+fname=$(basename -- "$1")
+dname=${PWD##*/}
+fext="${fname##*.}"
+
+# ENCONTRAR LA FECHA DE ÚLTIMA MODIFICACIÓN EN FORMATO YY MM DD
+y=$(date -r $1 +%y)
+m=$(date -r $1 +%m)
+d=$(date -r $1 +%d)
+M=(A B C D E F G H I J K L)
+
+# GENERAR UN STRING ALEATORIO. EN ESTE CASO DE 3 DIGITOS.
+rnd3=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 3 | head -n 1)
+
+# FORMATO DE SALIDA
+#      fecha@usuario®ranomstring.ext
+# por ejemplo
+#      221IG@leex.fer21®s1f.jpg
+mv "$(pwd)/${fname}" "$(pwd)/2${y}${M[$m]}${$(([##36]d))}@${dname}®${rnd3}.${fext}"
diff --git a/gu b/gu
new file mode 100755 (executable)
index 0000000..b2ae998
--- /dev/null
+++ b/gu
@@ -0,0 +1,4 @@
+#!/bin/sh
+git add .
+git commit -a -m "$(/mbin/tiempo -s)-$(cat /etc/hostname)"
+git push
diff --git a/hbk_anime b/hbk_anime
new file mode 100755 (executable)
index 0000000..1449f96
--- /dev/null
+++ b/hbk_anime
@@ -0,0 +1,96 @@
+#!/bin/zsh
+
+# FUNCIONES INTERNAS
+interpolate() {
+    (( a = $1 + 1 ))
+    (( b = $1 + 2 ))
+    (( c = $1 + 3 ))
+    composite -blend 66 -gravity center $1 $c `printf "%04d" $a`.png
+    composite -blend 33 -gravity center $1 $c `printf "%04d" $b`.png
+}
+
+# REQUISITOS
+# falta hacer `req` y de momento necesitamos mpv , ffmpeg , flatpak , HandBrakeCLI(flatpak) , ImageMagick
+
+# MANIPULADOR DE ENTRADAS
+if [[ -z $1 || "$1" == "-h" ]]; then
+    #ayuda $0
+    mdcat /mdoc/$0.md # de momento en lo que genero `ayuda`
+    return 0
+elif [[ -z $2 ]]; then
+    echo 'ERROR: olvidaste decir cuál será el subtítulo a trabajar'
+    return 1
+fi
+
+# VERIFICAR ESPACIO SUFICIENTE PARA TRABAJAR
+reqSpace=5120000
+availSpace=$(df /tmp | awk 'NR==2 { print $4 }')
+if (( availSpace < reqSpace )); then
+    echo "ERROR: sin espacio en disco" >&2
+    exit 1
+fi
+
+# CONFIGURACIÓN INICIAL
+if [[ -n $3 ]]; then
+    NOMBRE=$3
+else
+    NOMBRE=${1%.*}
+fi
+mkdir -p /tmp/wrk/frames
+curr=$PWD
+
+# PROCESO
+#HandBrakeCLI pero desde flatpak para poder emplear el hardware, falta poner IF para si no encuentra nvidia, usar QVS en ELIF o si todo falla pues con CPU. LO IMPORTANTE es un framerate constante de 20fps.
+flatpak run --command=HandBrakeCLI fr.handbrake.ghb -i "$1" -o tmpOut.m4v -e nvenc_h265 -Y 550 -X 1280 -r 20 --cfr --auto-anamorphic --keep-display-aspect --subtitle $2 --subtitle-burned
+mv tmpOut.m4v /tmp/wrk/tmp.m4v # quirk porque flatpak no permite escribir en /tmp
+# ffmpeg Magick
+# Extraer el audio
+ffmpeg -i /tmp/wrk/tmp.m4v -vn -acodec copy /tmp/wrk/audio.aac
+# Segmentar el video de entrada a cachos de 1 minuto, ya que salen demasiadons PNGs y pesa mucho en videos largos
+ffmpeg -i /tmp/wrk/tmp.m4v -c copy -map 0 -segment_time 00:01:00 -f segment -reset_timestamps 1 /tmp/wrk/v%05d.mp4
+rm /tmp/wrk/tmp.m4v
+for vid in /tmp/wrk/*.mp4; do
+    ## Extraer todos los frames del vídeo
+    rm /tmp/wrk/frames/*
+    ffmpeg -ss 0 -i $vid -t $(mediainfo $vid --Inform="Video;%Duration%") /tmp/wrk/frames/%09d.png
+    #Seleccionar archivos png y darles nombre al frame correspondiente
+    cd /tmp/wrk/frames
+    frames=()
+    for file in *.png; do
+        echo "Creando nuevos frames $file ... "
+        printf "\033[A" # esto hace la magia de imprimir el feedback con el echo anterior. NO TENGO NI IDEA DE COMO FUNCIONA xD
+        ogframe=$(echo $file | sed 's/\.png//')
+        (( frame = 3 * $ogframe ))
+        frames+=("$frame")
+        mv $file $frame
+    done
+    ##Interpolación sencilla
+    N=90
+    for f in ${frames[@]}; do
+        ((i=i%N)); ((i++==0)) && wait
+        echo "Interpolando ... "
+        printf "\033[A"
+        (( nxt = $f + 3 ))
+        if [[ -e $nxt ]]; then
+            interpolate $f &
+        fi
+    done
+    wait
+    for f in ${frames[@]}; do
+        mv $f `printf "%04d" $f`.png
+    done
+    cd $curr
+    ffmpeg -framerate 60 -pattern_type glob -i '/tmp/wrk/frames/*.png' -c:v libsvtav1 -preset 6 ${vid%.*}.mkv
+    echo "file '${vid%.*}.mkv'" >> /tmp/wrk/list.txt
+    rm $vid
+done
+##Mezcla final
+ffmpeg -f concat -safe 0 -i /tmp/wrk/list.txt -c copy /tmp/wrk/video.mkv
+ffmpeg -i /tmp/wrk/video.mkv -i /tmp/wrk/audio.aac -c:v copy -c:a libopus -b:a 36k -ac 1 $NOMBRE.webm
+
+# LIMPIEZA
+rm -rf /tmp/wrk
+
+### NUEVO
+# % HandBrakeCLI -i *.mkv -e nvenc_h264 -Y 360 -X 640 --vfr --auto-anamorphic --keep-display-aspect -E opus -6 mono -o /home/ale/Vídeos/REAL/TV/1999-デジモンアドベンチャー/S01E39.mp4
+
diff --git a/miniPDF b/miniPDF
new file mode 100755 (executable)
index 0000000..d46a1dd
--- /dev/null
+++ b/miniPDF
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+# FUNCIONES INTERNAS
+ayuda() {
+    printf "compress_pdf - Compress PDF files using Ghostscript\n\nUsage:\n\tcompress_pdf <input.pdf> [quality]\n\nQuality options (default: screen):\n\n\tscreen    - Smallest size, good for viewing on screen\n\tebook     - Medium size, good for e-readers\n\tprinter   - Good quality for printing\n\tprepress  - Highest quality for professional printing\n\n\nExamples:\n\tcompress_pdf document.pdf\n\tcompress_pdf document.pdf ebook"
+}
+
+# VALORES POR DEFECTO
+input_file=""
+read -a array <<< "$@"
+for elem in "${array[@]}"; do
+    if [[ $elem == *.pdf ]]; then
+    input_file="$elem"
+    fi
+done
+quality="screen"
+output_file="${input_file%.*}_compressed.pdf"
+
+# OPCIONES
+while getopts ":q:o:h" opt; do
+    case "$opt" in
+        q)
+            arg="$OPTARG"
+            if [[ $arg == "screen" || $arg == "ebook" || $arg == "printer" || $arg == "prepress" ]]; then
+                quality=$arg
+            else
+                echo "Error: '$arg' no es un valor adecuado de calidad. Usa: screen, ebook, printer o prepress"
+                exit 1
+            fi
+            ;;
+        o)
+            arg="$OPTARG"
+            if [[ -n "$arg" && "$arg"  != ${input_file%.*} ]]; then
+                output_file="$arg.pdf"
+            fi
+            ;;
+        h)
+            echo "Usage: $(basename $0) [-a] [-b] [-c arg]"
+                  ayuda
+            exit 0
+            ;;
+        :)  # falta el argumento requerido
+            echo "Error: la opción -$OPTARG necesita un valor." >&2
+            exit 1
+            ;;
+        ?)
+          echo -e "Invalid command option.\nUsage: $(basename $0) [-a] [-b] [-c arg]"
+          exit 1
+          ;;
+    esac
+done
+shift $((OPTIND - 1))
+
+# VERIFICACIÓN
+if [[ ! -f "$input_file" ]]; then
+    echo "Error: no existe $input_file"
+    exit 1
+fi
+mime=$(file -b --mime-type $input_file)
+if [[ $mime != "application/pdf" ]]; then
+    echo "Error: $mime no es un PDF"
+    exit 1
+fi
+echo "$mime ACEPTADO:"
+
+echo "Compressing '$input_file' (quality: $quality) -> '$output_file'"
+
+gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/"$quality" -dNOPAUSE -dQUIET -dBATCH -dBufferSpace=2000000000 -dNumRenderingThreads=8 -sOutputFile="$output_file" "$input_file"
diff --git a/nsi b/nsi
new file mode 100755 (executable)
index 0000000..d2ffe3a
--- /dev/null
+++ b/nsi
@@ -0,0 +1,3 @@
+#!/bin/zsh
+
+echo $@ | tr -d '[:space:]'
diff --git a/onePiece b/onePiece
new file mode 100755 (executable)
index 0000000..439773b
--- /dev/null
+++ b/onePiece
@@ -0,0 +1,34 @@
+#!/bin/zsh
+
+# REVISAR SI SE EJECUTA COMO root
+if [[ $(id -u) != 0 ]]; then
+   echo "The script need to be run as root." >&2
+   exit 1
+fi
+
+# EVALUA EL FORMATO DEL DIRECTORIO /home/nami/. SI ES nfs SIGNIFICA QUE YA ESTA MONTADO POR LO QUE NO SE VUELVE A MONTAR PARA EVITAR CONFLICTOS
+conn=$(stat -f -L -c %T /home/nami)
+echo $conn
+if [[ $conn == "nfs" ]]; then
+    echo "nami ya está conectada" >&2
+    exit 1
+else
+    echo "montando nami"
+    mount 192.168.0.100:/mnt/vault/media /home/nami &&
+    sleep 3
+    echo "montando TV"
+    mount 192.168.0.100:/mnt/vault/tv /home/nami/TV &&
+    sleep 1
+    echo "montando CINE"
+    mount 192.168.0.100:/mnt/vault/cine /home/nami/CINE &&
+    sleep 1
+    echo "montando MSK"
+    mount 192.168.0.100:/mnt/vault/msk /home/nami/MSK &&
+    sleep 1
+    echo "montando GAG"
+    mount 192.168.0.100:/mnt/vault/gag /home/nami/GAG &&
+    sleep 1
+    echo "montando PORK"
+    mount 192.168.0.100:/mnt/vault/pork /home/nami/PORK &&
+    echo ".\n.\n.\n\t¡Hecho!"
+fi
diff --git a/piedradura b/piedradura
new file mode 100755 (executable)
index 0000000..f54f8fe
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/zsh
+
+# REVISAR SI SE EJECUTA COMO root
+if [[ $(id -u) != 0 ]]; then
+   echo "The script need to be run as root." >&2
+   exit 1
+fi
+
+# EVALUA EL FORMATO DEL DIRECTORIO /home/pebbles/. SI ES nfs SIGNIFICA QUE YA ESTA MONTADO POR LO QUE NO SE VUELVE A MONTAR PARA EVITAR CONFLICTOS
+conn=$(stat -f -L -c %T /home/pebbles)
+echo $conn
+if [[ $conn == "nfs" ]]; then
+    echo "pebbles ya está conectada" >&2
+    exit 1
+else
+    echo "montando pebbles"
+    mount 192.168.0.99:/root/Downloads /home/pebbles
+    sleep 3
+    echo ".\n.\n.\n\t¡Hecho!"
+fi
diff --git a/roll b/roll
new file mode 100755 (executable)
index 0000000..db68b61
--- /dev/null
+++ b/roll
@@ -0,0 +1,213 @@
+#! /bin/bash
+
+# print instructions if no arguments given
+if [ $# -eq 0 ] || [ $1 == '-h' ]
+then
+    printf "
+roll v1.1 by Rodney DuPlessis
+
+roll is a command line script written in bash to roll arbitrary numbers of arbitrarily-sided dice.
+roll also allows for a modifier and to set the minimum accepted value of each individual roll.
+
+----
+
+The basic syntax is:
+
+roll [#]d[sides]
+
+Where:
+[#] is the number of dice you want to roll
+[sides] is the number of sides of the dice you want to roll
+
+----
+
+Optional:
+
+
+You may add a modifier to add or subtract from the final result:
+
+roll [#]d[sides][+/-][mod]
+
+Where:
+[+/-] is either a plus (+) or minus (-) sign
+[mod] is a modifier to add to the result
+
+
+You may also use the \"-min\" flag to set a minimum outcome for each individual die roll:
+
+roll [#]d[sides] -min [min#]
+
+Where:
+[min#] sets a minimum to round up to (any individual die that rolls less than this number will be rounded up)
+Note: don't forget to add a space before and after the \"-min\" flag.
+
+----
+
+Example usage:
+
+roll 3d15
+
+will roll 3 15-sided dice
+
+
+roll 5d6+10
+
+will roll 5 6-sided dice and add 10 to the total result
+
+
+roll 7d203-11
+
+will roll 7 203-sided dice and subtract 11 from the total result
+
+
+roll 6d10+12 -min 6
+
+will roll 6 10-sided dice, rounding up to 6 any individual die that results in less than 6, and then add 12 to the total result.
+
+"
+    exit 1
+fi
+
+if [ $# -eq 2 ] || [ $# -gt 3 ]
+then
+    printf "
+Syntax Error: Wrong number of arguments
+
+Type 'roll -h' to see correct syntax
+
+"
+    exit 2
+fi
+
+
+# parse the argument
+NUMDICE=$(echo $1 | sed 's/d.*//')
+
+# if no number of dice given, default to 1
+if [[ $NUMDICE == '' ]]
+then
+    NUMDICE=1
+fi
+
+# check for modifier
+if [ $(echo $1 | grep '+') ] # check for positive modifier
+then
+    FACES=$(echo $1 | sed -e 's/.*d\(.*\)+.*/\1/')
+    MODIFIER=$(echo $1 | sed 's/.*+/0+/' | bc)
+
+else
+    if [ $(echo $1 | grep '-') ] # check for negative modifier
+    then
+        FACES=$(echo $1 | sed -e 's/.*d\(.*\)-.*/\1/')
+        MODIFIER=$(echo $1 | sed 's/.*-/0-/' | bc)
+    else # If there is no modifier
+        FACES=$(echo $1 | sed -e 's/.*d\(.*\)/\1/')
+        MODIFIER=0
+    fi
+fi
+
+if [ $# -eq 3 ] # check if there are extra arguments
+then
+    if [ $2 = "-min" ] #  check that the flag is "-min" (accept no others)
+    then
+        MIN=$3
+    else
+        printf "
+Syntax Error: $2 is not a valid flag
+
+Type 'roll -h' to see correct syntax
+"
+        exit 1
+    fi
+else # if there is no minimum, set it to 0
+    MIN=0
+fi
+
+# int number regex to check args against
+INT='^-?[0-9]+$'
+# check if args are integer numbers
+if ! [[ $NUMDICE =~ $INT ]] || ! [[ $FACES =~ $INT ]] || ! [[ $MODIFIER =~ $INT ]] || ! [[ $MIN =~ $INT ]]
+then
+    printf "
+Syntax Error: arguments must be integer (whole) numbers.
+
+Type 'roll -h' to see correct syntax
+
+"
+    exit 1
+fi
+
+if [ $FACES -eq 0 ]
+then
+    printf "
+Syntax Error: Dice cannot have 0 faces... That would break reality.
+
+Type 'roll -h' to see correct syntax
+
+"
+    exit 1
+fi
+
+if [ $FACES -lt 0 ]
+then
+    printf "
+Syntax Error: Seriously? You want me to roll dice with a negative number of faces? Excuse me while I alter the laws of physics.
+
+Type 'roll -h' to see correct syntax
+
+"
+    exit 1
+fi
+
+if [ $NUMDICE -eq 0 ]
+then
+    printf "
+You roll no dice. I award you no points... and may God have mercy on your soul.
+
+"
+    exit 1
+fi
+
+if [ $NUMDICE -lt 0 ]
+then
+    printf "
+Syntax Error: I cannot roll a negative number of dice. Are you asking me to unroll dice? brb while I wage war against entropy...
+
+Type 'roll -h' to see correct syntax
+
+"
+    exit 1
+fi
+
+# Set the total to zero before rolling
+RESULT=0
+TOTALROUND=0
+
+# do the rolls
+for i in $(eval echo "{1..$NUMDICE}")
+do
+    ROUNDED=""
+    ROLL=$(( ( RANDOM % $FACES ) + 1 ))
+    if [ $ROLL -lt $MIN ]
+    then
+        ROUNDAMT=$(($MIN - $ROLL))
+        let TOTALROUND+=$ROUNDAMT
+        ROUNDED=" (Rounded up from $ROLL)"
+        ROLL=$MIN
+    fi
+    echo "roll "$i": "$ROLL $ROUNDED
+    let RESULT+=$ROLL
+
+done
+
+echo
+
+# add optional modifier
+if [ $MODIFIER -ne 0 ]
+then
+    echo "Rolled total:" $RESULT
+    let RESULT+=$MODIFIER
+    printf '%s: %+i \n' "Modifier" $MODIFIER
+fi
+
+echo "TOTAL:" $RESULT
diff --git a/rpatool b/rpatool
new file mode 100755 (executable)
index 0000000..58b2f8d
--- /dev/null
+++ b/rpatool
@@ -0,0 +1,468 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+import sys
+import os
+import codecs
+import pickle
+import errno
+import random
+try:
+    import pickle5 as pickle
+except:
+    import pickle
+    if sys.version_info < (3, 8):
+        print('warning: pickle5 module could not be loaded and Python version is < 3.8,', file=sys.stderr)
+        print('         newer Ren\'Py games may fail to unpack!', file=sys.stderr)
+        if sys.version_info >= (3, 5):
+            print('         if this occurs, fix it by installing pickle5:', file=sys.stderr)
+            print('             {} -m pip install pickle5'.format(sys.executable), file=sys.stderr)
+        else:
+            print('         if this occurs, please upgrade to a newer Python (>= 3.5).', file=sys.stderr)
+        print(file=sys.stderr)
+
+
+if sys.version_info[0] >= 3:
+    def _unicode(text):
+        return text
+
+    def _printable(text):
+        return text
+
+    def _unmangle(data):
+        if type(data) == bytes:
+            return data
+        else:
+            return data.encode('latin1')
+
+    def _unpickle(data):
+        # Specify latin1 encoding to prevent raw byte values from causing an ASCII decode error.
+        return pickle.loads(data, encoding='latin1')
+elif sys.version_info[0] == 2:
+    def _unicode(text):
+        if isinstance(text, unicode):
+            return text
+        return text.decode('utf-8')
+
+    def _printable(text):
+        return text.encode('utf-8')
+
+    def _unmangle(data):
+        return data
+
+    def _unpickle(data):
+        return pickle.loads(data)
+
+class RenPyArchive:
+    file = None
+    handle = None
+
+    files = {}
+    indexes = {}
+
+    version = None
+    padlength = 0
+    key = None
+    verbose = False
+
+    RPA2_MAGIC = 'RPA-2.0 '
+    RPA3_MAGIC = 'RPA-3.0 '
+    RPA3_2_MAGIC = 'RPA-3.2 '
+
+    # For backward compatibility, otherwise Python3-packed archives won't be read by Python2
+    PICKLE_PROTOCOL = 2
+
+    def __init__(self, file = None, version = 3, padlength = 0, key = 0xDEADBEEF, verbose = False):
+        self.padlength = padlength
+        self.key = key
+        self.verbose = verbose
+
+        if file is not None:
+            self.load(file)
+        else:
+            self.version = version
+
+    def __del__(self):
+        if self.handle is not None:
+            self.handle.close()
+
+    # Determine archive version.
+    def get_version(self):
+        self.handle.seek(0)
+        magic = self.handle.readline().decode('utf-8')
+
+        if magic.startswith(self.RPA3_2_MAGIC):
+            return 3.2
+        elif magic.startswith(self.RPA3_MAGIC):
+            return 3
+        elif magic.startswith(self.RPA2_MAGIC):
+            return 2
+        elif self.file.endswith('.rpi'):
+            return 1
+
+        raise ValueError('the given file is not a valid Ren\'Py archive, or an unsupported version')
+
+    # Extract file indexes from opened archive.
+    def extract_indexes(self):
+        self.handle.seek(0)
+        indexes = None
+
+        if self.version in [2, 3, 3.2]:
+            # Fetch metadata.
+            metadata = self.handle.readline()
+            vals = metadata.split()
+            offset = int(vals[1], 16)
+            if self.version == 3:
+                self.key = 0
+                for subkey in vals[2:]:
+                    self.key ^= int(subkey, 16)
+            elif self.version == 3.2:
+                self.key = 0
+                for subkey in vals[3:]:
+                    self.key ^= int(subkey, 16)
+
+            # Load in indexes.
+            self.handle.seek(offset)
+            contents = codecs.decode(self.handle.read(), 'zlib')
+            indexes = _unpickle(contents)
+
+            # Deobfuscate indexes.
+            if self.version in [3, 3.2]:
+                obfuscated_indexes = indexes
+                indexes = {}
+                for i in obfuscated_indexes.keys():
+                    if len(obfuscated_indexes[i][0]) == 2:
+                        indexes[i] = [ (offset ^ self.key, length ^ self.key) for offset, length in obfuscated_indexes[i] ]
+                    else:
+                        indexes[i] = [ (offset ^ self.key, length ^ self.key, prefix) for offset, length, prefix in obfuscated_indexes[i] ]
+        else:
+            indexes = pickle.loads(codecs.decode(self.handle.read(), 'zlib'))
+
+        return indexes
+
+    # Generate pseudorandom padding (for whatever reason).
+    def generate_padding(self):
+        length = random.randint(1, self.padlength)
+
+        padding = ''
+        while length > 0:
+            padding += chr(random.randint(1, 255))
+            length -= 1
+
+        return bytes(padding, 'utf-8')
+
+    # Converts a filename to archive format.
+    def convert_filename(self, filename):
+        (drive, filename) = os.path.splitdrive(os.path.normpath(filename).replace(os.sep, '/'))
+        return filename
+
+    # Debug (verbose) messages.
+    def verbose_print(self, message):
+        if self.verbose:
+            print(message)
+
+
+    # List files in archive and current internal storage.
+    def list(self):
+        return list(self.indexes.keys()) + list(self.files.keys())
+
+    # Check if a file exists in the archive.
+    def has_file(self, filename):
+        filename = _unicode(filename)
+        return filename in self.indexes.keys() or filename in self.files.keys()
+
+    # Read file from archive or internal storage.
+    def read(self, filename):
+        filename = self.convert_filename(_unicode(filename))
+
+        # Check if the file exists in our indexes.
+        if filename not in self.files and filename not in self.indexes:
+            raise IOError(errno.ENOENT, 'the requested file {0} does not exist in the given Ren\'Py archive'.format(
+                _printable(filename)))
+
+        # If it's in our opened archive index, and our archive handle isn't valid, something is obviously wrong.
+        if filename not in self.files and filename in self.indexes and self.handle is None:
+            raise IOError(errno.ENOENT, 'the requested file {0} does not exist in the given Ren\'Py archive'.format(
+                _printable(filename)))
+
+        # Check our simplified internal indexes first, in case someone wants to read a file they added before without saving, for some unholy reason.
+        if filename in self.files:
+            self.verbose_print('Reading file {0} from internal storage...'.format(_printable(filename)))
+            return self.files[filename]
+        # We need to read the file from our open archive.
+        else:
+            # Read offset and length, seek to the offset and read the file contents.
+            if len(self.indexes[filename][0]) == 3:
+                (offset, length, prefix) = self.indexes[filename][0]
+            else:
+                (offset, length) = self.indexes[filename][0]
+                prefix = ''
+
+            self.verbose_print('Reading file {0} from data file {1}... (offset = {2}, length = {3} bytes)'.format(
+                _printable(filename), self.file, offset, length))
+            self.handle.seek(offset)
+            return _unmangle(prefix) + self.handle.read(length - len(prefix))
+
+    # Modify a file in archive or internal storage.
+    def change(self, filename, contents):
+        filename = _unicode(filename)
+
+        # Our 'change' is basically removing the file from our indexes first, and then re-adding it.
+        self.remove(filename)
+        self.add(filename, contents)
+
+    # Add a file to the internal storage.
+    def add(self, filename, contents):
+        filename = self.convert_filename(_unicode(filename))
+        if filename in self.files or filename in self.indexes:
+            raise ValueError('file {0} already exists in archive'.format(_printable(filename)))
+
+        self.verbose_print('Adding file {0} to archive... (length = {1} bytes)'.format(
+            _printable(filename), len(contents)))
+        self.files[filename] = contents
+
+    # Remove a file from archive or internal storage.
+    def remove(self, filename):
+        filename = _unicode(filename)
+        if filename in self.files:
+            self.verbose_print('Removing file {0} from internal storage...'.format(_printable(filename)))
+            del self.files[filename]
+        elif filename in self.indexes:
+            self.verbose_print('Removing file {0} from archive indexes...'.format(_printable(filename)))
+            del self.indexes[filename]
+        else:
+            raise IOError(errno.ENOENT, 'the requested file {0} does not exist in this archive'.format(_printable(filename)))
+
+    # Load archive.
+    def load(self, filename):
+        filename = _unicode(filename)
+
+        if self.handle is not None:
+            self.handle.close()
+        self.file = filename
+        self.files = {}
+        self.handle = open(self.file, 'rb')
+        self.version = self.get_version()
+        self.indexes = self.extract_indexes()
+
+    # Save current state into a new file, merging archive and internal storage, rebuilding indexes, and optionally saving in another format version.
+    def save(self, filename = None):
+        filename = _unicode(filename)
+
+        if filename is None:
+            filename = self.file
+        if filename is None:
+            raise ValueError('no target file found for saving archive')
+        if self.version != 2 and self.version != 3:
+            raise ValueError('saving is only supported for version 2 and 3 archives')
+
+        self.verbose_print('Rebuilding archive index...')
+        # Fill our own files structure with the files added or changed in this session.
+        files = self.files
+        # First, read files from the current archive into our files structure.
+        for file in list(self.indexes.keys()):
+            content = self.read(file)
+            # Remove from indexes array once read, add to our own array.
+            del self.indexes[file]
+            files[file] = content
+
+        # Predict header length, we'll write that one last.
+        offset = 0
+        if self.version == 3:
+            offset = 34
+        elif self.version == 2:
+            offset = 25
+        archive = open(filename, 'wb')
+        archive.seek(offset)
+
+        # Build our own indexes while writing files to the archive.
+        indexes = {}
+        self.verbose_print('Writing files to archive file...')
+        for file, content in files.items():
+            # Generate random padding, for whatever reason.
+            if self.padlength > 0:
+                padding = self.generate_padding()
+                archive.write(padding)
+                offset += len(padding)
+
+            archive.write(content)
+            # Update index.
+            if self.version == 3:
+                indexes[file] = [ (offset ^ self.key, len(content) ^ self.key) ]
+            elif self.version == 2:
+                indexes[file] = [ (offset, len(content)) ]
+            offset += len(content)
+
+        # Write the indexes.
+        self.verbose_print('Writing archive index to archive file...')
+        archive.write(codecs.encode(pickle.dumps(indexes, self.PICKLE_PROTOCOL), 'zlib'))
+        # Now write the header.
+        self.verbose_print('Writing header to archive file... (version = RPAv{0})'.format(self.version))
+        archive.seek(0)
+        if self.version == 3:
+            archive.write(codecs.encode('{}{:016x} {:08x}\n'.format(self.RPA3_MAGIC, offset, self.key)))
+        else:
+            archive.write(codecs.encode('{}{:016x}\n'.format(self.RPA2_MAGIC, offset)))
+        # We're done, close it.
+        archive.close()
+
+        # Reload the file in our inner database.
+        self.load(filename)
+
+if __name__ == "__main__":
+    import argparse
+
+    parser = argparse.ArgumentParser(
+        description='A tool for working with Ren\'Py archive files.',
+        epilog='The FILE argument can optionally be in ARCHIVE=REAL format, mapping a file in the archive file system to a file on your real file system. An example of this: rpatool -x test.rpa script.rpyc=/home/foo/test.rpyc',
+        add_help=False)
+
+    parser.add_argument('archive', metavar='ARCHIVE', help='The Ren\'py archive file to operate on.')
+    parser.add_argument('files', metavar='FILE', nargs='*', action='append', help='Zero or more files to operate on.')
+
+    parser.add_argument('-l', '--list', action='store_true', help='List files in archive ARCHIVE.')
+    parser.add_argument('-x', '--extract', action='store_true', help='Extract FILEs from ARCHIVE.')
+    parser.add_argument('-c', '--create', action='store_true', help='Creative ARCHIVE from FILEs.')
+    parser.add_argument('-d', '--delete', action='store_true', help='Delete FILEs from ARCHIVE.')
+    parser.add_argument('-a', '--append', action='store_true', help='Append FILEs to ARCHIVE.')
+
+    parser.add_argument('-2', '--two', action='store_true', help='Use the RPAv2 format for creating/appending to archives.')
+    parser.add_argument('-3', '--three', action='store_true', help='Use the RPAv3 format for creating/appending to archives (default).')
+
+    parser.add_argument('-k', '--key', metavar='KEY', help='The obfuscation key used for creating RPAv3 archives, in hexadecimal (default: 0xDEADBEEF).')
+    parser.add_argument('-p', '--padding', metavar='COUNT', help='The maximum number of bytes of padding to add between files (default: 0).')
+    parser.add_argument('-o', '--outfile', help='An alternative output archive file when appending to or deleting from archives, or output directory when extracting.')
+
+    parser.add_argument('-h', '--help', action='help', help='Print this help and exit.')
+    parser.add_argument('-v', '--verbose', action='store_true', help='Be a bit more verbose while performing operations.')
+    parser.add_argument('-V', '--version', action='version', version='rpatool v0.8', help='Show version information.')
+    arguments = parser.parse_args()
+
+    # Determine RPA version.
+    if arguments.two:
+        version = 2
+    else:
+        version = 3
+
+    # Determine RPAv3 key.
+    if 'key' in arguments and arguments.key is not None:
+        key = int(arguments.key, 16)
+    else:
+        key = 0xDEADBEEF
+
+    # Determine padding bytes.
+    if 'padding' in arguments and arguments.padding is not None:
+        padding = int(arguments.padding)
+    else:
+        padding = 0
+
+    # Determine output file/directory and input archive
+    if arguments.create:
+        archive = None
+        output = _unicode(arguments.archive)
+    else:
+        archive = _unicode(arguments.archive)
+        if 'outfile' in arguments and arguments.outfile is not None:
+            output = _unicode(arguments.outfile)
+        else:
+            # Default output directory for extraction is the current directory.
+            if arguments.extract:
+                output = '.'
+            else:
+                output = _unicode(arguments.archive)
+
+    # Normalize files.
+    if len(arguments.files) > 0 and isinstance(arguments.files[0], list):
+        arguments.files = arguments.files[0]
+
+    try:
+        archive = RenPyArchive(archive, padlength=padding, key=key, version=version, verbose=arguments.verbose)
+    except IOError as e:
+        print('Could not open archive file {0} for reading: {1}'.format(archive, e), file=sys.stderr)
+        sys.exit(1)
+
+    if arguments.create or arguments.append:
+        # We need this seperate function to recursively process directories.
+        def add_file(filename):
+            # If the archive path differs from the actual file path, as given in the argument,
+            # extract the archive path and actual file path.
+            if filename.find('=') != -1:
+                (outfile, filename) = filename.split('=', 2)
+            else:
+                outfile = filename
+
+            if os.path.isdir(filename):
+                for file in os.listdir(filename):
+                    # We need to do this in order to maintain a possible ARCHIVE=REAL mapping between directories.
+                    add_file(outfile + os.sep + file + '=' + filename + os.sep + file)
+            else:
+                try:
+                    with open(filename, 'rb') as file:
+                        archive.add(outfile, file.read())
+                except Exception as e:
+                    print('Could not add file {0} to archive: {1}'.format(filename, e), file=sys.stderr)
+
+        # Iterate over the given files to add to archive.
+        for filename in arguments.files:
+            add_file(_unicode(filename))
+
+        # Set version for saving, and save.
+        archive.version = version
+        try:
+            archive.save(output)
+        except Exception as e:
+            print('Could not save archive file: {0}'.format(e), file=sys.stderr)
+    elif arguments.delete:
+        # Iterate over the given files to delete from the archive.
+        for filename in arguments.files:
+            try:
+                archive.remove(filename)
+            except Exception as e:
+                print('Could not delete file {0} from archive: {1}'.format(filename, e), file=sys.stderr)
+
+        # Set version for saving, and save.
+        archive.version = version
+        try:
+            archive.save(output)
+        except Exception as e:
+            print('Could not save archive file: {0}'.format(e), file=sys.stderr)
+    elif arguments.extract:
+        # Either extract the given files, or all files if no files are given.
+        if len(arguments.files) > 0:
+            files = arguments.files
+        else:
+            files = archive.list()
+
+        # Create output directory if not present.
+        if not os.path.exists(output):
+            os.makedirs(output)
+
+        # Iterate over files to extract.
+        for filename in files:
+            if filename.find('=') != -1:
+                (outfile, filename) = filename.split('=', 2)
+            else:
+                outfile = filename
+
+            try:
+                contents = archive.read(filename)
+
+                # Create output directory for file if not present.
+                if not os.path.exists(os.path.dirname(os.path.join(output, outfile))):
+                    os.makedirs(os.path.dirname(os.path.join(output, outfile)))
+
+                with open(os.path.join(output, outfile), 'wb') as file:
+                    file.write(contents)
+            except Exception as e:
+                print('Could not extract file {0} from archive: {1}'.format(filename, e), file=sys.stderr)
+    elif arguments.list:
+        # Print the sorted file list.
+        list = archive.list()
+        list.sort()
+        for file in list:
+            print(file)
+    else:
+        print('No operation given :(')
+        print('Use {0} --help for usage details.'.format(sys.argv[0]))
+
diff --git a/tiempo b/tiempo
new file mode 100755 (executable)
index 0000000..bcb2f2b
--- /dev/null
+++ b/tiempo
@@ -0,0 +1,71 @@
+#!/bin/zsh
+
+# FUNCIONES INTERNAS
+fecha() {
+    y=$(date +%y)
+    m=$(date +%m)
+    d=$(date +%d)
+    M=(A B C D E F G H I J K L)
+    echo "2${y}${M[$m]}${$(([##36]d))}"
+}
+hora() {
+    (( mid = 0.5 / 43200 ))
+    h=$(date +%H)
+    n=$(date +%M)
+    s=$(date +%S)
+    sec=$(( ($h * 3600) + ($n * 60) + $s ))
+    dec=$(( $sec * $mid ))
+    case "$1" in
+        frac)
+            echo $dec | cut -c 2-7
+            ;;
+        *)
+            (( out = $dec * 10))
+            echo $out | cut -c -6
+            ;;
+    esac
+}
+cuando() {
+    y=$3
+    ms=$2
+    d=$1
+    mes=(ene feb mar abr may jun jul ago sep oct nov dic)
+    M=(A B C D E F G H I J K L)
+    m=$mes[(I)$ms]
+    echo "${y:0:1}${y:2:2}${M[$m]}${$(([##36]d))}"
+}
+ayuda() {
+    echo "la madre esta se emplea así"
+}
+
+# MAIN
+while getopts ":cdfhsto" arg; do
+    case $arg in
+        h)
+            ayuda
+            exit;;
+        c)
+            cuando $2 $3 $4
+                ## formato de entrada
+                ## cuando 15 ago 2017
+                #> 217HF
+            exit;;
+        d|dia|f|fecha)
+            fecha
+            exit;;
+        o|hora)
+            hora
+            exit;;
+        s|stamp|t|timestamp)
+            o=$(fecha)
+            ut=$(hora frac)
+            echo $o$ut
+            exit;;
+        ?) #Invalid otion
+            echo "Error: Opción invalida"
+            exit 2;;
+    esac
+done
+
+echo "Error: Sin argumento valido"
+exit 2
diff --git a/up b/up
new file mode 100755 (executable)
index 0000000..2e7705b
--- /dev/null
+++ b/up
@@ -0,0 +1,78 @@
+#!/bin/zsh
+
+# DEPENDENCIAS
+. $HOME/.config/zsh/functions.zsh
+deps=(
+    #bin,path,source
+    realesrgan-ncnn-vulkan,/mbin/src/ncnn,https://github.com/xinntao/Real-ESRGAN-ncnn-vulkan
+    waifu2x-ncnn-vulkan,/mbin/src/ncnn,https://github.com/nihui/waifu2x-ncnn-vulkan
+    libavif.so,/usr/lib,https://github.com/AOMediaCodec/libavif
+    composite,/sbin,https://github.com/ImageMagick/ImageMagick
+    identify,/sbin,https://github.com/ImageMagick/ImageMagick
+    convert,/sbin,https://github.com/ImageMagick/ImageMagick
+    )
+# xbps-install ImageMagick libavif
+deps $deps
+
+# VARIABLES
+rsg="/mbin/src/ncnn/realesrgan-ncnn-vulkan"
+wfu="/mbin/src/ncnn/waifu2x-ncnn-vulkan"
+mkdir -p /tmp/wrk
+wrk="/tmp/wrk"
+
+# ARGUMENTOS
+if [[ -z $1 ]]; then
+    ayuda $0
+    exit
+fi
+while getopts ":hi:n:f:" arg; do
+    case $arg in
+        h)
+            ayuda $0
+            exit;;
+        i)
+            input="$OPTARG"
+            ;;
+        n)
+            nombre="$OPTARG"
+            ;;
+        f)
+            formato="$OPTARG"
+            ;;
+        ?)
+            echo "ERROR: Opción invalida"
+            exit 2;;
+    esac
+done
+
+# VERIFICAR
+if [[ -z $input ]]; then
+    echo "ERROR: Sin archivo de entrada especificado."
+    exit 2
+fi
+
+# DEFAULTS
+declare -A default
+default[nombre]="${input%.*}"
+default[formato]="avif"
+if [[ $(identify -format '%[fx:(h>w)]' $input) -eq 1 ]]; then
+    default[tamaño]="800x1280"
+else
+    default[tamaño]="1280x800"
+fi
+# CAMBIAR POR VALORES DE USUARIO
+for key value in ${(kv)default}; do
+    k=\$$key
+    if [[ ! -z ${(e)k} ]]; then
+        default[$key]=${(e)k}
+    fi
+done
+
+# MAIN
+$rsg -i $input -n realesrgan-x4plus -o /tmp/wrk/or.png
+$wfu -i $input -n 2 -s 4 -o /tmp/wrk/ow.png
+composite -blend 50 -gravity center /tmp/wrk/or.png /tmp/wrk/ow.png /tmp/wrk/out.png
+convert -strip -interlace Plane -gaussian-blur 0.05 -quality 85% -resize $default[tamaño] /tmp/wrk/out.png $default[nombre].$default[formato]
+
+# LIMPIEZA
+rm -rf /tmp/wrk
diff --git a/v b/v
new file mode 100755 (executable)
index 0000000..ba2499f
--- /dev/null
+++ b/v
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+handle() {
+       if [ -f "$1" ];
+       then
+               highlight "$1" -O ansi --force
+       elif [ -d "$1" ];
+       then
+               tree "$1" -La 1
+       fi
+}
+
+# Calculate where the image should be placed on the screen.
+cols=`expr $(tput cols) - 4`
+lins=`expr $(tput lines) - 4`
+img="timg -g${cols}x${lins} -C "
+
+case "$1" in
+    *.bmp|*.svg|*.png|*.jpg|*.jpeg|*.mkv|*.mp4|*.m4v) $img "$1";;
+    *.md) mdcat "$1";;
+    *.tar.gz) tar -ztvf "$1";;
+    *.tar.bz2) tar -jtvf "$1";;
+    *.tar) tar -tvf "$1";;
+    *.rar) unrar l "$1";;
+    *.7z|*.zip) 7z l "$1";;
+    #*.html|*.xml) w3m -dump "$1";;
+    #*.zsh*|*.bash*|*.git*) pistol "$1";;
+       *.torrent) transmission-show "$1";;
+       *.iso) iso-info --no-header -l "$1";;
+       *.csv) cat "$1" | sed s/,/\\n/g ;;
+       *.pdf) #requiere poppler poppler-utils
+               CACHE=$(mktemp /tmp/thumbcache.XXXXX)
+               pdftoppm -png -singlefile "$1" "$CACHE"
+               $img "$CACHE.png"
+               ;;
+       *.epub)
+               CACHE=$(mktemp /tmp/thumbcache.XXXXX) #requiere gnome-epub-thumbnailer
+               gnome-epub-thumbnailer "$1" "$CACHE"
+               $img "$CACHE"
+               ;;
+       *.wav|*.mp3|*.flac|*.m4a|*.wma|*.ape|*.ac3|*.og[agx]|*.spx|*.opus|*.as[fx]|*.flac) mediainfo "$1";;
+       *.avi|*.mp4|*.wmv|*.dat|*.3gp|*.ogv|*.mkv|*.mpg|*.mpeg|*.vob|*.fl[icv]|*.m2v|*.mov|*.webm|*.ts|*.mts|*.m4v|*.r[am]|*.qt|*.divx) $img "$1";;
+    *) handle "$1" ;;
+esac
+
diff --git a/vv b/vv
new file mode 100755 (executable)
index 0000000..42a4957
--- /dev/null
+++ b/vv
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+set -eu
+
+# Lists the current directory's files in Vim, so you can edit it and save to rename them
+# USAGE: vimv [file1 file2]
+# https://github.com/thameera/vimv
+
+declare -r FILENAMES_FILE=$(mktemp "${TMPDIR:-/tmp}/vimv.XXX")
+
+trap '{ rm -f "${FILENAMES_FILE}" ; }' EXIT
+
+if [ $# -ne 0 ]; then
+    src=( "$@" )
+else
+    IFS=$'\r\n' GLOBIGNORE='*' command eval 'src=($(ls))'
+fi
+
+for ((i=0;i<${#src[@]};++i)); do
+    echo "${src[i]}" >> "${FILENAMES_FILE}"
+done
+
+${EDITOR:-vim} "${FILENAMES_FILE}"
+
+IFS=$'\r\n' GLOBIGNORE='*' command eval 'dest=($(cat "${FILENAMES_FILE}"))'
+
+if (( ${#src[@]} != ${#dest[@]} )); then
+    echo "WARN: Number of files changed. Did you delete a line by accident? Aborting.." >&2
+    exit 1
+fi
+
+declare -i count=0
+for ((i=0;i<${#src[@]};++i)); do
+    if [ "${src[i]}" != "${dest[i]}" ]; then
+        mkdir -p "$(dirname "${dest[i]}")"
+        if git ls-files --error-unmatch "${src[i]}" > /dev/null 2>&1; then
+            git mv "${src[i]}" "${dest[i]}"
+        else
+            mv "${src[i]}" "${dest[i]}"
+        fi
+        ((++count))
+    fi
+done
+
+echo "$count" files renamed.
diff --git a/wallpapers b/wallpapers
new file mode 100755 (executable)
index 0000000..a19d95f
--- /dev/null
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+w2160=$(ls $HOME/.bkg/2160x3840 | shuf -n 1)
+w1080=$(ls $HOME/.bkg/1080x2560 | shuf -n 1)
+w1024=$(ls $HOME/.bkg/1024x768 | shuf -n 1)
+w1366=$(ls $HOME/.bkg/1366x768 | shuf -n 1)
+
+cp $HOME/.bkg/2160x3840/$w2160 $HOME/.w2160.jpg
+cp $HOME/.bkg/1080x2560/$w1080 $HOME/.w1080.jpg
+cp $HOME/.bkg/1024x768/$w1024 $HOME/.w1024.jpg
+cp $HOME/.bkg/1366x768/$w1366 $HOME/.w1366.jpg
+
+#feh --bg-fill $HOME/.w2160.jpg $HOME/.w1080.jpg $HOME/.w1366.jpg $HOME/.w1024.jpg
+feh --bg-fill $HOME/.w2160.jpg $HOME/.w1080.jpg $HOME/.w1024.jpg