diff --git a/README.markdown b/README.markdown
new file mode 100644
index 0000000..c765850
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,576 @@
+Vicious
+=======
+Vicious is a modular widget library for the "awesome" window manager,
+derived from the "Wicked" widget library. It has some of the old
+Wicked widget types, a few of them rewritten, and a good number of new
+ones:
+
+ - http://git.sysphere.org/vicious/about/
+
+Vicious widget types are a framework for creating your own awesome
+widgets. Vicious contains modules that gather data about your system,
+and a few helper functions that make it easier to register timers,
+suspend widgets and so on.
+
+For now Vicious doesn't depend on any third party Lua libraries, to
+make it easier to install and use. That means some system utilities
+are used instead, where available:
+
+ - hddtemp for the HDD Temperature widget type
+ - alsa-utils for the Volume widget type
+ - wireless_tools for the Wireless widget type
+ - curl for widget types accessing network resources
+
+
+Usage
+-----
+To use vicious move it to your awesome configuration directory in
+*$XDG_CONFIG_HOME* (usually ~/.config):
+
+ $ mv vicious $XDG_CONFIG_HOME/awesome/
+
+Vicious will only load modules for widget types you intend to use in
+your awesome configuration, to avoid having useless modules sitting in
+your memory.
+
+Then add the following to the top of your rc.lua:
+
+ require("vicious")
+
+Once you create a widget (a textbox, graph or a progressbar) call
+vicious.register() to register it with Vicious:
+
+ vicious.register(widget, wtype, format, interval, warg)
+
+**widget**
+
+ - widget created with widget() or awful.widget() (in case of a
+ graph or a progressbar)
+
+**wtype**
+
+ - one of the available widget types, see below for a list
+
+**format**
+
+ - string argument or a function
+ - $1, $2, $3... will be replaced by their respective value
+ returned by the widget type, some widget types return tables
+ with string keys, in that case use: ${key}
+ - function
+ - function(widget, args) can be used to manipulate data
+ returned by the widget type, more about this below
+
+**interval**
+
+ - number of seconds between updates of the widget, 2s by
+ default, also read the "Power" section below
+
+**warg**
+ - some widget types require an argument to be passed, for example
+ the battery ID
+
+
+Other functions
+---------------
+**Unregister a widget**:
+
+ vicious.unregister(widget, keep)
+
+if keep is true widget will be suspended, waiting to be activated
+
+**Suspend all widgets**:
+
+ vicious.suspend()
+
+[example automation script](http://sysphere.org/~anrxc/local/sources/lmt-vicious.sh) for the "laptop-mode-tools" start-stop module:
+
+**Restart suspended widgets:**
+ vicious.activate(widget)
+
+if widget is provided only that widget will be activated
+
+**Enable caching of a widget type:**
+
+ vicious.cache(wtype)
+
+enable caching of values returned by a widget type
+
+**Force update of widgets:**
+
+ vicious.force({ widget, })
+
+widget argument is a table with one or more widgets that will be updated
+
+
+Widget types
+------------
+Widget types consist of worker functions that take the *format*
+argument given to vicious.register as the first argument, *warg* as
+the second, and return a table of values to insert in the format
+string.
+
+**vicious.widgets.cpu**
+
+ - provides CPU usage for all available CPUs/cores
+ - returns 1st value as usage of all CPUs/cores, 2nd as usage of
+ first CPU/core, 3rd as usage of second CPU/core etc.
+
+**vicious.widgets.cpuinf**
+
+ - provides speed and cache information for all available CPUs/cores
+ - returns a table with string keys, using CPU ID as a base:
+ {cpu0 mhz}, {cpu0 ghz}, {cpu0 kb}, {cpu0 mb}, {cpu1 mhz} etc.
+
+**vicious.widgets.cpufreq**
+
+ - provides freq, voltage and governor info for a requested CPU
+ - takes the CPU ID as an argument, i.e. "cpu0"
+ - returns 1st value as frequency of requested CPU in MHz, 2nd in
+ GHz, 3rd as voltage in mV, 4th as voltage in V and 5th as the
+ governor state
+
+**vicious.widgets.thermal**
+
+ - provides temperature levels of ACPI and coretemp thermal zones
+ - takes the thermal zone as an argument, i.e. "thermal_zone0", or a
+ table with 1st field as thermal zone and 2nd as data source -
+ available data sources are "proc", "core" and "sys" - which is the
+ default when only the zone is provided
+ - returns 1st value as temperature of requested thermal zone
+
+**vicious.widgets.uptime**
+
+ - provides system uptime and load information
+ - returns 1st value as uptime in days, 2nd as uptime in hours, 3rd
+ as uptime in minutes, 4th as load average for past 1 minute, 5th
+ for 5 minutes and 6th for 15 minutes
+
+**vicious.widgets.bat**
+
+ - provides state, charge, and remaining time for a requested battery
+ - takes battery ID as an argument, i.e. "BAT0"
+ - returns 1st value as state of requested battery, 2nd as charge
+ level in percent and 3rd as remaining (charging or discharging)
+ time
+
+**vicious.widgets.mem**
+
+ - provides RAM and Swap usage statistics
+ - returns 1st value as memory usage in percent, 2nd as memory usage,
+ 3rd as total system memory, 4th as free memory, 5th as swap usage
+ in percent, 6th as swap usage, 7th as total system swap, 8th as
+ free swap and 9th as memory usage with buffers and cache
+
+**vicious.widgets.os**
+
+ - provides operating system information
+ - returns 1st value as the operating system in use, 2nd as the
+ release version, 3rd as your username, 4th the hostname, 5th as
+ available system entropy and 6th value as available entropy in
+ percent
+
+**vicious.widgets.fs**
+
+ - provides file system disk space usage
+ - takes an (optional) argument which, if true, includes remote file
+ systems, only local file systems are included by default
+ - returns a table with string keys, using mount points as a base:
+ {/ size_mb}, {/ size_gb}, {/ used_mb}, {/ used_gb}, {/ used_p},
+ {/ avail_mb}, {/ avail_gb}, {/ avail_p}, {/home size_mb} etc.
+
+**vicious.widgets.dio**
+
+ - provides I/O statistics for all available storage devices
+ - returns a table with string keys: {sda total_s}, {sda total_kb},
+ {sda total_mb}, {sda read_s}, {sda read_kb}, {sda read_mb},
+ {sda write_s}, {sda write_kb}, {sda write_mb}, {sdb1 total_s} etc.
+
+**vicious.widgets.raid**
+
+ - provides state information for a requested RAID array
+ - takes the RAID array ID as an argument
+ - returns 1st value as the number of assigned, and 2nd as active,
+ devices in the array
+
+**vicious.widgets.hddtemp**
+
+ - provides hard drive temperatures using the hddtemp daemon
+ - takes the hddtemp listening port as an argument, or defaults to
+ port 7634
+ - returns a table with string keys, using hard drives as a base:
+ {/dev/sda} and {/dev/sdc} for example
+
+**vicious.widgets.net**
+
+ - provides state and usage statistics of all network interfaces
+ - returns a table with string keys, using net interfaces as a base:
+ {eth0 carrier}, {eth0 rx_b}, {eth0 tx_b}, {eth0 rx_kb}, {eth0 tx_kb},
+ {eth0 rx_mb}, {eth0 tx_mb}, {eth0 rx_gb}, {eth0 tx_gb}, {eth0 down_b},
+ {eth0 up_b}, {eth0 down_kb}, {eth0 up_kb}, {eth0 down_mb},
+ {eth0 up_mb}, {eth0 down_gb}, {eth0 up_gb}, {eth1 rx_b} etc.
+
+**vicious.widgets.wifi**
+
+ - provides wireless information for a requested interface
+ - takes the network interface as an argument, i.e. "wlan0"
+ - returns a table with string keys: {ssid}, {mode}, {chan}, {rate},
+ {link}, {linp} and {sign}
+
+**vicious.widgets.mbox**
+
+ - provides the subject of last e-mail in a mbox file
+ - takes the full path to the mbox as an argument, or a table with
+ 1st field as path, 2nd as maximum lenght and 3rd (optional) as
+ widget name - if 3rd field is present scrolling will be used
+ - returns 1st value as the subject of the last e-mail
+
+**vicious.widgets.mboxc**
+
+ - provides the count of total, old and new messages in mbox files
+ - takes a table with full paths to mbox files as an argument
+ - returns 1st value as the total count of messages, 2nd as the count
+ of old messages and 3rd as the count of new messages
+
+**vicious.widgets.mdir**
+
+ - provides the number of new and unread messages in Maildir
+ structures/directories
+ - takes a table with full paths to Maildir structures as an argument
+ - returns 1st value as the count of new messages and 2nd as the
+ count of "old" messages lacking the Seen flag
+
+**vicious.widgets.gmail**
+
+ - provides count of new and subject of last e-mail on Gmail
+ - takes an (optional) argument, if it's a number subject will be
+ truncated, if a table, with 1st field as maximum lenght and 2nd
+ the widget name (i.e. "gmailwidget"), scrolling will be used
+ - keeps login information in the ~/.netrc file, example:
+ machine mail.google.com login user password pass
+ - returns a table with string keys: {count} and {subject}
+
+**vicious.widgets.org**
+
+ - provides agenda statistics for Emacs org-mode
+ - takes a table with full paths to agenda files, that will be
+ parsed, as an argument
+ - returns 1st value as count of tasks you forgot to do, 2nd as count
+ of tasks for today, 3rd as count of tasks for the next 3 days and
+ 4th as count of tasks to do in the week
+
+**vicious.widgets.pkg**
+
+ - provides number of pending updates on UNIX systems
+ - takes the distribution name as an argument, i.e. "Arch"
+ - returns 1st value as the count of available updates
+
+**vicious.widgets.mpd**
+
+ - provides Music Player Daemon information
+ - takes a table as an argument, 1st field should be the password (or
+ nil), 2nd the hostname (or nil) and 3rd port (or nil) - if no
+ argument is provided connection attempt will be made to localhost
+ port 6600 with no password
+ - returns a table with string keys: {volume}, {state}, {Artist},
+ {Title}, {Album}, {Genre} and optionally {Name} and {file}
+
+**vicious.widgets.volume**
+
+ - provides volume levels and state of requested ALSA mixers
+ - takes the ALSA mixer control as an argument, i.e. "Master",
+ optionally append the card ID or other options, i.e. "PCM -c 0"
+ - returns 1st value as the volume level and 2nd as the mute state of
+ the requested channel
+
+**vicious.widgets.weather**
+
+ - provides weather information for a requested station
+ - takes the ICAO station code as an argument, i.e. "LDRI"
+ - returns a table with string keys: {city}, {wind}, {windmph},
+ {windkmh}, {sky}, {weather}, {tempf}, {tempc}, {humid}, {press}
+
+**vicious.widgets.date**
+
+ - provides access to os.date, with optional time formatting provided
+ as the format string - using regular date sequences
+ - takes optional time offset, in seconds, as an argument for example
+ to calculate time zone differences, otherwise current time is
+ formatted
+ - returns the output of os.date, formatted by provided sequences
+
+
+Custom widget types
+-------------------
+Use any of the existing widget types as a starting point for your
+own. Write a quick worker function that does the work and plug it
+in. How data will be formatted, will it be red or blue, should be
+defined in rc.lua (or somewhere else, outside the actual module).
+
+Before writing a widget type you should check if there is already one
+in the contrib directory of Vicious. The contrib directory contains
+extra widgets you can use. Some are for less common hardware, and
+other were contributed by Vicious users. The contrib directory also
+holds widget types that were obsoleted or rewritten. Contrib widgets
+will not be imported by init unless you explicitly enable it.
+
+Richard Kolkovich, a FreeBSD user, published his vicious-fbsd
+branch. If you are also a BSD user you can find [his work.](http://git.sigil.org/vicious-fbsd/)
+
+Some users would like to avoid writing new modules. For them Vicious
+kept the old Wicked functionality, possibility to register their own
+functions as widget types. By providing them as the second argument to
+vicious.register. Your function can accept "format" and "warg"
+arguments, just like workers.
+
+
+Power and Caching
+-----------------
+When a lot of widgets are in use they, and awesome, can generate a lot
+of wake-ups and also be very expensive for system resources. This is
+especially important when running on battery power. It was a big
+problem with awesome v2 and widgets that used shell scripts to gather
+data, and with widget libraries written in languages like Ruby.
+
+Lua is an extremely fast and efficient programming language, and
+Vicious takes advantage of that. But suspending Vicious widgets is one
+way to prevent them from draining your battery, despite that.
+
+Update intervals also play a big role, and you can save a lot of power
+with a smart approach. Don't use intervals like: 5, 10, 30, 60... to
+avoid harmonics. If you take the 60-second mark as an example, all of
+your widgets would be executed at that point. Instead think about
+using only prime numbers, in that case you will have only a few
+widgets executed at any given time interval. When choosing intervals
+also consider what a widget actually does. Some widget types read
+files that reside in memory, others call external utilities and some,
+like the mbox widget, read big files.
+
+Vicious can also cache values returned by widget types. Caching
+enables you to have multiple widgets using the same widget type. With
+caching its worker function gets executed only once - which is also
+great for saving power.
+
+ - Some widget types keep internal data and if you call one multiple
+ times without caching, the widget that executes it first would
+ modify stored values. This can lead to problems and give you
+ inconsistent data. Remember it for widget types like CPU and
+ Network usage, which compare the old set of data with the new one
+ to calculate current usage.
+
+ - Widget types that require a widget argument to be passed should be
+ handled carefully. If you are requesting information for different
+ devices then caching should not be used, because you could get
+ inconsistent data.
+
+
+Security
+--------
+At the moment only one widget type (Gmail) requires auth. information
+in order to get to the data. In the future there could be more, and
+you should give some thought to the issue of protecting your data. The
+Gmail widget type by default stores login information in the ~/.netrc
+file, and you are advised to make sure that file is only readable by
+the owner. Other than that we can not force all users to conform to
+one standard, one way of keeping it secure, like in some keyring.
+
+First let's clear why we simply don't encrypt the login information
+and store it in ciphertext. By exposing the algorithm anyone can
+reverse the encryption steps. Some claim even that's better than
+plaintext but it's just security trough obscurity.
+
+Here are some ideas actually worth your time. Users that have KDE (or
+parts of it) installed could store their login information into the
+Kwallet service and request it via DBus from the widget type. It can
+be done with tools like "dbus-send" and "qdbus". The Gnome keyring
+should support the same, so those with parts of Gnome installed could
+use that keyring.
+
+Users of GnuPG (and its agent) could consider encrypting the netrc
+file with their GPG key. Trough the GPG Passphrase Agent they could
+then decrypt the file transparently while their session is active.
+
+
+Usage examples
+--------------
+Start with a simple widget, like date. Then build your setup from
+there, one widget at a time. Also remember that besides creating and
+registering widgets you have to add them to a wibox (statusbar) in
+order to actually display them.
+
+**Date widget**
+
+ datewidget = widget({ type = "textbox" })
+ vicious.register(datewidget, vicious.widgets.date, "%b %d, %R")
+
+updated every 2 seconds (the default interval), uses standard
+date sequences as the format string
+
+**Memory widget**
+
+ memwidget = widget({ type = "textbox" })
+ vicious.cache(vicious.widgets.mem)
+ vicious.register(memwidget, vicious.widgets.mem, "$1 ($2MB/$3MB)", 13)
+
+updated every 13 seconds, appends "MB" to 2nd and 3rd returned
+values and enables caching of this widget type
+
+**HDD temperature widget**
+
+ hddtempwidget = widget({ type = "textbox" })
+ vicious.register(hddtempwidget, vicious.widgets.hddtemp, "${/dev/sda} °C", 19)
+
+updated every 19 seconds, requests the temperature level of the
+{/dev/sda} key/disk and appends "°C" to the returned value, does
+not provide the port argument so default port is used
+
+**Mbox widget**
+
+ mboxwidget = widget({ type = "textbox" })
+ vicious.register(mboxwidget, vicious.widgets.mbox, "$1", 5, "/home/user/mail/Inbox")
+
+updated every 5 seconds, provides full path to the mbox as an
+argument
+
+**Battery widget**
+
+ batwidget = awful.widget.progressbar()
+ batwidget:set_width(8)
+ batwidget:set_height(10)
+ batwidget:set_vertical(true)
+ batwidget:set_background_color("#494B4F")
+ batwidget:set_border_color(nil)
+ batwidget:set_color("#AECF96")
+ batwidget:set_gradient_colors({ "#AECF96", "#88A175", "#FF5656" })
+ vicious.register(batwidget, vicious.widgets.bat, "$2", 61, "BAT0")
+
+updated every 61 seconds, requests the current battery charge
+level and displays a progressbar, provides "BAT0" battery ID as an
+argument
+
+**CPU usage widget**
+
+ cpuwidget = awful.widget.graph()
+ cpuwidget:set_width(50)
+ cpuwidget:set_background_color("#494B4F")
+ cpuwidget:set_color("#FF5656")
+ cpuwidget:set_gradient_colors({ "#FF5656", "#88A175", "#AECF96" })
+ vicious.register(cpuwidget, vicious.widgets.cpu, "$1", 3)
+
+updated every 3 seconds, feeds the graph with total usage
+percentage of all CPUs/cores
+
+
+Format functions
+----------------
+You can use a function instead of a string as the format parameter.
+Then you are able to check the value returned by the widget type and
+change it or perform some action. You can change the color of the
+battery widget when it goes below a certain point, hide widgets when
+they return a certain value or maybe use string.format for padding.
+
+ - Do not confuse this with just coloring the widget, in those cases
+ standard pango markup can be inserted into the format string.
+
+The format function will get the widget as its first argument, table
+with the values otherwise inserted into the format string as its
+second argument, and will return the text/data to be used for the
+widget.
+
+**Example**
+
+ mpdwidget = widget({ type = "textbox" })
+ vicious.register(mpdwidget, vicious.widgets.mpd,
+ function (widget, args)
+ if args["{state}"] == "Stop" then return ""
+ else return 'MPD: '..
+ args["{Artist}"]..' - '.. args["{Title}"]
+ end
+ end)
+
+hides the mpd widget when no song is playing, updated every 2
+seconds (the default interval)
+
+**Example**
+
+ uptimewidget = widget({ type = "textbox" })
+ vicious.register(uptimewidget, vicious.widgets.uptime,
+ function (widget, args)
+ return string.format("Uptime: %2dd %02d:%02d ", args[1], args[2], args[3])
+ end, 61)
+
+uses string.format for padding uptime values to a minimum amount
+of digits, updated every 61 seconds
+
+When it comes to padding it is also useful to mention how a widget can
+be configured to have a fixed width. You can set a fixed width on your
+textbox widgets by changing their .width field (by default width is
+automatically adapted to text width).
+
+**Example**
+
+ uptimewidget = widget({ type = "textbox" })
+ uptimewidget.width, uptimewidget.align = 50, "right"
+ vicious.register(uptimewidget, vicious.widgets.uptime, "$1 $2:$3", 61)
+
+forces a fixed width of 50px to the uptime widget, and aligns its
+text to the right
+
+Another use case are stacked graphs (aka multigraphs) which Vicious
+does not handle on its own at the moment, as it's hard to pass on
+color index arguments elegantly. But they are not unusable, far from
+it.
+
+**Example**
+
+ ctext = widget({ type = "textbox"})
+ cgraph = awful.widget.graph()
+ cgraph:set_width(100):set_height(20)
+ cgraph:set_stack(true):set_max_value(100)
+ cgraph:set_background_color("#494B4F")
+ cgraph:set_stack_colors({ "#FF5656", "#88A175", "#AECF96" })
+ vicious.register(ctext, vicious.widgets.cpu,
+ function (widget, args)
+ cgraph:add_value(args[2], 1) -- Core 1, color 1
+ cgraph:add_value(args[3], 2) -- Core 2, color 2
+ cgraph:add_value(args[4], 3) -- Core 3, color 3
+ end, 3)
+
+enables graph stacking/multigraph and plots usage of all three CPU
+cores on a single graph, the textbox "ctext" is just an empty
+placeholder, graph is updated every 3 seconds
+
+
+Other
+-----
+Read *"awesome"* manual pages:
+
+ - awesome(1) awesomerc(5)
+
+[Awesome widgets explained](http://awesome.naquadah.org/wiki/Widgets_in_awesome)
+
+[Example *"awesome"* configuration](http://git.sysphere.org/awesome-configs/)
+
+
+Authors
+-------
+Wicked written by:
+
+ - Lucas de Vries
+
+Vicious written by:
+
+ - Adrian C. (anrxc)
+
+Vicious contributors:
+
+ - Michael Unterkalmsteiner
+ - Martin Striz
+ - Benedikt Sauer
+ - Greg D.
+ - Henning Glawe
+ - Rémy C.
+ - Hiltjo Posthuma
+ - Hagen Schink
+ - Jörg Thalheim
+