commit abac18fd7911e089915e196d36a320f809a8c6a8
Author: Charles Baptista <charles@charlesbaptista.com>
Date: Mon, 22 Jun 2020 23:24:28 -0400
Initial commit
Diffstat:
39 files changed, 2354 insertions(+), 0 deletions(-)
diff --git a/dotfiles.html b/dotfiles.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | dotfiles</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <b><a href="./dotfiles.html">dotfiles</a></b>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>dotfiles</h3>
+ <p>My config files for software I use. You're welcome to them, if it pleases you:</p>
+ <a href="./dotfiles/i3/config">i3</a><br>
+ <a href="./dotfiles/i3status/config">i3status</a><br>
+ <a href="./dotfiles/st/config.h">st</a><br>
+ <a href="./dotfiles/.vimrc">vim</a><br>
+</div>
+
+</body>
+</html>
diff --git a/dotfiles/.bashrc b/dotfiles/.bashrc
@@ -0,0 +1,13 @@
+#
+# ~/.bashrc
+#
+
+# If not running interactively, don't do anything
+
+[[ $- != *i* ]] && return
+
+alias ls='ls --color=auto'
+alias wifiscan='sudo iw dev wlp2s0 scan |grep SSID'
+
+PS1='[\u@\h \W]\$ '
+
diff --git a/dotfiles/.vimrc b/dotfiles/.vimrc
@@ -0,0 +1,8 @@
+syntax enable
+filetype plugin on
+
+set path+=**
+set wildmenu
+
+command! Ctags !ctags -R
+
diff --git a/dotfiles/i3/config b/dotfiles/i3/config
@@ -0,0 +1,195 @@
+# This file has been auto-generated by i3-config-wizard(1).
+# It will not be overwritten, so edit it as you like.
+#
+# Should you change your keyboard layout some time, delete
+# this file and re-run i3-config-wizard(1).
+#
+
+# i3 config file (v4)
+#
+# Please see https://i3wm.org/docs/userguide.html for a complete reference!
+
+set $mod Mod4
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+font Inconsolata:monospace 8
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# Before i3 v4.8, we used to recommend this one as the default:
+# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+# The font above is very space-efficient, that is, it looks good, sharp and
+# clear in small sizes. However, its unicode glyph coverage is limited, the old
+# X core fonts rendering does not support right-to-left and this being a bitmap
+# font, it doesn’t scale on retina/hidpi displays.
+
+# Colors
+# class border backgr. text indicator child_border
+#client.focused #884400 #773322 #ffffff #773322 #773322
+#client.focused_inactive #333333 #5f676a #ffffff #5f676a #5f676a
+#client.unfocused #333333 #222222 #888888 #222222 #222222
+#client.urgent #2f343a #900000 #ffffff #900000 #900000
+#client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c
+#client.background #ffffff
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# start a terminal
+bindsym $mod+Return exec i3-sensible-terminal
+
+# kill focused window
+bindsym $mod+Shift+q kill
+
+#lock the session
+bindsym $mod+Shift+p exec i3lock -c 000000 -k --datestr="%m-%d-%Y" --datecolor=FFFFFFFF --date-font=iosevka --datesize=20 --timestr="%I:%M %p" --timecolor=FFFFFFFF --time-font=iosevka --ringcolor=FFFFFFFF --verif-font=iosevka --veriftext="VALIDATING" --verifcolor=FFFFFFFF --wrong-font=iosevka --wrongtext="INVALID" --wrongcolor=FFFFFFFF --noinputtext="CLEARED" --insidevercolor=00000000 --insidewrongcolor=00000000 --ringwrongcolor=BB0000FF
+
+# start dmenu (a program launcher)
+bindsym $mod+d exec dmenu_run -fn Iosevka-10
+# There also is the (new) i3-dmenu-desktop which only displays applications
+# shipping a .desktop file. It is a wrapper around dmenu, so you need that
+# installed.
+# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
+
+# change focus
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+Shift+h move left
+bindsym $mod+Shift+j move down
+bindsym $mod+Shift+k move up
+bindsym $mod+Shift+l move right
+
+# alternatively, you can use the cursor keys:
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+Right move right
+
+# split in horizontal orientation
+bindsym $mod+g split h
+
+# split in vertical orientation
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+e layout toggle split
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+#bindsym $mod+d focus child
+
+# Define names for default workspaces for which we configure key bindings later on.
+# We use variables to avoid repeating the names in multiple places.
+set $ws1 "1"
+set $ws2 "2"
+set $ws3 "3"
+set $ws4 "4"
+set $ws5 "5"
+set $ws6 "6"
+set $ws7 "7"
+set $ws8 "8"
+set $ws9 "9"
+set $ws10 "10"
+
+# switch to workspace
+bindsym $mod+1 workspace $ws1
+bindsym $mod+2 workspace $ws2
+bindsym $mod+3 workspace $ws3
+bindsym $mod+4 workspace $ws4
+bindsym $mod+5 workspace $ws5
+bindsym $mod+6 workspace $ws6
+bindsym $mod+7 workspace $ws7
+bindsym $mod+8 workspace $ws8
+bindsym $mod+9 workspace $ws9
+bindsym $mod+0 workspace $ws10
+
+# move focused container to workspace
+bindsym $mod+Shift+1 move container to workspace $ws1
+bindsym $mod+Shift+2 move container to workspace $ws2
+bindsym $mod+Shift+3 move container to workspace $ws3
+bindsym $mod+Shift+4 move container to workspace $ws4
+bindsym $mod+Shift+5 move container to workspace $ws5
+bindsym $mod+Shift+6 move container to workspace $ws6
+bindsym $mod+Shift+7 move container to workspace $ws7
+bindsym $mod+Shift+8 move container to workspace $ws8
+bindsym $mod+Shift+9 move container to workspace $ws9
+bindsym $mod+Shift+0 move container to workspace $ws10
+
+# reload the configuration file
+bindsym $mod+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym j resize shrink width 10 px or 10 ppt
+ bindsym k resize grow height 10 px or 10 ppt
+ bindsym l resize shrink height 10 px or 10 ppt
+ bindsym semicolon resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # back to normal: Enter or Escape or $mod+r
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+ bindsym $mod+r mode "default"
+}
+
+bindsym $mod+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+bar {
+ status_command i3status
+ colors {
+ separator #4c7899
+ background #000000
+ statusline #ffffff
+
+ focused_workspace #4c7899 #285577 #ffffff
+ active_workspace #333333 #5f676a #ffffff
+ inactive_workspace #333333 #222222 #888888
+ urgent_workspace #2f343a #900000 #ffffff
+ binding_mode #2f343a #900000 #ffffff
+ }
+}
+
+default_border pixel 2
diff --git a/dotfiles/i3status/config b/dotfiles/i3status/config
@@ -0,0 +1,62 @@
+# i3status configuration file.
+# see "man i3status" for documentation.
+
+# It is important that this file is edited as UTF-8.
+# The following line should contain a sharp s:
+# ß
+# If the above line is not correctly displayed, fix your editor first!
+
+general {
+ colors = true
+ interval = 5
+}
+
+#order += "ipv6"
+order += "disk /"
+order += "wireless _first_"
+order += "ethernet _first_"
+order += "battery all"
+order += "load"
+order += "cpu_usage"
+order += "cpu_temperature 0"
+order += "memory"
+order += "tztime local"
+
+wireless _first_ {
+ format_up = "W: (%quality at %essid) %ip"
+ format_down = "W: down"
+}
+
+ethernet _first_ {
+ # if you use %speed, i3status requires root privileges
+ format_up = "E: %ip (%speed)"
+ format_down = "E: down"
+}
+
+battery all {
+ format = "%status %percentage %consumption %remaining"
+}
+
+tztime local {
+ format = "%m-%d-%Y %I:%M%p "
+}
+
+load {
+ format = "%1min"
+}
+
+memory {
+ format = "RAM: %used (%percentage_used)"
+}
+
+disk "/" {
+ format = "%avail"
+}
+
+cpu_usage {
+ format = "CPU_0: %cpu0 CPU_1: %cpu1"
+}
+
+cpu_temperature 0 {
+ format = "CORETEMP: %degrees °C"
+}
diff --git a/dotfiles/st/config.h b/dotfiles/st/config.h
@@ -0,0 +1,468 @@
+/* See LICENSE file for copyright and license details. */
+
+/*
+ * appearance
+ *
+ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
+ */
+static char *font = "Iosevka-10:antialias=true";
+static int borderpx = 2;
+
+/*
+ * What program is execed by st depends of these precedence rules:
+ * 1: program passed with -e
+ * 2: utmp option
+ * 3: SHELL environment variable
+ * 4: value of shell in /etc/passwd
+ * 5: value of shell in config.h
+ */
+static char *shell = "/bin/sh";
+char *utmp = NULL;
+char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
+
+/* identification sequence returned in DA and DECID */
+char *vtiden = "\033[?6c";
+
+/* Kerning / character bounding-box multipliers */
+static float cwscale = 1.0;
+static float chscale = 1.0;
+
+/*
+ * word delimiter string
+ *
+ * More advanced example: L" `'\"()[]{}"
+ */
+wchar_t *worddelimiters = L" ";
+
+/* selection timeouts (in milliseconds) */
+static unsigned int doubleclicktimeout = 300;
+static unsigned int tripleclicktimeout = 600;
+
+/* alt screens */
+int allowaltscreen = 1;
+
+/* frames per second st should at maximum draw to the screen */
+static unsigned int xfps = 120;
+static unsigned int actionfps = 30;
+
+/*
+ * blinking timeout (set to 0 to disable blinking) for the terminal blinking
+ * attribute.
+ */
+static unsigned int blinktimeout = 800;
+
+/*
+ * thickness of underline and bar cursors
+ */
+static unsigned int cursorthickness = 2;
+
+/*
+ * bell volume. It must be a value between -100 and 100. Use 0 for disabling
+ * it
+ */
+static int bellvolume = 0;
+
+/* default TERM value */
+char *termname = "st-256color";
+
+/*
+ * spaces per tab
+ *
+ * When you are changing this value, don't forget to adapt the »it« value in
+ * the st.info and appropriately install the st.info in the environment where
+ * you use this st version.
+ *
+ * it#$tabspaces,
+ *
+ * Secondly make sure your kernel is not expanding tabs. When running `stty
+ * -a` »tab0« should appear. You can tell the terminal to not expand tabs by
+ * running following command:
+ *
+ * stty tabs
+ */
+unsigned int tabspaces = 8;
+
+/* bg opacity */
+float alpha = 0.8;
+
+/* Terminal colors (16 first used in escape sequence) */
+static const char *colorname[] = {
+ /* 8 normal colors */
+ "black",
+ "red3",
+ "green3",
+ "yellow3",
+ "blue2",
+ "magenta3",
+ "cyan3",
+ "gray90",
+
+ /* 8 bright colors */
+ "gray50",
+ "red",
+ "green",
+ "yellow",
+ "#5c5cff",
+ "magenta",
+ "cyan",
+ "white",
+
+ [255] = 0,
+
+ /* more colors can be added after 255 to use with DefaultXX */
+ "#cccccc",
+ "#555555",
+ "black",
+};
+
+
+/*
+ * Default colors (colorname index)
+ * foreground, background, cursor, reverse cursor
+ */
+unsigned int defaultfg = 7;
+unsigned int defaultbg = 258;
+static unsigned int defaultcs = 256;
+static unsigned int defaultrcs = 257;
+
+/*
+ * Default shape of cursor
+ * 2: Block ("█")
+ * 4: Underline ("_")
+ * 6: Bar ("|")
+ * 7: Snowman ("☃")
+ */
+static unsigned int cursorshape = 2;
+
+/*
+ * Default columns and rows numbers
+ */
+
+static unsigned int cols = 80;
+static unsigned int rows = 24;
+
+/*
+ * Default colour and shape of the mouse cursor
+ */
+static unsigned int mouseshape = XC_xterm;
+static unsigned int mousefg = 7;
+static unsigned int mousebg = 0;
+
+/*
+ * Color used to display font attributes when fontconfig selected a font which
+ * doesn't match the ones requested.
+ */
+static unsigned int defaultattr = 11;
+
+/*
+ * Internal mouse shortcuts.
+ * Beware that overloading Button1 will disable the selection.
+ */
+static MouseShortcut mshortcuts[] = {
+ /* button mask string */
+ { Button4, XK_ANY_MOD, "\031" },
+ { Button5, XK_ANY_MOD, "\005" },
+};
+
+/* Internal keyboard shortcuts. */
+#define MODKEY Mod1Mask
+#define TERMMOD (ControlMask|ShiftMask)
+
+static Shortcut shortcuts[] = {
+ /* mask keysym function argument */
+ { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} },
+ { ControlMask, XK_Print, toggleprinter, {.i = 0} },
+ { ShiftMask, XK_Print, printscreen, {.i = 0} },
+ { XK_ANY_MOD, XK_Print, printsel, {.i = 0} },
+ { TERMMOD, XK_Prior, zoom, {.f = +1} },
+ { TERMMOD, XK_Next, zoom, {.f = -1} },
+ { TERMMOD, XK_Home, zoomreset, {.f = 0} },
+ { TERMMOD, XK_C, clipcopy, {.i = 0} },
+ { TERMMOD, XK_V, clippaste, {.i = 0} },
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
+ { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} },
+ { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} },
+};
+
+/*
+ * Special keys (change & recompile st.info accordingly)
+ *
+ * Mask value:
+ * * Use XK_ANY_MOD to match the key no matter modifiers state
+ * * Use XK_NO_MOD to match the key alone (no modifiers)
+ * appkey value:
+ * * 0: no value
+ * * > 0: keypad application mode enabled
+ * * = 2: term.numlock = 1
+ * * < 0: keypad application mode disabled
+ * appcursor value:
+ * * 0: no value
+ * * > 0: cursor application mode enabled
+ * * < 0: cursor application mode disabled
+ * crlf value
+ * * 0: no value
+ * * > 0: crlf mode is enabled
+ * * < 0: crlf mode is disabled
+ *
+ * Be careful with the order of the definitions because st searches in
+ * this table sequentially, so any XK_ANY_MOD must be in the last
+ * position for a key.
+ */
+
+/*
+ * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF)
+ * to be mapped below, add them to this array.
+ */
+static KeySym mappedkeys[] = { -1 };
+
+/*
+ * State bits to ignore when matching key or button events. By default,
+ * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored.
+ */
+static uint ignoremod = Mod2Mask|XK_SWITCH_MOD;
+
+/*
+ * Override mouse-select while mask is active (when MODE_MOUSE is set).
+ * Note that if you want to use ShiftMask with selmasks, set this to an other
+ * modifier, set to 0 to not use it.
+ */
+static uint forceselmod = ShiftMask;
+
+/*
+ * This is the huge key array which defines all compatibility to the Linux
+ * world. Please decide about changes wisely.
+ */
+static Key key[] = {
+ /* keysym mask string appkey appcursor */
+ { XK_KP_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0},
+ { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0},
+ { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0},
+ { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0},
+ { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0},
+ { XK_KP_End, ControlMask, "\033[J", -1, 0},
+ { XK_KP_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_KP_End, ShiftMask, "\033[K", -1, 0},
+ { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_KP_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
+ { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0},
+ { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0},
+ { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0},
+ { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0},
+ { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0},
+ { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0},
+ { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0},
+ { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0},
+ { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0},
+ { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0},
+ { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0},
+ { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0},
+ { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0},
+ { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0},
+ { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0},
+ { XK_Up, ShiftMask, "\033[1;2A", 0, 0},
+ { XK_Up, Mod1Mask, "\033[1;3A", 0, 0},
+ { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0},
+ { XK_Up, ControlMask, "\033[1;5A", 0, 0},
+ { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0},
+ { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0},
+ { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0},
+ { XK_Up, XK_ANY_MOD, "\033[A", 0, -1},
+ { XK_Up, XK_ANY_MOD, "\033OA", 0, +1},
+ { XK_Down, ShiftMask, "\033[1;2B", 0, 0},
+ { XK_Down, Mod1Mask, "\033[1;3B", 0, 0},
+ { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0},
+ { XK_Down, ControlMask, "\033[1;5B", 0, 0},
+ { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0},
+ { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0},
+ { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0},
+ { XK_Down, XK_ANY_MOD, "\033[B", 0, -1},
+ { XK_Down, XK_ANY_MOD, "\033OB", 0, +1},
+ { XK_Left, ShiftMask, "\033[1;2D", 0, 0},
+ { XK_Left, Mod1Mask, "\033[1;3D", 0, 0},
+ { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0},
+ { XK_Left, ControlMask, "\033[1;5D", 0, 0},
+ { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0},
+ { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0},
+ { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0},
+ { XK_Left, XK_ANY_MOD, "\033[D", 0, -1},
+ { XK_Left, XK_ANY_MOD, "\033OD", 0, +1},
+ { XK_Right, ShiftMask, "\033[1;2C", 0, 0},
+ { XK_Right, Mod1Mask, "\033[1;3C", 0, 0},
+ { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0},
+ { XK_Right, ControlMask, "\033[1;5C", 0, 0},
+ { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0},
+ { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0},
+ { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0},
+ { XK_Right, XK_ANY_MOD, "\033[C", 0, -1},
+ { XK_Right, XK_ANY_MOD, "\033OC", 0, +1},
+ { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0},
+ { XK_Return, Mod1Mask, "\033\r", 0, 0},
+ { XK_Return, XK_ANY_MOD, "\r", 0, 0},
+ { XK_Insert, ShiftMask, "\033[4l", -1, 0},
+ { XK_Insert, ShiftMask, "\033[2;2~", +1, 0},
+ { XK_Insert, ControlMask, "\033[L", -1, 0},
+ { XK_Insert, ControlMask, "\033[2;5~", +1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0},
+ { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0},
+ { XK_Delete, ControlMask, "\033[M", -1, 0},
+ { XK_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
+ { XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
+ { XK_Home, ShiftMask, "\033[2J", 0, -1},
+ { XK_Home, ShiftMask, "\033[1;2H", 0, +1},
+ { XK_Home, XK_ANY_MOD, "\033[H", 0, -1},
+ { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1},
+ { XK_End, ControlMask, "\033[J", -1, 0},
+ { XK_End, ControlMask, "\033[1;5F", +1, 0},
+ { XK_End, ShiftMask, "\033[K", -1, 0},
+ { XK_End, ShiftMask, "\033[1;2F", +1, 0},
+ { XK_End, XK_ANY_MOD, "\033[4~", 0, 0},
+ { XK_Prior, ControlMask, "\033[5;5~", 0, 0},
+ { XK_Prior, ShiftMask, "\033[5;2~", 0, 0},
+ { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0},
+ { XK_Next, ControlMask, "\033[6;5~", 0, 0},
+ { XK_Next, ShiftMask, "\033[6;2~", 0, 0},
+ { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0},
+ { XK_F1, XK_NO_MOD, "\033OP" , 0, 0},
+ { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0},
+ { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0},
+ { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0},
+ { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0},
+ { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0},
+ { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0},
+ { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0},
+ { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0},
+ { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0},
+ { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0},
+ { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0},
+ { XK_F3, XK_NO_MOD, "\033OR" , 0, 0},
+ { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0},
+ { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0},
+ { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0},
+ { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0},
+ { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0},
+ { XK_F4, XK_NO_MOD, "\033OS" , 0, 0},
+ { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0},
+ { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0},
+ { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0},
+ { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0},
+ { XK_F5, XK_NO_MOD, "\033[15~", 0, 0},
+ { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0},
+ { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0},
+ { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0},
+ { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0},
+ { XK_F6, XK_NO_MOD, "\033[17~", 0, 0},
+ { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0},
+ { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0},
+ { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0},
+ { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0},
+ { XK_F7, XK_NO_MOD, "\033[18~", 0, 0},
+ { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0},
+ { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0},
+ { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0},
+ { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0},
+ { XK_F8, XK_NO_MOD, "\033[19~", 0, 0},
+ { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0},
+ { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0},
+ { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0},
+ { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0},
+ { XK_F9, XK_NO_MOD, "\033[20~", 0, 0},
+ { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0},
+ { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0},
+ { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0},
+ { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0},
+ { XK_F10, XK_NO_MOD, "\033[21~", 0, 0},
+ { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0},
+ { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0},
+ { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0},
+ { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0},
+ { XK_F11, XK_NO_MOD, "\033[23~", 0, 0},
+ { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0},
+ { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0},
+ { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0},
+ { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0},
+ { XK_F12, XK_NO_MOD, "\033[24~", 0, 0},
+ { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0},
+ { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0},
+ { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0},
+ { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0},
+ { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0},
+ { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0},
+ { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0},
+ { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0},
+ { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0},
+ { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0},
+ { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0},
+ { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0},
+ { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0},
+ { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0},
+ { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0},
+ { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0},
+ { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0},
+ { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0},
+ { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0},
+ { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0},
+ { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0},
+ { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0},
+ { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0},
+ { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0},
+ { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0},
+ { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0},
+ { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0},
+};
+
+/*
+ * Selection types' masks.
+ * Use the same masks as usual.
+ * Button1Mask is always unset, to make masks match between ButtonPress.
+ * ButtonRelease and MotionNotify.
+ * If no match is found, regular selection is used.
+ */
+static uint selmasks[] = {
+ [SEL_RECTANGULAR] = Mod1Mask,
+};
+
+/*
+ * Printable characters in ASCII, used to estimate the advance width
+ * of single wide characters.
+ */
+static char ascii_printable[] =
+ " !\"#$%&'()*+,-./0123456789:;<=>?"
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+ "`abcdefghijklmnopqrstuvwxyz{|}~";
diff --git a/examples/infoukes.com/index.html b/examples/infoukes.com/index.html
@@ -0,0 +1,243 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+<TITLE>InfoUkes - Information Resource about Ukraine and Ukrainians</TITLE>
+<link REL="shortcut icon" HREF="/favicon.ico" TYPE="image/x-icon">
+<META NAME="Description" CONTENT="Information about Ukraine and Ukrainians">
+<META NAME="Keywords" CONTENT="Ukraine, Ukrainian, Ykpaina, Ukraina,
+Information, Guide, Education, News, Maps, Culture, Business, Ukes,
+Genealogy, History, Media, Mail Lists, Resources, Language, Religion,
+Software, Technology, Fonts, Discussion, Literature, Music, Dance,
+Research, Links, Index, Organizations, Country, Countries,
+Travel, Politics, Community Announcements, Galleries, Photos,
+InfoUkes, Main Page">
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" TEXT="#104e8b" LINK="#104E8B" ALINK="#00FF00" VLINK="#FF0000">
+<P>
+<CENTER>
+<FONT SIZE=1 COLOR="#FFFFFF">Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian</FONT>
+<table width=100% border=0 cellpadding=2 cellspacing=0>
+<tr><td width=550 colspan=2 align=center valign=middle>
+ <A HREF="/corporate/"><IMG ALIGN=CENTER alt="InfoUkes Logo" width=459 height=117 BORDER=0 SRC="/icons2/infologo.gif"></A><br>
+
+ <!-- Optional site announcement goes here -->
+ <FONT size=5><B>InfoUkes<BR>22 Years online since April 16th 1997</B></FONT><BR><BR>
+ <!-- Ukrainian quotes -->
+ <center><table><tr><td><font color="#104e8b" size=-1><pre>Yes, Shevchenko became a very embodiment of the ideals and
+the aspirations and the dreams of every Ukrainian patriot.
+He believed in his country, and although seventy-five years
+have passed since his untimely death [March 10, 1861] and
+his ideals have not been realized, there can be no doubt
+that the Ukrainian spirit which Shevchenko voiced, will
+continue to struggle for its aspirations until it finally
+meets with success and Ukraine will appear again among the
+recognized nations of the world.
+ - Clarence A. Manning, Columbia University. In: Taras
+ Shevchenko: Bard of Ukraine, by D. Doroshenko. New
+ York 1936, p. 5.
+</pre></font></table></center><br>
+ <!--
+ <FONT size=5><B>Russia has invaded Ukrainian soil<BR>in a sneak unprovoked attack</B></FONT><BR><BR>
+ <A HREF="/euromaidan/"><FONT size=5><B>EuroMaidan Protests for Civil Society</B></FONT></A><BR><BR>
+ -->
+ <FONT size=5><B>#LetMyPeopleGo<BR>Free Ukrainian Political Prisoners held by the Kremlin</B></FONT><BR><BR>
+<!-- <A HREF="/orange_revolution/"><img align=center alt="orange_ribbon" border=0 src="/icons2/ribbon.png"></A><BR> -->
+ </td>
+ <TD BGCOLOR="#FFFFFF">
+ <A HREF="http://www.ukremb.ca/"><IMG width=60 height=45 SRC="/buttons/ukremb.gif" BORDER=0 align=center><font face="Arial-Narrow" size="1"> Embassy of Ukraine</a></font><br>
+ <A HREF="http://www.shevchenkofoundation.com/"><IMG align=middle WIDTH=60 HEIGHT=45 BORDER=0 SRC="/buttons/ts.png" alt="Taras Shevchenko Foundation"><font face="Arial-Narrow" size="1">Shevchenko Foundation</font></A><br>
+ <A HREF="http://www.utoronto.ca/cius"><IMG align=middle WIDTH=60 HEIGHT=45 BORDER=0 SRC="/buttons/cius.gif" alt="CIUS Press"><font face="Arial-Narrow" size="1"> CIUS Press</font></A><br>
+ <A HREF="http://encyclopediaofukraine.com/"><IMG align=middle WIDTH=60 HEIGHT=45 BORDER=0 SRC="/buttons/sunflower.gif" alt="Encyclopedia of Ukraine"><font face="Arial-Narrow" size="1"> Encyclopedia of Ukraine</font></A><br>
+ <A HREF="http://www.petro-jacyk-foundation.org"><IMG align=middle WIDTH=60 HEIGHT=45 BORDER=0 SRC="/buttons/pjef.gif" alt="PJEF"><font face="Arial-Narrow" size="1"> PJEF</font></A><br>
+ <A HREF="http://kontakt.infoukes.com/"><IMG align=middle WIDTH=60 HEIGHT=45 BORDER=0 SRC="/icons2/icon-kontakt.gif" alt="KONTAKT Ukrainian TV"><font face="Arial-Narrow" size="1"> Kontakt Ukrainian TV</font></A><br>
+ <table border=0 cellpadding=0 cellspacing=0 ALIGN=LEFT>
+ <tr><td width=70 rowspan=4><A HREF="/ucpbf/"><IMG VALIGN=middle ALIGN=LEFT WIDTH=60 HEIGHT=45 BORDER=0 SRC="/icons2/icon-ucpba.gif" alt="UCPBA"></A></td>
+ <!--
+ <tr><td><A HREF="/organizations/ucpba-toronto/"><FONT face="Arial-Narrow" SIZE="1" COLOR="#104E8B"> UCPBA of Toronto</FONT></A><br></td></tr>
+ -->
+ <tr><td><A HREF="/organizations/ucpba-hamilton/"><FONT face="Arial-Narrow" SIZE="1" COLOR="#104E8B"> UCPBA of Hamilton</FONT></A></td></tr>
+ </table>
+ </font>
+</tr>
+<TR>
+ <!-- Topics Title -->
+ <TD width=160 ALIGN=LEFT VALIGN=top BGCOLOR="#B0C4DE"><FONT color="#104e8b" SIZE="+1"><B><I>Topics</I></B></FONT></TD>
+ <!-- What's New Title -->
+ <TD width=400 ALIGN=LEFT VALIGN=MIDDLE BGCOLOR="#B0C4DE"><B><I><FONT color="#104e8b" SIZE="+1">What's New</FONT></I></B></TD>
+ <TD ALIGN=LEFT VALIGN=MIDDLE BGCOLOR="#ffffff"><B><I><FONT SIZE=4> </FONT></I></B></TD>
+</TR>
+<TR>
+ <TD ALIGN=LEFT VALIGN=top BGCOLOR="#EEE8CD">
+ <A HREF="/news/"><FONT face="Arial-Narrow" SIZE=3><B>Announcements</B></FONT></A><br>
+ <A HREF="/bookstore/"><FONT face="Arial-Narrow" SIZE=3><B>Bookstore</B></FONT></A><br>
+ <A HREF="/business/"><FONT face="Arial-Narrow" SIZE=3><B>Business</B></FONT></A><br>
+ <A HREF="/commercial/"><FONT face="Arial-Narrow" SIZE=3><B>Commercial Clients</B></FONT></A><br>
+ <A HREF="/culture/"><FONT face="Arial-Narrow" SIZE=3><B>Culture</B></FONT></A><br>
+ <A HREF="/education/"><FONT face="Arial-Narrow" SIZE=3><B>Education</B></FONT></A><br>
+ <A HREF="/euromaidan/"><FONT face="Arial-Narrow" SIZE=3><B>EuroMaidan</B></FONT></A><br>
+ <A HREF="/entertainment/"><FONT face="Arial-Narrow" SIZE=3><B>Entertainment</B></FONT></A><br>
+ <A HREF="/faq/"><FONT face="Arial-Narrow" SIZE=3><B>FAQ</B></FONT></A><br>
+ <A HREF="/fonts/"><FONT face="Arial-Narrow" SIZE=3><B>Fonts</B></FONT></A><br>
+ <A HREF="/genealogy/"><FONT face="Arial-Narrow" SIZE=3><B>Genealogy</B></FONT></A><br>
+ <A HREF="/history/"><FONT face="Arial-Narrow" SIZE=3><B>History</B></FONT></A><br>
+ <A HREF="/humour/"><FONT face="Arial-Narrow" SIZE=3><B>Humour & Satire</B></FONT></A><br>
+ <A HREF="/corporate/"><FONT face="Arial-Narrow" SIZE=3><B>InfoUkes Corporate</B></FONT></A><br>
+ <A HREF="/culture/lemkos/"><FONT face="Arial-Narrow" SIZE=3><B>Lemkos</B></FONT></A><br>
+ <A HREF="/lists/"><FONT face="Arial-Narrow" SIZE=3><B>Mailing Lists</B></FONT></A><br>
+ <A HREF="/ua-maps/"><FONT face="Arial-Narrow" SIZE=3><B>Map Server</B></FONT></A><br>
+ <A HREF="/media/"><FONT face="Arial-Narrow" SIZE=3><B>Media on Internet</B></FONT></A><br>
+ <A HREF="/medicine/"><FONT face="Arial-Narrow" SIZE=3><B>Medicine</B></FONT></A><br>
+ <A HREF="/culture/music/"><FONT face="Arial-Narrow" SIZE=3><B>Music</B></FONT></A><br>
+ <A HREF="/news/"><FONT face="Arial-Narrow" SIZE=3><B>News</B></FONT></A><br>
+ <A HREF="/organizations/"><FONT face="Arial-Narrow" SIZE=3><B>Organizations</B></FONT></A><br>
+ <A HREF="/politics/"><FONT face="Arial-Narrow" SIZE=3><B>Politics</B></FONT></A><br>
+ <A HREF="/religion/"><FONT face="Arial-Narrow" SIZE=3><B>Religion</B></FONT></A><br>
+ <A HREF="/search/"><FONT face="Arial-Narrow" SIZE=3><B>Site Search Engine</B></FONT></A><br>
+ <A HREF="/software/"><FONT face="Arial-Narrow" SIZE=3><B>Software</B></FONT></A><br>
+ <A HREF="/sports/"><FONT face="Arial-Narrow" SIZE=3><B>Sports</B></FONT></A><br>
+ <A HREF="/technology/"><FONT face="Arial-Narrow" SIZE=3><B>Technology</B></FONT></A><br>
+ <A HREF="/travel/"><FONT face="Arial-Narrow" SIZE=3><B>Travel</B></FONT></A><br>
+ <A HREF="/canada/"><FONT face="Arial-Narrow" SIZE=3><B>Ukrainians in Canada</B></FONT></A><br>
+ <A HREF="/whats_new/"><FONT face="Arial-Narrow" SIZE=3><B>What's New Archive</B></FONT></A><br>
+ <!--
+ <A HREF="http://www.ucc.ca/news.htm"><FONT face="Arial-Narrow" SIZE=3><B>What's New on UCC</B></FONT></A><br>
+ <A HREF="/wwwlinks/"><FONT face="Arial-Narrow" SIZE=3><B>WWW Links</B></FONT></A>
+ -->
+ </TD>
+ <TD VALIGN=TOP BGCOLOR="#FFFFF0"><br>
+ <A HREF="/russia_invaded_ukraine/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Russia Invaded Ukraine</b> </a></font><br /><br />
+ <A HREF="/lists/politics/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Politics Discussion Mail List</b> </a></font><br /><br />
+ <A HREF="/euromaidan/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>EuroMaidan</b> </a></font><br /><br />
+ <A HREF="/culture/architecture/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Ukrainian Churches in Canada</b> </a></font><br /><br />
+ <A HREF="/ukremb/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Ukraine Information Portal</b> </a></font><br /><br />
+ <A HREF="/tarasinottawa/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>National Taras Shevchenko Monument in Ottawa</font></A></b><br><br>
+ <A HREF="http://www.canadianfriendsofukraine.com/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Canadian Friends of Ukraine</font></A></b><br><br>
+ <A HREF="/scarry/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Ukrainian-English-French Children's Dictionary, by Scarry</font></A></b><br><br>
+ <A HREF="http://www.tsiopa-shkola.ca/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Tsiopa Palijiw Ukrainian School</font></A></b><br><br>
+ <A HREF="/summerdance/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>The International Summer School of Dance</b></font></A><br><br>
+ <A HREF="/churches/senyk/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Irena Senyk</b></font></A><br><br>
+ <A HREF="http://www.ugolf.ca/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Ukrainian Golf Association of Canada</b></font></A><br><br>
+ <A HREF="/churches/indexZak-eng.htm"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Churches of Ukraine. Zakarpatia</b></font></A><br><br>
+ <A HREF="http://www.yuzyk.com/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>Honourable Senator Paul Yuzyk</font></a></b><br><br>
+ <A HREF="/shevchenkomuseum/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>The Taras Shevchenko Museum of Canada</font></A></b><br><br>
+ <A HREF="http://www.shkola.org/"><font face="Arial-Narrow" size="3" COLOR="#104E8B"> <b>SHKOLA.ORG</font></A></b><br><br>
+ </TD>
+ <TD ALIGN=CENTER VALIGN=TOP BGCOLOR="#FFFFFF">
+
+<!-- <IMG SRC="/icons2/kozak2.gif" ALT="Kozak" WIDTH=193 HEIGHT=360 BORDER=0><br> -->
+ <table bgcolor="#EEE8CD">
+ <tr><td><center><FONT color="#104e8b"><b>Features</b></font></center>
+ <!--
+ <tr><td bgcolor="#ffffff">
+ <b>Parliamentary Elections in Ukraine -- March 26th 2006</b><br>
+ <li><font size=2>Exit Poll in <a href="http://exitpoll.org.ua/"><b>Ukrainian</b></a> & in
+ <a href="http://exitpoll.vis-design.com/?langid=2"><b>English</b></a>
+ provided by the Democratic Iniatives Foundation, Kyiv International Institute
+ of Sociology, and Razumkov Centrer for Economic and Political Research</font>
+ <li><font size=2><a href="http://www.cvk.gov.ua/"><b>Central Election Commission</b></a>
+ in Ukrainian. Direct Links in
+ <font size=2><a href="http://www.cvk.gov.ua/vnd2006/w6p001.html"><b>Ukrainian</b></a> and
+ <font size=2><a href="http://www.cvk.gov.ua/vnd2006/w6p001e.html"><b>English</b></a>
+ <li><font size=2><a href="http://www.pravda.com.ua/"><b>Ukrainian Pravda</b></a> News Site</font>
+ <li><font size=2><a href="http://www.maidan.org.ua/"><b>Maidan</b></a> Activist Site</font>
+ <li><font size=2>InfoUkes's <a href="/lists/politics/2006/03/"><b>Politics</b></a> List</font>
+ <br><br>
+ -->
+
+ <tr><td bgcolor="#ffffff">
+ <b>Famine/Genocide (Holodomor) 1932-1933</b><br>
+ <li><font size=2>Every November Ukrainians around the world commemmorate the Artificial <font size=2><a href="/history/famine/"><b>Famine/Genocide</b></a> (Holodomor) in Ukraine 1932-33.</font><br><br>
+ <b>Internment of Ukrainian Canadians 1914-1920</b><br>
+ <li><font size=2><a href="/history/internment/"><b>Internment</b></a> of Ukrainian Canadians 1914-1920 in a archipelago of 26 concentration camps across Canada.</font>
+ <li><font size=2><a href="/history/internment/bill_c-331/"><b>Bill C-331</b></a> The Ukrainian Canadian Restitution Act.</font><br><br>
+ <b>70th Anniversary of D-Day</b><br>
+ <li><font size=2>Article about <b><a href="/history/ww2/">World War II in Ukraine</a></b> by Andrew Gregorovich</font>
+ <li><font size=2><b><a href="/upa/">Litopys-UPA</a></b> Chronicle of the Ukrainian Insurgent Army</font>
+ <li><font size=2>Brotherhood of Veterans of the <b><a href="/galiciadivision/">1st Division</a></b> of the Ukrainian National Army</font>
+ <!--
+ <li><font size=2>Statements from the Ukrainian Canadian Congress in the <b><a href="http://www.ucc.ca/media_releases/2005-05-06_1/">English Language</a></b> and in the <b><a href="http://www.ucc.ca/media_releases/2005-05-06_1/index_ua.html">Ukrainian Language</a></b> on the 60th Anniversary of Victory in Europe</font><br><br>
+ -->
+ <tr><td><center><FONT color="#104e8b"><b>News - Novyny</b></font></center>
+ <tr><td bgcolor="#ffffff">
+ <b><i>announce</i> mailing list</b><br>
+ <font size=2><a href="/lists/announce/2014/12/">Dec</a>
+ <a href="/lists/announce/2015/01/">Jan</a> archives.</font><br><br>
+ <a href="/lists/announce/2015/02/">Feb</a> archives.</font><br><br>
+ <b>New Pathway</b><br>
+ <font size=2>Ukrainian <A HREF="http://www.newpathway.ca">weekly newspaper</a>.</font><br><br>
+ <b>Radio Free Europe / Radio Liberty</b><br>
+ <font size=2>Daily Ukraine-related <A HREF="/rfe-ukraine/">news stories</a>.</font><br><br>
+ <!--
+ <b>Ukrainian World Congress</b><br>
+ <font size=2>Visit the webiste of the Ukrainian World Congress <A HREF="http://www.ukrainianworldcongress.org/">here</a>.</font><br><br>
+ -->
+ <!--
+ <b>Ukrainian Canadian Congress</b><br>
+ <font size=2>Recent <A HREF="http://www.ucc.ca/media_releases/index.htm">press releases</a> and
+ <A HREF="http://www.ucc.ca/issues.htm">Important Issues & Positions</a>. Visit the main page
+ of this site <A HREF="http://www.ucc.ca/">here</a> or see what is <A HREF="http://www.ucc.ca/news.htm">new</A>
+ on the UCC Site.</font><br><br>
+ -->
+ <!--
+ <b>UCCLA</b><br>
+ <font size=2>Recent <A HREF="http://www.uccla.ca/">press releases</a> on Ukrainian Canadian Issues by the Ukrainian Canadian Civil Liberties Association..
+ </font><br><br>
+ -->
+ <!--
+ <b>UACLA</b><br>
+ <font size=2>Check out the Ukrainian American Civil Liberties Association
+ <A HREF="http://www.uacla.org/">HERE</a>.<br><br>
+ <font size=2>
+ -->
+ <a href="http://kontakt.ca/features/?cat=3/">
+ <img align=middle src="/icons2/eoc_s.jpg" alt="Ochyma kul'tury"> Ochyma kul'tury</a>
+ </font><br><br>
+ <b>Weather</b></A><br>
+ <font size=2>Today's <a href="http://www.wunderground.com/global/UR.html">conditions</a> in major cities of Ukraine.
+ <tr><td><center><b>Upcoming Events</b></center>
+ <tr><td bgcolor="#ffffff"><br>
+ <FONT size=2>UCC Toronto Branch <a href="http://ucctoronto.infoukes.com/calendar/index_new.html">Calendar of Events
+ </a></font><br><br>
+ <FONT size=2>UCC Community <a href="http://www.ucc.ca/news/community-calendar/">Calendar</a></font><br>
+ <a href="/cgi-bin2/pfunny.pl"><font color="#ffffff">funny</font></a>
+ </font><br>
+ <font size=2>
+ KONTAKT Ukrainian TV Network</A><br>
+ View latest <A HREF="http://kontakt.ca/">Kontakt Television Program</a>.
+ View <A HREF="http://kontakt.infoukes.com/archives/">past Kontakt TV Programs</A>.
+ </font><br><br>
+ </table>
+ </TD>
+</TR>
+<tr><td bgcolor="#B0C4DE" colspan=3>
+<font size="2">
+ <FORM METHOD="post" ACTION="/cgi-bin2/htsearch"> Search:
+ <input type="text" size="20" name="words" value="">
+ <input type="submit" value="Search">
+ <input type="reset">
+
+ Match: <SELECT name=method>
+ <option value=and>all words
+ <option value=or>any words
+ <option value=boolean>boolean</SELECT>
+ Search area: <select name=exclude>
+ <option value="www.infoukes.com/lists/">web site only
+ <option value="">web and lists</SELECT>
+ <input type=hidden name=config value=htdig>
+ <input type=hidden name=restrict value="">
+ </FORM>
+</font>
+</table>
+<FONT SIZE=1 COLOR="#FFFFFF">Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian</FONT>
+</p>
+Please read the <A HREF="/corporate/disclaimer/">InfoUkes Disclaimer</A>.<br>
+<B>© 1997-2020 <A HREF="/corporate/">InfoUkes Inc.</A> All Rights Reserved.</B></font><br><br>
+<A HREF="http://www.eff.org/"><IMG WIDTH=143 HEIGHT=30 ALIGN=MIDDLE BORDER=0 SRC="/buttons/rib_bar_wh.gif" alt="Free Speech Online"></A>
+<A HREF="/bookstore/amazon/amazon.html"><IMG width=148 height=45 ALT="In Association with Amazon.com" ALIGN=MIDDLE BORDER=0 SRC="/buttons/amzn-bmm-wht.gif"></A>
+<A HREF="http://www.monkeys.com/wpoison/"><IMG WIDTH=88 HEIGHT=31 ALIGN=MIDDLE BORDER=0 SRC="/icons2/wplogo.gif" ALT="Best Viewed With Any Browser"></A>
+<A HREF="http://www.anybrowser.org/campaign/"><IMG WIDTH=88 HEIGHT=31 ALIGN=MIDDLE BORDER=0 SRC="/buttons/ab-white.gif" ALT="Best Viewed With Any Browser"></A>
+<IMG align=middle SRC="/cgi-bin2/Count.cgi?md=7|df=ukes.dat|dd=B|ft=7" alt="since Mar 1 1997">
+<P><FONT SIZE=1 COLOR="#FFFFFF">Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian Ukraine Ukrainian</FONT></P>
+</center>
+</BODY>
+</HTML>
diff --git a/examples/lukesmith.xyz/index.html b/examples/lukesmith.xyz/index.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+<title>Luke Smith's Homepage</title>
+<link rel='stylesheet' type='text/css' href='style.css'>
+<link rel='alternate' type='application/rss+xml' href='rss.xml' title='Latest from Luke'>
+<meta charset="utf-8"/>
+</head>
+
+<body>
+
+<h1><big>Luke Smith</big> <small>(https://lukesmith.xyz)</small></h1>
+<ul>
+
+<ul>
+ <!-- (<a target="_blank" href="https://www.youtube.com/feeds/videos.xml?channel_id=UC2eYFnH61tmytImy1mTYvhA">RSS</a>) -->
+<!-- (<a href="https://lbry.tv/$/invite/@Luke">Join</a>) -->
+
+
+<div id="links">
+
+videos:
+<a target="_blank" href="https://youtube.com/c/lukesmithxyz"><img src="pix/icons/youtube.svg" alt="YouTube"></a>
+<a target="_blank" href="https://www.bitchute.com/channel/lukesmith/"><img src="pix/icons/bitchute.svg" alt="BitChute"></a>
+<a href="https://lbry.tv/@Luke:7"><img src="pix/icons/lbry.png"></a>
+
+
+code:
+<a target="_blank" href="https://github.com/lukesmithxyz"><img src="pix/icons/github.svg" alt="Github"></a>
+<a target="_blank" href="https://gitlab.com/lukesmithxyz"><img src="pix/icons/gitlab.svg" alt="Gitlab"></a>
+<a href="https://git.lukesmith.xyz"><img src="pix/icons/git.svg" alt="Git Server"></a>
+
+
+other:
+<a href="https://larbs.xyz"><img src="pix/larbs.png" alt="LARBS"></a>
+<a href="https://notrelated.xyz"><img src="pix/notrelated.png" alt="Not Related!"></a>
+
+ <!-- (<a target="_blank" href="https://notrelated.xyz/rss">RSS</a>) -->
+
+<a href="donate.html">donate:</a>
+<a href="donate.html#zelle"><img src="pix/icons/zelle.svg" alt="Zelle"></a>
+<a target="_blank" href="https://paypal.me/lukemsmith"><img src="pix/icons/paypal.svg" alt="Paypal"></a>
+<a target="_blank" href="https://patreon.com/lukesmith"><img src="pix/icons/patreon.svg" alt="Patreon"></a>
+<a href="donate.html#crypto"><img src="pix/icons/bitcoin.svg" alt="Bitcoin"></a>
+
+</br>
+
+personal:
+<a href="emailme.html">email</a>
+<a href="blogindex.html">blog</a>
+<a href="library.html">library</a>
+<a href="rss.xml">rss</a>
+<a href="files/">files</a>
+
+<!-- <li><a rel="me" href="https://gab.com/lukesmith"><img src="pix/icons/gab.svg" alt="Gab"> Gab</a></li> -->
+<!-- <li><a href="faq.html"><img src="pix/icons/question.svg" alt="FAQs"> FAQs</a></li> -->
+
+</div>
+
+<!-- <div class="mainpanel" > -->
+<h2 style="margin:0px">Welcome!</h2>
+<img style="float:right;margin:10px" src="pix/lukenew.gif" alt="Luke">
+
+<p>My name is Luke Smith, I'm known for being:</p>
+
+<ul>
+<li>Someone who puts up videos on <a target="_blank" href="https://youtube.com/c/lukesmithxyz">my YouTube channel</a>.
+</li>
+<li>The Luke of <a href="https://larbs.xyz">Luke's Auto-Rice Bootstrapping Scripts (LARBS)</a>.
+<li>I have done a podcast: <a href="https://notrelated.xyz"><em>Not Related!</em></a> on Big-Braned topics. I'm only just now starting to put up episodes for it again, but it's still literally the best podcast.</li>
+<li>A Ph.D. candidate in linguistics at the University of Arizona.</li>
+</ul>
+
+<h2><img src="pix/icons/blog.svg" alt="Blog"> Recent blog posts</h2>
+<p><a href="blog.html">Rolling Blog Page</a> – <a href="blogindex.html">Full browsable blog index</a></p>
+<ul>
+<!--BLOG--><li>2020 Feb 01 – <a href="blog/big-fix-for-the-stsuckless-crashonemoji-error.html">Big fix for the st/suckless 'Crash-On-Emoji' error</a></li><li>2020 Jan 20 – <a href="blog/newold-episode-of-not-related-out-every-scientific-paper-youve-read-is-wrong.html">New/old episode of Not Related! out: Every scientific paper you've read is wrong</a></li><li>2020 Jan 03 – <a href="blog/new-video-on-new-books.html">New video on new books</a></li><li>2019 Dec 24 – <a href="blog/merry-christmas-to-all-and-a-vid-from-the-archives.html">Merry Christmas to all and a vid from the archives</a></li><li>2019 Dec 08 – <a href="blog/im-thinking-about-using-bspwm.html">I'm thinking about using bspwm</a></li>
+</ul>
+
+<h2>Misc</h2>
+<ul>
+ <!-- <li><a href="wishlist.html">"A Hacking Wishlist"</a></li> -->
+<li>The <a href="programs.html">Programs and Equipment</a> I use.</li>
+<li>Automatically configured and setup email on the terminal with <a target="_blank" href="https://github.com/lukesmithxyz/mutt-wizard">mutt-wizard</a>.</li>
+<li>So you want to learn <a href="latex.html">LaTeX</a>?</li>
+<li>My <a href="https://github.com/lukesmithxyz/voidrice">dotfiles/config files</a>, which many people use and like.</li>
+</ul>
+
+<h2>Updates/RSS urls</h2>
+
+<p>Copy and paste these urls into your RSS reader (e.g. <a target="_blank" href="https://www.youtube.com/watch?v=dUFCRqs822w">newsboat</a>) for all my RSS feeds. The first is my main feed and blog, second is YouTube, the third is my podcast:</p>
+
+<pre><code>https://lukesmith.xyz/rss.xml
+https://www.youtube.com/feeds/videos.xml?channel_id=UC2eYFnH61tmytImy1mTYvhA
+https://notrelated.xyz/rss
+</code></pre>
+<!-- </div> -->
+
+
+<!-- <div class="sidepanel"> -->
+
+<!-- <h2 style="margin:0px">Links:</h2> -->
+
+<!-- <ul> -->
+
+<!-- <li>Content: -->
+<!-- <ul> -->
+<!-- <1!-- <li><a href="videos.html"><img src="pix/icons/videos.svg" alt="Video Gallery"> Video Gallery</a></li> --1> -->
+<!-- <li><a target="_blank" href="https://youtube.com/c/lukesmithxyz"><img src="pix/icons/youtube.svg" alt="YouTube"> YouTube</a> (<a target="_blank" href="https://www.youtube.com/feeds/videos.xml?channel_id=UC2eYFnH61tmytImy1mTYvhA">RSS</a>)</li> -->
+<!-- <li><a target="_blank" href="https://www.bitchute.com/channel/lukesmith/"><img src="pix/icons/bitchute.svg" alt="BitChute"> BitChute</a></li> -->
+<!-- <li><a href="https://lbry.tv/@Luke:7"><img src="pix/icons/lbry.png"> LBRY</a> (<a href="https://lbry.tv/$/invite/@Luke">Join</a>)</li> -->
+<!-- <li> -->
+<!-- <a target="_blank" href="https://github.com/lukesmithxyz"><img src="pix/icons/github.svg" alt="Github"> Github</a> -->
+<!-- (<a target="_blank" href="https://gitlab.com/lukesmithxyz"><img src="pix/icons/gitlab.svg" alt="Gitlab"></a>/ -->
+<!-- <a href="https://git.lukesmith.xyz"><img src="pix/icons/git.svg" alt="Git"></a>) -->
+<!-- </li> -->
+<!-- <li><a href="https://larbs.xyz"><img src="pix/larbs.png" alt="LARBS"> LARBS</a></li> -->
+<!-- <li><a href="https://notrelated.xyz"><img src="pix/notrelated.png" alt="Not Related!"> <em>Not Related!</em></a> (<a target="_blank" href="https://notrelated.xyz/rss">RSS</a>)</li> -->
+<!-- </ul></li> -->
+
+<!-- <li>Personal: -->
+<!-- <ul> -->
+<!-- <li><a href="emailme.html"><img src="pix/icons/email.svg" alt="Contact me"> Contact me</a></li> -->
+<!-- <li><a href="blogindex.html"><img src="pix/icons/blog.svg" alt="Blog"> Blog</a></li> -->
+<!-- <li><a href="library.html"><img src="pix/icons/books.svg" alt="Books"> Library</a></li> -->
+<!-- <li><a href="rss.xml"><img src="pix/icons/rss.svg" alt="RSS feed"> RSS feed</a></li> -->
+<!-- <1!-- <li><a rel="me" href="https://gab.com/lukesmith"><img src="pix/icons/gab.svg" alt="Gab"> Gab</a></li> --1> -->
+<!-- <1!-- <li><a href="faq.html"><img src="pix/icons/question.svg" alt="FAQs"> FAQs</a></li> --1> -->
+<!-- </ul></li> -->
+
+<!-- <li><a href="donate.html"><img src="pix/money.png"> Donate/Support</a> -->
+<!-- <ul> -->
+<!-- <li><a href="donate.html#zelle"><img src="pix/icons/zelle.svg" alt="Zelle"> Zelle (🇺🇸 US only)</a></li> -->
+<!-- <li><a target="_blank" href="https://paypal.me/lukemsmith"><img src="pix/icons/paypal.svg" alt="Paypal"> Paypal</a></li> -->
+<!-- <li><a target="_blank" href="https://patreon.com/lukesmith"><img src="pix/icons/patreon.svg" alt="Patreon"> Patreon</a></li> -->
+<!-- <li><a href="donate.html#crypto"><img src="pix/icons/bitcoin.svg" alt="Bitcoin"> Crypto</a></li> -->
+<!-- </ul> -->
+<!-- </li> -->
+
+<!-- <li><a href="files/"><img src="pix/icons/folder.svg" alt="Downloadable files"> Downloadable Files</a></li> -->
+<!-- </ul> -->
+<!-- </div> -->
+
+<div style="clear: both;"> </div>
+
+<center>
+ <a href="donate.html">
+ <img src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
+ </a>
+</center>
+
+</body>
+
+</html>
diff --git a/examples/lukesmith.xyz/style.css b/examples/lukesmith.xyz/style.css
@@ -0,0 +1,299 @@
+
+/* This goblino stylesheet is under construction. t. Luke */
+/* I'm merging a couple user submissions. */
+
+:root {
+ --color0: #292D3E;
+ --color1: #F07178;
+ --color2: #C3E88D;
+ --color3: #FFCB6B;
+ --color4: #82AAFF;
+ --color5: #C792EA;
+ --color6: #89DDFF;
+ --color7: #959DCB;
+ --color8: #676E95;
+ --color9: #f78C6C;
+ --color10: #444267;
+ --color11: #32374D;
+ --color12: #8796B0;
+ --color13: #959DCB;
+ --color14: #FF5370;
+ --color15: #FFFFFF;
+ --textcol: #858596;
+ --bg: #1b1b23;
+ --altbg:#292934;
+ --link: #97bef9;
+ --linkalt: #5982c1;
+}
+
+#links img{
+ height: 1.25em;
+}
+
+#links {
+ font-size: large;
+ align: center;
+ margin: auto;
+ max-width: 600px;
+ text-align: center;
+ background-color: var(--altbg);
+ padding: 5px;
+ border-radius: 30px;
+}
+
+li img{
+ height: 1.25em;
+}
+h1 img{
+ height: 1em;
+}
+
+h2 img{
+ height: 1em;
+}
+
+h3 img{
+ height: 1em;
+}
+
+
+
+html {
+ padding-bottom: 100px;
+ color: var(--textcol);
+ font-family: sans-serif;
+ background: var(--bg);
+}
+
+a {
+ color: var(--link);
+ text-decoration: none;
+}
+
+a:hover {
+ color: var(--linkalt);
+}
+
+body {
+ max-width: 1050px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 30px;
+ overflow: none;
+}
+
+/* The two panels on the main page: */
+.mainpanel {
+ float: left;
+ max-width: 700px;
+ padding: 4px;
+ padding-right: 30px;
+}
+
+.mainpanel li {
+ line-height:20px;
+}
+
+.sidepanel {
+ float: left;
+ max-width: 300px;
+ background-color: var(--altbg);
+ padding:2px;
+ border-radius: 0 10px 30px 0;
+}
+
+.sidepanel a {
+ color: #85631b;
+}
+
+.sidepanel a:hover {
+ color: #d89e23;
+}
+
+.sidepanel ul li {
+ font-size:20px;
+ margin:0 0 15px 0;
+}
+
+.sidepanel ul li ul li {
+ font-size:18px;
+ margin: 0px;
+ list-style: none;
+}
+
+a:hover img {
+ background: #fe8019;
+}
+
+/* Blog entry: */
+.entry {
+ padding: 10px;
+ border-radius: 0 10px 30px 0;
+ margin-bottom: 20px;
+ background: #2a2a35;
+ border-left: 10px solid #5982c1;
+}
+
+.entry h2 {
+ margin: 5px auto 2px auto;
+}
+
+footer strong {
+ font-weight: bold;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dt img {
+ height: 1em;
+}
+
+/* Class name of video thumbnails in videos.html */
+.image {
+ width: 175px !important;
+ table-layout: fixed;
+ margin-left: auto;
+ margin-right: auto;
+ display: inline-table;
+ padding: 0px;
+}
+
+.image figcaption img {
+ height: 1em;
+}
+
+img.centered {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+img {
+ /* border: 1px solid var(--color10); */
+ /* background: var(--color10); */
+ /* border-radius: 4px; */
+}
+
+figcaption {
+ padding: 0px;
+ max-width: 175px;
+}
+
+code {
+ color: var(--color2);
+ overflow-x: auto;
+ /* background: #1d2021; */
+}
+
+pre {
+ background: var(--color11);
+ border: 1px solid var(--color10);
+ border-radius: 4px;
+ padding: 5px;
+ display: block;
+ align: center;
+ max-width: 900px;
+ /* background: #1d2021; */
+}
+
+.indexcolname {
+ max-width: 100px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+.indexcoldesc {
+ font-weight: bold;
+ padding: 10px;
+ font-size: large;
+}
+
+.indexcollastmod,.indexcolsize {
+ font-size: small;
+}
+
+#indexlist {
+ margin: 0px auto;
+}
+
+.centerpiece {
+ align: center;
+ margin: 0px auto;
+}
+
+/* Used in library.html */
+.booklist dt {
+ display: list-item;
+ list-style-type: square;
+ font-weight: normal;
+}
+
+.booklist dd {
+ display: none;
+}
+
+.booklist:hover dd {
+ display: block;
+}
+
+/* The mic class is for books featured in a NotRelated episode. */
+ .mic:before {
+ content: "🎙️";
+}
+
+.mic {
+ list-style: none;
+ padding-left: 1em;
+ text-indent: -1em;
+ margin-left: 0;
+ padding-left: 0;
+}
+
+ h1 {
+ color: #50505f;
+ font-weight:normal;
+}
+
+ h2 {
+ color: #bb841a;
+ font-weight:normal;
+}
+
+.imgcont {
+ text-align: center;
+ position: relative;
+}
+
+.imgconttext {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: xx-large;
+ color: black;
+ text-shadow:
+ -1px -1px 0 white,
+ 1px -1px 0 white,
+ -1px 1px 0 white,
+ 1px 1px 0 white;
+}
+
+.hiddiv {
+ display: none;
+}
+
+.qr:hover {
+ color: goldenrod;
+}
+
+.qr:hover .hiddiv {
+ display: block;
+ float: right;
+}
+
+.hiddiv img {
+ height: 200px;
+}
diff --git a/examples/wadespage/Dive.shtml b/examples/wadespage/Dive.shtml
@@ -0,0 +1,381 @@
+<html>
+<!-- CoffeeCup HTML Editor May 6, 2000 4:26:16 AM at Guam Airport -->
+<head>
+<title>Diving In Florida</title>
+ <meta name="description" content="Diving in Florida">
+ <meta name="keywords" content="scuba diving in Florida, dive sites in Florida, diving in the Florida springs, Ginnie Springs, drift diving, dive boats in Florida, manatee encounters, diving West Palm Beach, diving Boynton Beach">
+ <link rel="Stylesheet" type="text/css" href="Divetest.css">
+</head>
+<body leftmargin=0 topmargin=0 marginheight=0 marginwidth=0>
+
+<!-- table for navbar text and icons-->
+<table border=0 cellspacing=0 cellpadding=0 bgcolor=000080>
+<tr>
+<td width=40><img src="i.gif" height=20 width=40 hspace=0 align=left border=0></td>
+<td width=84><img src="wp_ntop.gif" height=26 width=84></td>
+<td width=145 valign=center><FONT FACE="Century Gothic" SIZE=3 COLOR="FFFFFF">wadespage<FONT COLOR="FF0000">.com</td>
+
+<td width=59><img src="i.gif" height=20 width=59 hspace=0 align=left border=0></td>
+<td width=70><img src="i.gif" height=20 width=70 hspace=0 align=left border=0></td>
+<td width=66><img src="i.gif" height=20 width=60 hspace=0 align=left border=0></td>
+<td width=88><img src="i.gif" height=20 width=60 hspace=0 align=left border=0></td>
+<td width=80><img src="i.gif" height=20 width=60 hspace=0 align=left border=0></td>
+<td width=71><img src="i.gif" height=20 width=60 hspace=0 align=left border=0></td>
+<td width=57><img src="i.gif" height=20 width=60 hspace=0 align=left border=0></td>
+</tr>
+<tr>
+<td><img src="i.gif" height=10 width=40 hspace=0 align=left ></td>
+<td align=left><img src="wp_nbot.gif" height=16 width=84></td>
+<td align=left><img src="wp_pline.gif" height=16 width=145></td>
+<td align=left><a href="index.shtml"><img src="Home_nbg.gif" width="59" height="16" alt="" border="0"></a></td>
+<td align=left><a href="Boat.shtml"><img src="Boating_nbg.gif" width="70" height="16" alt="" border="0"></a></td>
+
+<td align=left><a href="Dive.shtml"><img src="Diving_rednoline.gif" width="66" height="16" alt="" border="0"></a></td>
+<td align=left><a href="UWPhoto.shtml"><img src="UWPhotos_nbg.gif" width="88" height="16" alt="" border="0"></a></td>
+<td align=left><a href="UWVideo.shtml"><img src="UWVideo_nbg.gif" width="80" height="16" alt="" border="0"></a></td>
+<td align=left><a href="Report.shtml"><img src="Reports_nbg.gif" width="71" height="16" alt="" border="0"></a></td>
+<td align=left><a href="CFOA.shtml"><img src="CFOA_nbg.gif" width="57" height="16" alt="" border="0"></a></td>
+</tr>
+</table>
+
+<!-- table for main text table and sidebar menu table -->
+<table border=0 cellspacing=0 cellpadding=0 bgcolor=000080>
+<tr>
+<td valign=top>
+
+<!-- table for sidebar menu text -->
+<table border=0 cellspacing=0 cellpadding=0 bgcolor=000080 valign=top>
+<!-- adjust height of any of the i.gifs below to move light blue field lower -->
+<tr>
+<td><img src="i.gif" height=20 width=8 hspace=0 align=left border=0></td>
+<td><img src="i.gif" height=20 width=15 hspace=0 align=left border=0></td>
+<td><img src="i.gif" height=20 width=5 hspace=0 align=left border=0></td>
+<td><img src="i.gif" height=20 width=100 hspace=0 align=left border=0></td>
+<td><img src="i.gif" height=20 width=15 hspace=0 align=left border=0></td>
+<td><img src="i.gif" height=20 width=8 hspace=0 align=left border=0></td>
+</tr>
+
+<td> <br></td>
+<td> <br></td>
+<td colspan=2 align=center><FONT FACE="Tahoma" SIZE=5 COLOR="FF0000"><b>Dive <br>Pages<b></font></td>
+<td> <br></td>
+<td > <br></td>
+
+<tr>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c1nb.gif" height=15 width=15 hspace=0></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c2nb.gif" height=15 width=15 hspace=0></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2 ><a href="D800DS00RF00.shtml"><font color="FF0000"><b><u>Diving in Florida</u></b></font></a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td colspan=2 bgcolor=C0D2FF><a href="D800DS01RF00.shtml">Ocean Diving</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS01RF01.shtml">Diving Styles</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS01RF02.shtml">West Palm Sites</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS01RF03.shtml">Boynton Sites</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS01RF04.shtml">Dive Boats</a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS02RF00.shtml">Springs Diving</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS02RF01.shtml">Ginnie Springs</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS02RF02.shtml">Devil's Den</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS02RF03.shtml">Blue Grotto</a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td class=m1> <br></td>
+<td class=m1 colspan=3><a href="D800DS06RF01.shtml">Blue Heron Bridge</a><br><br></td>
+<td> <br></td>
+</tr>
+
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS04RF00.shtml">Wreck Diving</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS04RF00.shtml">The Empire Mica</a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS06RF00.shtml">Manatees</a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS05RF00.shtml">Travel Reports</a><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS05RF00.shtml">Diving Palau</a><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS05RF01.shtml">Diving Truk</a><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td bgcolor=C0D2FF><a href="D800DS05RF02.shtml">Diving Hawaii</font></a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS07RF00.shtml">GPS While Diving</a><br><br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2><a href="D800DS03RF00.shtml">Coming Soon</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td><img src="i.gif" height=2 width=2></td>
+<td bgcolor=C0D2FF><img src="c4nb.gif" height=15 width=15></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="c3nb.gif" height=15 width=15></td>
+<td><img src="i.gif" height=2 width=2></td>
+</tr>
+<tr>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c1nb.gif" height=15 width=15 hspace=0></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c2nb.gif" height=15 width=15 hspace=0></td>
+<td > <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2 align=center><a href="http://www.wadespage.com/cgi/Ultimate.cgi?action=intro&category=2">Dive Reports <br> Bulletin Board</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+</tr>
+<tr>
+<td><img src="i.gif" height=2 width=2></td>
+<td bgcolor=C0D2FF><img src="c4nb.gif" height=15 width=15></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="c3nb.gif" height=15 width=15></td>
+<td><img src="i.gif" height=2 width=2></td>
+</tr>
+<tr>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+<td> <br></td>
+</tr>
+<tr>
+<td> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c1nb.gif" height=15 width=15 hspace=0></td>
+<td bgcolor=C0D2FF colspan=2> <br></td>
+<td valign=top bgcolor=C0D2FF><img src="c2nb.gif" height=15 width=15 hspace=0></td>
+<td > <br></td>
+</tr>
+<td> <br></td>
+<td bgcolor=C0D2FF> <br></td>
+<td bgcolor=C0D2FF colspan=2 align=center><a href="mailto:w_pemberton@sprynet.com">Send Email</a></td>
+<td bgcolor=C0D2FF> <br></td>
+<td > <br></td>
+<tr>
+<td><img src="i.gif" height=2 width=2></td>
+<td bgcolor=C0D2FF><img src="c4nb.gif" height=15 width=15></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="i.gif" height=2 width=10></td>
+<td bgcolor=C0D2FF><img src="c3nb.gif" height=15 width=15></td>
+<td><img src="i.gif" height=2 width=2></td>
+</tr>
+</table>
+
+</td><!-- closes column with sidebar menu in it -->
+<td valign=top> <!-- opens column for main text -->
+<table border=0 cellspacing=0 cellpadding=0 bgcolor=EAEAD0>
+
+<td width=610 valign=top><img src="c1nby.gif" height=15 width=15><img src="i.gif" height=15 width=580><img src="c2nby.gif" height=15 width=15>
+ <Font face=tahoma color=000080 size=4><b>Diving in Florida.</font><br><br>
+<table cellspacing=0 cellpadding=0 border=0>
+<tr>
+<td width="350"><p>
+"I'm going to be in Orlando for a week of vacation."<br>
+"Is there any diving nearby?" <br><br>
+I live in Orlando, Florida, the tourist center of the known
+universe. I get these questions frequently either in person, or
+from email and newsgroups. The dive pages of WadesPage
+are to share the information that I've learned over the years
+as where to dive and which operators I use when diving here in
+Florida. With the ocean to the southeast and the springs northwest,
+there's certain to be something of interest.<br><br></td>
+<td width=260 align=center valign=top>
+ <img src="Boynton/Wp0205Dm.jpg" border=1 height=160 width=240 alt="Stingray"><br>
+ <font face="Arial" size=1 color=000080>A big stingray on a Boynton reef.</font></td>
+</tr>
+</table>
+<table cellspacing=0 cellpadding=0 border=0>
+<tr>
+ <td width=610><H5>World class either direction.</H5><p>
+Orlando is located within 3 hours of two different world class diving environments.
+Travel in either direction is nearly all interstate or turnpike,
+so it's easy to do a one day dive trip out of Orlando. <br><br>
+To the southeast are the gulfstream warmed coasts of West Palm and Boynton Beaches.
+Drift diving in ocean waters that reach 84F in the summer lead to frequent
+sightings of turtles, moray eels, jacks, barracuda, grouper and an occasional shark.
+There are many large schools of grunts and snappers, and tropical fish of all sizes.
+The bright coral and sponge colors add to the show as the diver drifts along with the current
+on the 60 foot deep reefs. I believe the variety and quantity of underwater flora and
+fauna is as good here as any place in this part of the world, including the Carribbean.<br></td>
+</tr>
+</table>
+<br>
+<table cellspacing=0 cellpadding=0 border=0>
+<tr>
+<td width="250" align=right valign=top><img src="Dana/Dana_02M.jpg" border=1 height="160" width="240" ALT="Dana"><font face="Arial" size=1color=000080><center> Dana at Alexander Springs.</center></td>
+<td width="350"><p>
+In the opposite direction, to the northwest, is the limestone karst area,
+with its myriad of crystal clear springs and their cavern and cave systems.
+The springs areas offer fresh clear water of stunning visibility, interesting geology,
+easy staircase access, and year around 72F water temperature.
+They offer OW divers a sample of the overhead environment, and for those who
+suffer from mal de mer, there's no seasickness here. There are picnic tables for
+easy gearing up, and rental equipment for those who couldn't bring their own.
+C-cards are required for diving.<br><br></td>
+</tr>
+</table><br>
+<table cellspacing=0 cellpadding=0 border=0>
+<tr>
+<td width="600"><p>
+The Florida Keys also offer excellent diving for beginners through advanced, but need
+a multiple day trip to be enjoyed fully. For those inclined to take a boat trip,
+I'll soon add pages on diving around Grand Bahama, the Biminis, and the Abacos in the nearby
+Bahamas. If you can't make any of those, there's always the aquarium at EPCOT.
+While a bit pricey, it offers twice daily dives to small groups, and you
+don't even have to be a park visitor to do it.<br><br>
+Use the Diving Page menu to surf through your options.
+There's a lot of diving to be done in Florida.<br><br>
+<hr align="center" width="300"></td>
+</tr>
+</table>
+</td>
+</tr>
+<tr>
+<td width=610 valign=bottom><img src="c4nby.gif" height=15 width=15><img src="i.gif" height=5 width=580><img src="c3nby.gif" height=15 width=15></td>
+</tr>
+<tr>
+<td bgcolor=000080> <br></td>
+</tr>
+</table>
+</table>
+
+<!-- WiredMinds eMetrics tracking with Enterprise Edition V5.4 START -->
+<script type='text/javascript' src='https://count.carrierzone.com/app/count_server/count.js'></script>
+<script type='text/javascript'><!--
+wm_custnum='0eac260f473c6bcb';
+wm_page_name='Dive.shtml';
+wm_group_name='/services/webpages/w/a/wadespage.com/public';
+wm_campaign_key='campaign_id';
+wm_track_alt='';
+wiredminds.count();
+// -->
+</script>
+<!-- WiredMinds eMetrics tracking with Enterprise Edition V5.4 END -->
+</BODY>
+</HTML>+
\ No newline at end of file
diff --git a/fkik.html b/fkik.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Forward & Inverse Kinematics</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <b><a href="./fkik.html">Forward & Inverse Kinematics</a></b>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>Forward and Inverse Kinematics | 09.06.2018</h3>
+ <p>Forward and inverse kinematics were the most important software systems of my <a href="http://charlesbaptista.com/smart-lamp/">Smart Lamp</a> project.</p>
+ <p>Control of the lamp arm has two layers; the lowest level control layer that manages the PWM interface with the servos, and the kinematics layer, which is responsible for calculating how the arm needs to move to bring the light, or end-effector, to a desired position.</p>
+ <p>The kinematics layer has two parts, forward and inverse. Forward kinematics (FK), calculates the position of the end-effector given the position of each of link in the arm. Inverse kinematics (IK), does the opposite, it solves for the position of the arm given a goal position of the end-effector.</p>
+ <p>The kinematics system I wrote for this project is based on the <a href="https://en.wikipedia.org/wiki/Denavit%E2%80%93Hartenberg_parameters">Denavit-Hartenberg convention</a>. Denavit-Hartenberg is a method for describing the positions of links in an arm, and is commonly used in robot kinematics.</p>
+ <p>Under the Denavit-Hartenberg convention each link is assigned a frame of reference according to a set of rules:</p>
+ <ul>
+ <li>The Z<sub>i-1</sub>axis must be the axis of actuation for joint i.</li>
+ </ul>
+ <ul>
+ <li>The X<sub>i</sub> axis must be perpendicular to and intersect the Z<sub>i-1</sub> axis.</li>
+ </ul>
+ <ul>
+ <li>The Y<sub>i</sub> axis is derived from Z<sub>i</sub> and X<sub>i</sub> per the right-hand-rule.</li>
+ </ul>
+ <p>In the case of Smart Lamp’s arm they look like this:</p>
+ <p><img src="./imgs/DH_ex_iso-768x524.png" alt="DH_ex_iso" width="600" height="410"/></p>
+ <p>Once these frames are established each link’s position can be defined relative to the previous link using four parameters:</p>
+ <p><b>a</b> – <b>Link Length</b> – Distance from joint (i-1) to (i) on the X<sub>i</sub> axis</p>
+ <p><b>α</b>– <b>Link Twist</b> – Angle between Z<sub>i-1</sub> axis and Z<sub>i</sub> axis about the X<sub>i</sub> axis</p>
+ <p><b>d</b>– <b>Link Offset</b> – Distance from joint (i-1) to (i) on the Z<sub>i-1</sub> axis</p>
+ <p><b>θ</b>– <b>Joint Angle</b> – Angle between X<sub>i-1</sub> axis and X<sub>i</sub> axis about the Z<sub>i-1</sub> axis</p>
+ <p>Parameters <b>d</b> (Link Offset) and <b>θ</b> (Joint Angle) are the “joint variables” for a link and respectively represent prismatic and revolute actuation. </p>
+ <p>To solve the forward kinematics problem, these parameters are plugged into a homogeneous transformation matrix for each link. The homogeneous transform matrix is the product of four transformation matrices, rotation about Z<sub>(i-1)</sub>, translation along Z<sub>(i-1)</sub>, rotation about X<sub>i</sub>, and translation along X<sub>i</sub>.</p>
+ <p><img src="./imgs/HT_mat.png" alt="HT_mat" width="600" height="140"/></p>
+ <p>By multiplying the homogeneous transform matrices together the position of the end effector can be found with respect to the frame of reference associated with any previous link in the kinematic chain.</p>
+ <p>The last part of my FK system is handling the parallelogram four-bar joints in our arm. This type linkage causes the next link in the chain to rotate as the previous link moves, such that its angle relative to the floor remains fixed. The animations below demonstrate how this behavior differs between a regular joint and a four-bar linkage:</p>
+ <p><img src="./imgs/reg_rot.gif" alt="reg_rot" width="300" height="206" /> <img src="./imgs/4bar_rot.gif" alt="4bar_rot" width="300" height="206" /></p>
+ <p>To account for this in the FK system, the two four-bar links are flagged and whenever their position is updated they rotate the subsequent link an equal and opposite amount, to match the behavior of the real mechanism.</p>
+ <p>Solving IK is more complicated. For FK there is only one solution for any configuration of the arm; However for IK there can be multiple, one or no solutions for any desired position of the end-effector. I decided to use a rudimentary method called gradient following, which was acceptable for the scope of this project.</p>
+ <p>In this example, the arm needs to move from it’s current position at (13.7, 12.4) to a goal position of (8.0, 8.0).
+ <p><img src="./imgs/IK_demo_highlight-768x519.jpg" alt="IK_demo_highlight" width="600" height="406"/>
+ <p>To solve this problem the gradient following method tests how manipulating each joint affects distance from the goal position. The contour plot below shows the configuration space of the arm in this example. The axes represent the position of joints 1 & 3 (circled in red above), and the colors show distance in inches from the goal position at that point.</p>
+ <p><img src="./imgs/ik_plot.jpg" alt="ik_plot" width="600" height="578"/>
+ <p>By incrementing each joint independently and simulating the new position using the FK system the software can measure how adjusting each axis affects distance to the target. Using these measurements the software finds a new point closer to the goal, and repeats the process, while scaling down the increment as it approaches the goal.</p>
+ <p>Looking at the blue line on the plot you can see how it “follows the gradient” of the configuration space to find the solution.</p>
+</div>
+
+</body>
+</html>
diff --git a/imgs/4bar_rot.gif b/imgs/4bar_rot.gif
Binary files differ.
diff --git a/imgs/DH_ex_iso-768x524.png b/imgs/DH_ex_iso-768x524.png
Binary files differ.
diff --git a/imgs/HT_mat.png b/imgs/HT_mat.png
Binary files differ.
diff --git a/imgs/IK_demo_highlight-768x519.jpg b/imgs/IK_demo_highlight-768x519.jpg
Binary files differ.
diff --git a/imgs/cropped-screen1.png b/imgs/cropped-screen1.png
Binary files differ.
diff --git a/imgs/cropped-screen3-2.png b/imgs/cropped-screen3-2.png
Binary files differ.
diff --git a/imgs/example-rb_tree-300x174.png b/imgs/example-rb_tree-300x174.png
Binary files differ.
diff --git a/imgs/example-rb_tree_restore.png b/imgs/example-rb_tree_restore.png
Binary files differ.
diff --git a/imgs/example-tree-300x152.png b/imgs/example-tree-300x152.png
Binary files differ.
diff --git a/imgs/example-tree-insert-300x152.png b/imgs/example-tree-insert-300x152.png
Binary files differ.
diff --git a/imgs/ik_plot.jpg b/imgs/ik_plot.jpg
Binary files differ.
diff --git a/imgs/rb_example2.png b/imgs/rb_example2.png
Binary files differ.
diff --git a/imgs/reg_rot.gif b/imgs/reg_rot.gif
Binary files differ.
diff --git a/imgs/screen2-768x344.png b/imgs/screen2-768x344.png
Binary files differ.
diff --git a/imgs/screen4-768x329.png b/imgs/screen4-768x329.png
Binary files differ.
diff --git a/imgs/screen6-1-768x432.png b/imgs/screen6-1-768x432.png
Binary files differ.
diff --git a/imgs/screen6-300x297.png b/imgs/screen6-300x297.png
Binary files differ.
diff --git a/imgs/search_time1.png b/imgs/search_time1.png
Binary files differ.
diff --git a/imgs/search_time2.png b/imgs/search_time2.png
Binary files differ.
diff --git a/imgs/tapestry_banner.png b/imgs/tapestry_banner.png
Binary files differ.
diff --git a/imgs/unbalanced-tree-300x237.png b/imgs/unbalanced-tree-300x237.png
Binary files differ.
diff --git a/index.html b/index.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Home</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <b><a href="./index.html">Home</a></b>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>About Me</h3>
+ <p>I'm Charles Baptista and this is my website. I'm a multidisciplinary engineer aspiring to independence and mastery.</p>
+ <p>I write about projects I'm working on. Maybe the things I've learned will be useful to you.</p>
+ <p>I'm a corporate worker currently in the service of <a href="https://www.berkshiregrey.com>">Berkshire Grey</a> as a field engineer.
+ <br>I've previously worked at <a href="http://www.cytonome.com/">Cytonome</a>, <a href="http://www.sharkninja.com/">SharkNinja</a> & <a href="http://www.ydreams.com/">YDreams Robotics</a>.
+ <br>I graduated from <a href="https://wit.edu/">Wentworth Institute of Technology</a> with a BSME in 2018. </p>
+ <p>You can email me at <a href=mailto:charles@charlesbaptista.com>charles@charlesbaptista.com</a>.</p>
+</div>
+
+</body>
+</html>
diff --git a/links.html b/links.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Links</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <b><a href="./links.html">Links</a></b>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>Links</h3>
+ <p>Links to interesting places; just for fun.</p>
+ <p>
+ <a href=http://archives.nd.edu/whitaker/words.htm>archives.nd.edu/whitaker/words.htm</a><br>
+ <a href=http://homestarrunner.com/>homestarrunner.com/</a><br>
+ <a href=https://libreboot.org/>libreboot.org/</a><br>
+ <a href=https://sdp-si.com/eStore/CenterDistanceDesigner>sdp-si.com/eStore/CenterDistanceDesigner</a><br>
+ <a href=http://simonstalenhag.se/>simonstalenhag.se/</a><br>
+ <a href=https://typeof.net/Iosevka/>typeof.net/Iosevka/</a><br>
+ ssh bit@whisper.onthewifi.com<br>
+ <a href="https://www.wiby.me">wiby.me</a><br>
+ </p>
+</div>
+
+</body>
+</html>
diff --git a/models.html b/models.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Models</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <a href="./tapestry.html">Tapestry</a>
+ <b><a href="./models.html">Models</a></b>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>Models</h3>
+ <p>A portfolio of CAD models. Some have general utility, others are just exhibits.</p>
+ <div id="shown"><label for="Conduit_cb"><b>[+] Conduit Elbow</b></label></div>
+ <input type="checkbox" id="Conduit_cb" style="display:none;">
+ <div id="hidden">
+ <p>I had cause to mount one of <a href=hoses.com>these hoses</a> under a table.
+ If you do too, I've got you covered.</p>
+
+ <p>[ <a href="elbow.stl">elbow.stl</a> ] [ <a href="elbow.sldprt">elbow.sldprt</a> ]</p>
+ </div>
+ <br>
+ <div id="shown"><label for="Odroid_cb"><b>[+] ODROID-XU4 Mount</b></label></div>
+ <input type="checkbox" id="Odroid_cb" style="display:none;">
+ <div id="hidden">
+ <p>A cradle for wall mounting an ODROID-XU4. It's compatible with the
+ now discontinued <a href=https://www.youtube.com/watch?v=GvqoWKBJDsA>
+ Shapedmedia XU4 Aluminmum Cooling Case</a>.</p>
+
+ <p>
+ [ <a href="elbow.stl">odroid_cradle.stl</a> ]
+ [ <a href="elbow.sldprt">odroid_cradle.sldprt</a> ]
+ </p>
+ </div>
+ <br>
+ <div id="shown"><label for="Dish_cb"><b>[+] Dish Scrubber</b></label></div>
+ <input type="checkbox" id="Dish_cb" style="display:none;">
+ <div id="hidden">
+ <p>An electric dish scrubber prototype assembly. It features a tricky
+ gearbox that reverses the brush's direction every half rotation.</p>
+
+ <p>[ <a href="scrub.zip">scrubber.zip</a> ] </p>
+ </div>
+ <br>
+ <div id="shown"><label for="NUTRONs_cb"><b>[+] NUTRONs</b></label></div>
+ <input type="checkbox" id="NUTRONs_cb" style="display:none;">
+ <div id="hidden">
+ <p>In highschool I participated in the FIRST robotics competition on team
+ 125, the <a href=https://www.nutrons.com/>NUTRONS</a>.</p>
+ <p>This was a formative experience; I wouldn't be where I am without it.</p>
+ <p>The mentors who freely gave hours upon hours of their time to teach me
+ hold my deepest, sincerest, gratitude and respect.</p>
+
+ <p>
+ [ <a href="elbow.stl">minibotII.zip</a> ]
+ [ <a href="elbow.sldprt">minibotIII.zip</a> ]
+ [ <a href="elbow.sldprt">launcher.zip</a> ]
+ [ <a href="elbow.sldprt">intake.zip</a> ]
+ </p>
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/rbtree.html b/rbtree.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Red-Black Trees</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <b><a href="./rbtree.html">Red Black Trees</a></b>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>Red-Black Trees | 12.22.2016</h3>
+ <p>The latest system I wrote for my game engine project is my own Red-Black trees. This served both to create a powerful and useful new tool for my engine and as a great opportunity to learn about data structures.</p>
+ <p>Red-Black trees are a form of balanced binary tree. A binary tree is a form of linked list where linked nodes are sorted based on the value of a numerical item they hold. An example of a binary tree is shown here:</p>
+ <p><img src="./imgs/example-tree-300x152.png" alt="example tree" width="300" height="152"</p>
+ <p>Every number in this tree represents a node, which stores the number shown and links to two other nodes. When a new node is inserted into the tree it starts at the top node, 10. If the number in the new node is larger than the top node it is passed to the right, if it’s smaller it’s passed to the left. This process is repeated at each node until the new node gets to an empty spot where is then stored in the tree.</p>
+ <p>If a 16 were inserted into the above tree it would be passed right to 15 from 10 (16>10), then right from 15 to 17 (16>15) then left from 17 to the empty spot (16<17).</p>
+ <p><img src="./imgs/example-tree-insert-300x152.png" alt="example tree insert" width="300" height="152"</p>
+ <p>When nodes are inserted in this pattern it is fast to search for them in the tree. Rather than just checking each number until finding the target, the tree can be searched in the same pattern as nodes are inserted (eg. To find 7 the program would check (7<10) -> go left to 5, (7>5) -> go right to find 7). Because of this sorting, the majority of the nodes can be eliminated from the search without being checked.</p>
+ <p>This method is much faster and scales much better to large data sets, than simply iterating through an entire array as long as the tree is relatively “balanced”. A tree is more “balanced” the more evenly the nodes are distributed among the branches. The previous example tree in the most unbalanced state would be:</p>
+ <p><img src="./imgs/unbalanced-tree-300x237.png" alt="unbalanced tree" width="300" height="237"</p>
+ <p>This tree contains all the same data and follows the same rules as the example tree but searching for the data is the same as searching for the data in an array because the target number is always to the right so effectively the search is just iterating over the numbers. Each step of the search only eliminates one node from the search until it finds the right node.</p>
+ <p>This is where the Red-Black aspect is introduced. Red-Black is an algorithm for balancing the tree as nodes are inserted.</p>
+ <p>The Red-Black algorithm follows a few simple rules:</p>
+ <ol>
+ <li>Each node is labeled either red or black</li>
+ <li>The root node is black</li>
+ <li>If a node is red, it’s child nodes are black</li>
+ <li>NULL nodes with no number are black</li>
+ <li>Every path from the root node to a bottom node has the same number of black nodes (equal “black height”)</li>
+ </ol>
+ <p><img src="./imgs/example-rb_tree-300x174.png" alt="unbalanced rb_tree" width="300" height="174"</p>
+ <p>The tree above is an example of a red black tree. All nodes are red or black, the root 15 is black, all red nodes have only black children and each path from 15 to the bottom has an equal black height of 2 (eg. 15 and 17, 15 and 10, 15 and 5).</p>
+ <p>When a new node is inserted it always starts as red, and is inserted the same way it normally is in an unbalanced binary tree.</p>
+ <p>Once it gets to the bottom different cases can occur and are resolved to restore the red black rules. In the process of doing this the tree becomes balanced.</p>
+ <p>The restoration functions make use of changing the color of nodes and what are called “rotations”. A rotation operation takes a sub-tree and rotates the root node left or right. This does not violate the binary tree rules. A combination of these operations can restore the tree from any case to a balanced state.</p>
+ <p><img src="./imgs/example-rb_tree_restore.png" alt="example rb_tree_restore" width="918" height="174"</p>
+ <p>The example above shows a Red-Black restore operation including a right rotation on 15</p>
+ <p>There are four possible cases that can occur after an insert.</p>
+ <p>The first is that the new node ends up as the child of a black node. No rules will be violated in this case and no corrections are needed.</p>
+ <p>The second is that the new node is the child of a red parent and has a red uncle node. This case can be seen in the 1<sup>st</sup> stage of the above image (2 is the red parent, 6 is the red uncle). In this case the color of the parent, uncle and grandparent nodes are swapped.</p>
+ <p>The third case is that the new node has a red parent, a black uncle, and is the left child of a left child or is the right child of a right child. This case can be seen in the 2<sup>nd</sup> stage of the above image (7 is a red parent, 10 is a black uncle. 7 is the left child of 10 and 5 is the left child of 7). In this case the new node’s grandparent is rotated away from the new node (rotate right in the left-left case, or left in the right-right case). Then the color of the grand parent and parent node are swapped.</p>
+ <p>The fourth case it that the new node has a red parent, a black uncle and is the left child of a right child or the right child of a left child. In this case the parent is rotated away from the child. This will create case 3 which is resolved as above.</p>
+ <p><img src="./imgs/rb_example2.png" alt="rb_example2" width="918" height="174"</p>
+ <p>The above example shows a restore using cases 4 and 3.</p>
+ <p>Performing these operations keeps the tree mostly balanced, keeping search times short.</p>
+ <p>To demonstrate the improvement in search time and scalability I timed searches in my red-black trees and in standard arrays of the same number of elements to compare. I collected the data by timing one million search operations for random items in an array and tree of the same size. I then divided by the number of searches and plotted the results.</p>
+ <p><img src="./imgs/search_time1.png" alt="search_time1" width="778" height="497"</p>
+ <p><img src="./imgs/search_time2.png" alt="search_time2" width="778" height="497"</p>
+ <p>The first graph clearly demonstrates the greatly increased scalability of the red-black trees over standard arrays. You can the that the red-black trees, which scale logarithmically with size, quickly become much faster than arrays, which scale linearly, as more elements are added to the structures. The second graph shows a closeup of the data for structures of less than 200 elements and clearly shows the point where the logarithmic scaling tree search times level off and surpass the speed of the array searches.</p>
+ <p>It felt pretty good to finally see my trees fully functional and to watch them totally blow away the arrays and vectors I’ve been using up until now.</p>
+</div>
+
+</body>
+</html>
diff --git a/style.css b/style.css
@@ -0,0 +1,93 @@
+header {
+ height: 5em;
+ padding: 0.5em 1em 0 1em;
+ background: #941;
+}
+
+body {
+ margin:0;
+ padding:0;
+ background:#DDD;
+}
+
+header a {
+ text-decoration: none;
+ color: #FFF;
+}
+
+img {
+ width=100%;
+ height= 100%;
+}
+
+#top_nav {
+ height: 1em;
+ padding: 0.3em;
+ font-size:14px;
+ text-align: left;
+ border-bottom: 1px dotted;
+ background-color: #578;
+}
+
+#top_nav a {
+ text-decoration: none;
+ color: #FFF;
+ padding: 0.3em 1em 0.15em 1em;
+}
+
+#top_nav a:hover {
+ color: #C00;
+ background-color: #ACD
+}
+
+#side_nav {
+ float: right;
+ height: 100vh;
+ font-size:14px;
+ border-left: 1px dotted;
+ text-align: left;
+}
+
+#side_nav li {
+ list-style: none;
+}
+
+#side_nav a {
+ display: block;
+ text-decoration: none;
+ color: #07E;
+ padding: 0.3em 1em 0.3em 1em;
+ margin: 0;
+}
+
+#side_nav a:hover {
+ color: #05C;
+ background-color: #EEE;
+}
+
+#center_content {
+ width: 75%;
+ font-size:14px;
+ padding: 0 0 0 20px;
+}
+
+#center_content a {
+ color: #07E;
+}
+
+#center_content a:hover {
+ color: #05C;
+}
+
+#hidden {
+ display: none;
+}
+:checked + #hidden {
+ display: block;
+}
+#shown {
+ display: block;
+}
+:checked + #shown {
+ display: none;
+}
diff --git a/tapestry.html b/tapestry.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Tapestry</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <a href="./index.html">Home</a>
+ <b><a href="./tapestry.html">Tapestry</a></b>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>Tapestry Engine</h3>
+ <p><img src="./imgs/cropped-screen1.png"/></p>
+ <p>The Tapestry game engine is a 2D side-scroller engine written in C++ using the <a href="https://www.libsdl.org/" target="_blank">SDL2</a> library. Over the year+ of time I’ve dedicated to the project it’s grown from a window with a couple static images drifting around to a complex and powerful program that features actors, animation, sound, terrain & water physics, actor collisions, level loading, events, and particles among a number of other systems.</p>
+ <p><img src="./imgs/screen2-768x344.png" width="485" height="217"/></p>
+ <p><img src="./imgs/screen6-300x297.png" width="218" height="216"/></p>
+ <p>Developing this program has been an extremely fun and instructive process. It has presented me with a wide range of unique problems to solve and systems to engineer; from text wrapping and scrolling to writing my own <a href="http://charlesbaptista.com/2016/12/22/red-black-trees/">red-black trees</a> to JSON based level loading. This project continuously pushes my horizons as a programmer and always presents new challenges.</p>
+ <p><img src="./imgs/screen6-1-768x432.png" width="699" height="394"/></p>
+ <p><img src="./imgs/screen4-768x329.png" width="698" height="298"/></p>
+ <p> </p>
+ <p>All the images shown are screenshots from levels created in the engine. Art assets created by <a href="https://sofiabaptistacrafts.wordpress.com/">Sofia Baptista</a>.</p>
+ <p> </p>
+</div>
+
+</body>
+</html>
diff --git a/template.html b/template.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Charles Baptista | Home</title>
+ <meta charset="utf-8">
+ <link rel='stylesheet' type='text/css' href='style.css'>
+</head>
+
+<body>
+<header>
+ <h1><a href="./index.html">Charles Baptista</a></h1>
+</header>
+
+<div id="top_nav">
+ <b><a href="./index.html">Home</a></b>
+ <a href="./tapestry.html">Tapestry</a>
+ <a href="./models.html">Models</a>
+ <a href="./dotfiles.html">dotfiles</a>
+ <a href="./links.html">Links</a>
+</div>
+
+<div id="side_nav">
+ <br>
+ <li>
+ <a href="./fkik.html">Forward & Inverse Kinematics</a>
+ <a href="./rbtree.html">Red Black Trees</a>
+ </li>
+</div>
+
+<div id="center_content">
+ <h3>About Me</h3>
+ <p>I'm a corporate bugman currently employed as a field service engineer for <a href="https://www.berkshiregrey.com>">Berkshire Grey</a>.
+ <br>I've previously worked at <a href="http://www.cytonome.com/">Cytonome</a>, <a href="http://www.sharkninja.com/">SharkNinja</a> & <a href="http://www.ydreams.com/">YDreams Robotics</a>.
+ <br>I graduated from <a href="https://wit.edu/">Wentworth Institute of Technology</a> with a BSME in 2018. </p>
+</div>
+
+</body>
+</html>