+
+ Project maintained by soperd
+ Hosted on GitHub Pages — Theme by mattgraham
+
-
-
+
Introduction
This is a reflective piece on my Year 1 group project. Please view the code here.
The project is a chatbot written in Python 3 primarily for use with Discord. Current features include:
@@ -60,20 +78,15 @@
"port": 6379
}
}
-
This details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the run_discord.py script, this passes the discord configuration to the DiscordBot class constructor, which in turn calls ChatBot's constructor. If the optional parameter services is None then ChatBot's constructor then will find the services listed in config.json from the global_services and store them in the services class member. This was my attempt to "inject" services into the bot automatically.
+
This details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the run_discord.py script, this passes the discord configuration to the DiscordBot class constructor, which in turn calls ChatBot's constructor. If the optional parameter services :p is None then ChatBot's constructor then will find the services listed in config.json from the global_services and store them in the services class member. This was my attempt to "inject" services into the bot automatically.
DiscordBot is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.
Reflection
-
I think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the global_services dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.
-
-
-
-
+
I think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as :p the global_services dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.
+
-
+
+
+
diff --git a/javascripts/respond.js b/javascripts/respond.js
new file mode 100644
index 0000000..76bc260
--- /dev/null
+++ b/javascripts/respond.js
@@ -0,0 +1,779 @@
+if(typeof Object.create!=="function"){
+Object.create=function(o){
+function F(){
+};
+F.prototype=o;
+return new F();
+};
+}
+var ua={toString:function(){
+return navigator.userAgent;
+},test:function(s){
+return this.toString().toLowerCase().indexOf(s.toLowerCase())>-1;
+}};
+ua.version=(ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1];
+ua.webkit=ua.test("webkit");
+ua.gecko=ua.test("gecko")&&!ua.webkit;
+ua.opera=ua.test("opera");
+ua.ie=ua.test("msie")&&!ua.opera;
+ua.ie6=ua.ie&&document.compatMode&&typeof document.documentElement.style.maxHeight==="undefined";
+ua.ie7=ua.ie&&document.documentElement&&typeof document.documentElement.style.maxHeight!=="undefined"&&typeof XDomainRequest==="undefined";
+ua.ie8=ua.ie&&typeof XDomainRequest!=="undefined";
+var domReady=function(){
+var _1=[];
+var _2=function(){
+if(!arguments.callee.done){
+arguments.callee.done=true;
+for(var i=0;i<_1.length;i++){
+_1[i]();
+}
+}
+};
+if(document.addEventListener){
+document.addEventListener("DOMContentLoaded",_2,false);
+}
+if(ua.ie){
+(function(){
+try{
+document.documentElement.doScroll("left");
+}
+catch(e){
+setTimeout(arguments.callee,50);
+return;
+}
+_2();
+})();
+document.onreadystatechange=function(){
+if(document.readyState==="complete"){
+document.onreadystatechange=null;
+_2();
+}
+};
+}
+if(ua.webkit&&document.readyState){
+(function(){
+if(document.readyState!=="loading"){
+_2();
+}else{
+setTimeout(arguments.callee,10);
+}
+})();
+}
+window.onload=_2;
+return function(fn){
+if(typeof fn==="function"){
+_1[_1.length]=fn;
+}
+return fn;
+};
+}();
+var cssHelper=function(){
+var _3={BLOCKS:/[^\s{][^{]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,BLOCKS_INSIDE:/[^\s{][^{]*\{[^{}]*\}/g,DECLARATIONS:/[a-zA-Z\-]+[^;]*:[^;]+;/g,RELATIVE_URLS:/url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,REDUNDANT_COMPONENTS:/(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g,REDUNDANT_WHITESPACE:/\s*(,|:|;|\{|\})\s*/g,MORE_WHITESPACE:/\s{2,}/g,FINAL_SEMICOLONS:/;\}/g,NOT_WHITESPACE:/\S+/g};
+var _4,_5=false;
+var _6=[];
+var _7=function(fn){
+if(typeof fn==="function"){
+_6[_6.length]=fn;
+}
+};
+var _8=function(){
+for(var i=0;i<_6.length;i++){
+_6[i](_4);
+}
+};
+var _9={};
+var _a=function(n,v){
+if(_9[n]){
+var _b=_9[n].listeners;
+if(_b){
+for(var i=0;i<_b.length;i++){
+_b[i](v);
+}
+}
+}
+};
+var _c=function(_d,_e,_f){
+if(ua.ie&&!window.XMLHttpRequest){
+window.XMLHttpRequest=function(){
+return new ActiveXObject("Microsoft.XMLHTTP");
+};
+}
+if(!XMLHttpRequest){
+return "";
+}
+var r=new XMLHttpRequest();
+try{
+r.open("get",_d,true);
+r.setRequestHeader("X_REQUESTED_WITH","XMLHttpRequest");
+}
+catch(e){
+_f();
+return;
+}
+var _10=false;
+setTimeout(function(){
+_10=true;
+},5000);
+document.documentElement.style.cursor="progress";
+r.onreadystatechange=function(){
+if(r.readyState===4&&!_10){
+if(!r.status&&location.protocol==="file:"||(r.status>=200&&r.status<300)||r.status===304||navigator.userAgent.indexOf("Safari")>-1&&typeof r.status==="undefined"){
+_e(r.responseText);
+}else{
+_f();
+}
+document.documentElement.style.cursor="";
+r=null;
+}
+};
+r.send("");
+};
+var _11=function(_12){
+_12=_12.replace(_3.REDUNDANT_COMPONENTS,"");
+_12=_12.replace(_3.REDUNDANT_WHITESPACE,"$1");
+_12=_12.replace(_3.MORE_WHITESPACE," ");
+_12=_12.replace(_3.FINAL_SEMICOLONS,"}");
+return _12;
+};
+var _13={mediaQueryList:function(s){
+var o={};
+var idx=s.indexOf("{");
+var lt=s.substring(0,idx);
+s=s.substring(idx+1,s.length-1);
+var mqs=[],rs=[];
+var qts=lt.toLowerCase().substring(7).split(",");
+for(var i=0;i-1&&_23.href&&_23.href.length!==0&&!_23.disabled){
+_1f[_1f.length]=_23;
+}
+}
+if(_1f.length>0){
+var c=0;
+var _24=function(){
+c++;
+if(c===_1f.length){
+_20();
+}
+};
+var _25=function(_26){
+var _27=_26.href;
+_c(_27,function(_28){
+_28=_11(_28).replace(_3.RELATIVE_URLS,"url("+_27.substring(0,_27.lastIndexOf("/"))+"/$1)");
+_26.cssHelperText=_28;
+_24();
+},_24);
+};
+for(i=0;i<_1f.length;i++){
+_25(_1f[i]);
+}
+}else{
+_20();
+}
+};
+var _29={mediaQueryLists:"array",rules:"array",selectors:"object",declarations:"array",properties:"object"};
+var _2a={mediaQueryLists:null,rules:null,selectors:null,declarations:null,properties:null};
+var _2b=function(_2c,v){
+if(_2a[_2c]!==null){
+if(_29[_2c]==="array"){
+return (_2a[_2c]=_2a[_2c].concat(v));
+}else{
+var c=_2a[_2c];
+for(var n in v){
+if(v.hasOwnProperty(n)){
+if(!c[n]){
+c[n]=v[n];
+}else{
+c[n]=c[n].concat(v[n]);
+}
+}
+}
+return c;
+}
+}
+};
+var _2d=function(_2e){
+_2a[_2e]=(_29[_2e]==="array")?[]:{};
+for(var i=0;i<_4.length;i++){
+_2b(_2e,_4[i].cssHelperParsed[_2e]);
+}
+return _2a[_2e];
+};
+domReady(function(){
+var els=document.body.getElementsByTagName("*");
+for(var i=0;i=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));
+}else{
+return false;
+}
+}else{
+return _46>0;
+}
+}else{
+if("device-height"===_41.substring(l-13,l)){
+_47=screen.height;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));
+}else{
+return false;
+}
+}else{
+return _47>0;
+}
+}else{
+if("width"===_41.substring(l-5,l)){
+_46=document.documentElement.clientWidth||document.body.clientWidth;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_46>=_44)||(max&&_46<_44)||(!min&&!max&&_46===_44));
+}else{
+return false;
+}
+}else{
+return _46>0;
+}
+}else{
+if("height"===_41.substring(l-6,l)){
+_47=document.documentElement.clientHeight||document.body.clientHeight;
+if(_42!==null){
+if(_43==="length"){
+return ((min&&_47>=_44)||(max&&_47<_44)||(!min&&!max&&_47===_44));
+}else{
+return false;
+}
+}else{
+return _47>0;
+}
+}else{
+if("device-aspect-ratio"===_41.substring(l-19,l)){
+return _43==="aspect-ratio"&&screen.width*_44[1]===screen.height*_44[0];
+}else{
+if("color-index"===_41.substring(l-11,l)){
+var _48=Math.pow(2,screen.colorDepth);
+if(_42!==null){
+if(_43==="absolute"){
+return ((min&&_48>=_44)||(max&&_48<_44)||(!min&&!max&&_48===_44));
+}else{
+return false;
+}
+}else{
+return _48>0;
+}
+}else{
+if("color"===_41.substring(l-5,l)){
+var _49=screen.colorDepth;
+if(_42!==null){
+if(_43==="absolute"){
+return ((min&&_49>=_44)||(max&&_49<_44)||(!min&&!max&&_49===_44));
+}else{
+return false;
+}
+}else{
+return _49>0;
+}
+}else{
+if("resolution"===_41.substring(l-10,l)){
+var res;
+if(_45==="dpcm"){
+res=_3d("1cm");
+}else{
+res=_3d("1in");
+}
+if(_42!==null){
+if(_43==="resolution"){
+return ((min&&res>=_44)||(max&&res<_44)||(!min&&!max&&res===_44));
+}else{
+return false;
+}
+}else{
+return res>0;
+}
+}else{
+return false;
+}
+}
+}
+}
+}
+}
+}
+}
+};
+var _4a=function(mq){
+var _4b=mq.getValid();
+var _4c=mq.getExpressions();
+var l=_4c.length;
+if(l>0){
+for(var i=0;i0){
+s[c++]=",";
+}
+s[c++]=n;
+}
+}
+if(s.length>0){
+_39[_39.length]=cssHelper.addStyle("@media "+s.join("")+"{"+mql.getCssText()+"}",false);
+}
+};
+var _4e=function(_4f){
+for(var i=0;i<_4f.length;i++){
+_4d(_4f[i]);
+}
+if(ua.ie){
+document.documentElement.style.display="block";
+setTimeout(function(){
+document.documentElement.style.display="";
+},0);
+setTimeout(function(){
+cssHelper.broadcast("cssMediaQueriesTested");
+},100);
+}else{
+cssHelper.broadcast("cssMediaQueriesTested");
+}
+};
+var _50=function(){
+for(var i=0;i<_39.length;i++){
+cssHelper.removeStyle(_39[i]);
+}
+_39=[];
+cssHelper.mediaQueryLists(_4e);
+};
+var _51=0;
+var _52=function(){
+var _53=cssHelper.getViewportWidth();
+var _54=cssHelper.getViewportHeight();
+if(ua.ie){
+var el=document.createElement("div");
+el.style.position="absolute";
+el.style.top="-9999em";
+el.style.overflow="scroll";
+document.body.appendChild(el);
+_51=el.offsetWidth-el.clientWidth;
+document.body.removeChild(el);
+}
+var _55;
+var _56=function(){
+var vpw=cssHelper.getViewportWidth();
+var vph=cssHelper.getViewportHeight();
+if(Math.abs(vpw-_53)>_51||Math.abs(vph-_54)>_51){
+_53=vpw;
+_54=vph;
+clearTimeout(_55);
+_55=setTimeout(function(){
+if(!_3a()){
+_50();
+}else{
+cssHelper.broadcast("cssMediaQueriesTested");
+}
+},500);
+}
+};
+window.onresize=function(){
+var x=window.onresize||function(){
+};
+return function(){
+x();
+_56();
+};
+}();
+};
+var _57=document.documentElement;
+_57.style.marginLeft="-32767px";
+setTimeout(function(){
+_57.style.marginTop="";
+},20000);
+return function(){
+if(!_3a()){
+cssHelper.addListener("newStyleParsed",function(el){
+_4e(el.cssHelperParsed.mediaQueryLists);
+});
+cssHelper.addListener("cssMediaQueriesTested",function(){
+if(ua.ie){
+_57.style.width="1px";
+}
+setTimeout(function(){
+_57.style.width="";
+_57.style.marginLeft="";
+},0);
+cssHelper.removeListener("cssMediaQueriesTested",arguments.callee);
+});
+_3c();
+_50();
+}else{
+_57.style.marginLeft="";
+}
+_52();
+};
+}());
+try{
+document.execCommand("BackgroundImageCache",false,true);
+}
+catch(e){
+}
+
diff --git a/params.json b/params.json
index 64698b6..6d56520 100644
--- a/params.json
+++ b/params.json
@@ -1,6 +1,6 @@
{
"name": "chatbot",
"tagline": "Year 1 Project",
- "body": "### Introduction\r\nThis is a reflective piece on my Year 1 group project. Please view the code [here](https://github.coventry.ac.uk/soperd/chatbot).\r\n\r\nThe project is a chatbot written in Python 3 primarily for use with Discord. Current features include:\r\n- Some natural language understanding with [RasaNLU](https://rasa.com/).\r\n- Weather forecast integration with [DarkSky](https://darksky.net/).\r\n- Location services with [Nominantim by OpenStreetMaps](https://nominatim.openstreetmap.org/).\r\n- Datastore integration with [Redis](https://redis.io/).\r\n\r\n\r\n### Design\r\nAs the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.\r\n\r\nI did this by putting all code that provided some kind of generic services into the `handlers` folder of the project. Here you can find a file called `services.py` which contains a class called `Service` that acts as a configurable base class. All other services in `handlers` inherits this `Service` class and implements its own functionality. For example, the `WeatherService` class in `weather.py` contains methods like `get_weather_at` that takes a given longitude and latitude and queries DarkSky's forecast API. \r\n\r\nThe services can then be registered using the `register_service` decorator that can be found in `services.py`. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in `config.json`, and stores it in the dictionary `global_services`.\r\n\r\nFor all the platform specific implementations, I put the code in the `wrappers` folder. This contains a file called `bot.py` which has a class `ChatBot`. This acts as an interface that defines common behaviours for every bot with methods such as `start` and `stop`, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in `discord.py`. Here we can see the bot inherits `ChatBot`, implements the `start` method and defines its own. `ChatBot` also declares three class members:\r\n- `services`: A dictionary containing instances of services for the bot to use.\r\n- `datastore`: A Redis client object for the bot to access the datastore.\r\n- `config`: A `ConfigDict` object that acts as a representation of the bot's config in `config.json` (see below).\r\n\r\nBoth services and wrappers are configurable via the `config.json` file, which looks something like this:\r\n\r\n```json\r\n{\r\n \"discord\": {\r\n \"token\": \"\",\r\n \"services\": [\r\n \"weather\",\r\n \"location\"\r\n ]\r\n },\r\n \"services\": {\r\n \"weather\": {\r\n \"token\": \"\"\r\n }\r\n },\r\n \"redis\": {\r\n \"host\": \"localhost\",\r\n \"port\": 6379\r\n }\r\n}\r\n```\r\n\r\nThis details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the `run_discord.py` script, this passes the `discord` configuration to the `DiscordBot` class constructor, which in turn calls `ChatBot`'s constructor. If the optional parameter `services` is `None` then `ChatBot`'s constructor then will find the services listed in `config.json` from the `global_services` and store them in the `services` class member. This was my attempt to \"inject\" services into the bot automatically.\r\n\r\n`DiscordBot` is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.\r\n\r\n### Reflection\r\nI think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as the `global_services` dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.",
+ "body": "### Introduction\r\nThis is a reflective piece on my Year 1 group project. Please view the code [here](https://github.coventry.ac.uk/soperd/chatbot).\r\n\r\nThe project is a chatbot written in Python 3 primarily for use with Discord. Current features include:\r\n- Some natural language understanding with [RasaNLU](https://rasa.com/).\r\n- Weather forecast integration with [DarkSky](https://darksky.net/).\r\n- Location services with [Nominantim by OpenStreetMaps](https://nominatim.openstreetmap.org/).\r\n- Datastore integration with [Redis](https://redis.io/).\r\n\r\n\r\n### Design\r\nAs the most experienced member of my team, I set down the foundation for the bot's design and structure. At the time, we were unsure what platform which platforms we wanted to target, so I set out by separating the platform-specific implementations from the platform-neutral services.\r\n\r\nI did this by putting all code that provided some kind of generic services into the `handlers` folder of the project. Here you can find a file called `services.py` which contains a class called `Service` that acts as a configurable base class. All other services in `handlers` inherits this `Service` class and implements its own functionality. For example, the `WeatherService` class in `weather.py` contains methods like `get_weather_at` that takes a given longitude and latitude and queries DarkSky's forecast API. \r\n\r\nThe services can then be registered using the `register_service` decorator that can be found in `services.py`. The decorator takes a name as a parameter, then resolves the config provided to that service with the same name detailed in `config.json`, and stores it in the dictionary `global_services`.\r\n\r\nFor all the platform specific implementations, I put the code in the `wrappers` folder. This contains a file called `bot.py` which has a class `ChatBot`. This acts as an interface that defines common behaviours for every bot with methods such as `start` and `stop`, since the reasoning behind it was that every bot must at least start and be able to be stopped. At the moment, the only implemented platform is Discord, the code for which can be seen in `discord.py`. Here we can see the bot inherits `ChatBot`, implements the `start` method and defines its own. `ChatBot` also declares three class members:\r\n- `services`: A dictionary containing instances of services for the bot to use.\r\n- `datastore`: A Redis client object for the bot to access the datastore.\r\n- `config`: A `ConfigDict` object that acts as a representation of the bot's config in `config.json` (see below).\r\n\r\nBoth services and wrappers are configurable via the `config.json` file, which looks something like this:\r\n\r\n```json\r\n{\r\n \"discord\": {\r\n \"token\": \"\",\r\n \"services\": [\r\n \"weather\",\r\n \"location\"\r\n ]\r\n },\r\n \"services\": {\r\n \"weather\": {\r\n \"token\": \"\"\r\n }\r\n },\r\n \"redis\": {\r\n \"host\": \"localhost\",\r\n \"port\": 6379\r\n }\r\n}\r\n```\r\n\r\nThis details that the Discord bot has a token and a set of services it can use. For this example, it can use the weather and location services. When we run the bot using the `run_discord.py` script, this passes the `discord` configuration to the `DiscordBot` class constructor, which in turn calls `ChatBot`'s constructor. If the optional parameter `services` :p is `None` then `ChatBot`'s constructor then will find the services listed in `config.json` from the `global_services` and store them in the `services` class member. This was my attempt to \"inject\" services into the bot automatically.\r\n\r\n`DiscordBot` is currently the only functioning bot. It uses the Discord.py library which makes for easy integration with Discord's API.\r\n\r\n### Reflection\r\nI think my design worked well for the most part. If we decided we wanted to integrate the app into WhatsApp or Messenger, I feel that my design would aid in porting our features over to the new bot. This design also allows for multiple bots with similar features on the same platform, which I am happy with. I do, however, believe that in some areas my code is poorly implemented, such as :p the `global_services` dictionary. This seems like a bit of a hack, and it wasn't really necessary to achieve my goal. That being said, this is the first time I've used a custom decorator in Python and I can see its potential elsewhere.",
"note": "Don't delete this file! It's used internally to help with page regeneration."
}
\ No newline at end of file
diff --git a/stylesheets/github-dark.css b/stylesheets/github-dark.css
new file mode 100644
index 0000000..8e9b4e1
--- /dev/null
+++ b/stylesheets/github-dark.css
@@ -0,0 +1,138 @@
+/*!
+ * GitHub Dark v0.3.0
+ * Copyright (c) 2012 - 2016 GitHub, Inc.
+ * Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
+ */
+
+.pl-c /* comment, punctuation.definition.comment, string.comment */ {
+ color: #969896;
+}
+
+.pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header */,
+.pl-s .pl-v /* string variable */ {
+ color: #0099cd;
+}
+
+.pl-e /* entity */,
+.pl-en /* entity.name */ {
+ color: #9774cb;
+}
+
+.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+.pl-s .pl-s1 /* string source */ {
+ color: #ddd;
+}
+
+.pl-ent /* entity.name.tag */ {
+ color: #7bcc72;
+}
+
+.pl-k /* keyword, storage, storage.type */ {
+ color: #cc2372;
+}
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+ color: #3c66e2;
+}
+
+.pl-v /* variable */,
+.pl-smw /* sublimelinter.mark.warning */ {
+ color: #fb8764;
+}
+
+.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
+ color: #e63525;
+}
+
+.pl-ii /* invalid.illegal */ {
+ color: #f8f8f8;
+ background-color: #e63525;
+}
+
+.pl-c2 /* carriage-return */ {
+ color: #f8f8f8;
+ background-color: #e63525;
+}
+
+.pl-c2::before /* carriage-return */ {
+ content: "^M";
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+ font-weight: bold;
+ color: #7bcc72;
+}
+
+.pl-ml /* markup.list */ {
+ color: #c26b2b;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+ font-weight: bold;
+ color: #264ec5;
+}
+
+.pl-mq /* markup.quote */ {
+ color: #00acac;
+}
+
+.pl-mi /* markup.italic */ {
+ font-style: italic;
+ color: #ddd;
+}
+
+.pl-mb /* markup.bold */ {
+ font-weight: bold;
+ color: #ddd;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.pl-mc /* markup.changed, punctuation.definition.changed */ {
+ color: #ef9700;
+ background-color: #ffe3b4;
+}
+
+.pl-mi2 /* markup.ignored, markup.untracked */ {
+ color: #d8d8d8;
+ background-color: #808080;
+}
+
+.pl-mdr /* meta.diff.range */ {
+ font-weight: bold;
+ color: #9774cb;
+}
+
+.pl-mo /* meta.output */ {
+ color: #264ec5;
+}
+
+.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
+ color: #e1e1e1;
+}
+
+.pl-sg /* sublimelinter.gutter-mark */ {
+ color: #6e7880;
+}
+
+.pl-corl /* constant.other.reference.link, string.other.link */ {
+ text-decoration: underline;
+ color: #3c66e2;
+}
+
diff --git a/stylesheets/ie.css b/stylesheets/ie.css
new file mode 100644
index 0000000..43882f2
--- /dev/null
+++ b/stylesheets/ie.css
@@ -0,0 +1,3 @@
+nav {
+ display: none;
+}
diff --git a/stylesheets/normalize.css b/stylesheets/normalize.css
index 30366a6..16a1351 100644
--- a/stylesheets/normalize.css
+++ b/stylesheets/normalize.css
@@ -1,35 +1,10 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- * user zoom.
- */
-
-html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
- margin: 0;
-}
-
-/* HTML5 display definitions
+/* normalize.css 2012-02-07T12:37 UTC - https://github.com/necolas/normalize.css */
+/* =============================================================================
+ HTML5 display definitions
========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
+/*
+ * Corrects block display not defined in IE6/7/8/9 & FF3
*/
-
article,
aside,
details,
@@ -38,126 +13,209 @@ figure,
footer,
header,
hgroup,
-main,
-menu,
nav,
section,
summary {
display: block;
}
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+/*
+ * Corrects inline-block display not defined in IE6/7/8/9 & FF3
*/
-
audio,
canvas,
-progress,
video {
- display: inline-block; /* 1 */
- vertical-align: baseline; /* 2 */
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
}
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
+/*
+ * Prevents modern browsers from displaying 'audio' without controls
*/
-
audio:not([controls]) {
display: none;
- height: 0;
}
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
+/*
+ * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
+ * Known issue: no IE6 support
*/
-
-[hidden],
-template {
+[hidden] {
display: none;
}
-/* Links
+/* =============================================================================
+ Base
========================================================================== */
+/*
+ * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
+ * http://clagnut.com/blog/348/#c790
+ * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
+ * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
+ */
+html {
+ font-size: 100%;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -ms-text-size-adjust: 100%;
+ /* 2 */
+}
-/**
- * Remove the gray background color from active links in IE 10.
+/*
+ * Addresses font-family inconsistency between 'textarea' and other form elements.
*/
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
-a {
- background-color: transparent;
+/*
+ * Addresses margins handled incorrectly in IE6/7
+ */
+body {
+ margin: 0;
}
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
+/* =============================================================================
+ Links
+ ========================================================================== */
+/*
+ * Addresses outline displayed oddly in Chrome
*/
+a:focus {
+ outline: thin dotted;
+}
-a:active,
-a:hover {
+/*
+ * Improves readability when focused and also mouse hovered in all browsers
+ * people.opera.com/patrickl/experiments/keyboard/test
+ */
+a:hover,
+a:active {
outline: 0;
}
-/* Text-level semantics
+/* =============================================================================
+ Typography
========================================================================== */
-
-/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+/*
+ * Addresses font sizes and margins set differently in IE6/7
+ * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
*/
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
-abbr[title] {
- border-bottom: 1px dotted;
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
}
-/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.75em;
+ margin: 2.33em 0;
+}
+
+/*
+ * Addresses styling not present in IE7/8/9, S5, Chrome
*/
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+/*
+ * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
+*/
b,
strong {
font-weight: bold;
}
-/**
- * Address styling not present in Safari and Chrome.
- */
+blockquote {
+ margin: 1em 40px;
+}
+/*
+ * Addresses styling not present in S5, Chrome
+ */
dfn {
font-style: italic;
}
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
+/*
+ * Addresses styling not present in IE6/7/8/9
*/
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
+mark {
+ background: #ff0;
+ color: #000;
}
-/**
- * Address styling not present in IE 8/9.
+/*
+ * Addresses margins set differently in IE6/7
*/
+p,
+pre {
+ margin: 1em 0;
+}
-mark {
- background: #ff0;
- color: #000;
+/*
+ * Corrects font family set oddly in IE6, S4/5, Chrome
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
+ */
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
}
-/**
- * Address inconsistent and variable font size in all browsers.
+/*
+ * 1. Addresses CSS quotes not supported in IE6/7
+ * 2. Addresses quote property not supported in S4
*/
+/* 1 */
+q {
+ quotes: none;
+}
+
+/* 2 */
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
small {
- font-size: 80%;
+ font-size: 75%;
}
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+/*
+ * Prevents sub and sup affecting line-height in all browsers
+ * gist.github.com/413930
*/
-
sub,
sup {
font-size: 75%;
@@ -174,251 +232,228 @@ sub {
bottom: -0.25em;
}
-/* Embedded content
+/* =============================================================================
+ Lists
========================================================================== */
+/*
+ * Addresses margins set differently in IE6/7
+ */
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
-/**
- * Remove border when inside `a` element in IE 8/9/10.
+dd {
+ margin: 0 0 0 40px;
+}
+
+/*
+ * Addresses paddings set differently in IE6/7
*/
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+/*
+ * Corrects list images handled incorrectly in IE7
+ */
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/* =============================================================================
+ Embedded content
+ ========================================================================== */
+/*
+ * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
+ * 2. Improves image quality when scaled in IE7
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
+ */
img {
border: 0;
+ /* 1 */
+ -ms-interpolation-mode: bicubic;
+ /* 2 */
}
-/**
- * Correct overflow not hidden in IE 9/10/11.
+/*
+ * Corrects overflow displayed oddly in IE9
*/
-
svg:not(:root) {
overflow: hidden;
}
-/* Grouping content
+/* =============================================================================
+ Figures
========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
+/*
+ * Addresses margin not present in IE6/7/8/9, S5, O11
*/
-
figure {
- margin: 1em 40px;
+ margin: 0;
}
-/**
- * Address differences between Firefox and other browsers.
+/* =============================================================================
+ Forms
+ ========================================================================== */
+/*
+ * Corrects margin displayed oddly in IE6/7
*/
-
-hr {
- box-sizing: content-box;
- height: 0;
+form {
+ margin: 0;
}
-/**
- * Contain overflow in all browsers.
+/*
+ * Define consistent border, margin, and padding
*/
-
-pre {
- overflow: auto;
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
}
-/**
- * Address odd `em`-unit font size rendering in all browsers.
+/*
+ * 1. Corrects color not being inherited in IE6/7/8/9
+ * 2. Corrects text not wrapping in FF3
+ * 3. Corrects alignment displayed oddly in IE6/7
*/
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace;
- font-size: 1em;
+legend {
+ border: 0;
+ /* 1 */
+ padding: 0;
+ white-space: normal;
+ /* 2 */
+ *margin-left: -7px;
+ /* 3 */
}
-/* Forms
- ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
+/*
+ * 1. Corrects font size not being inherited in all browsers
+ * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
+ * 3. Improves appearance and consistency in all browsers
*/
-
-/**
- * 1. Correct color not being inherited.
- * Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
button,
input,
-optgroup,
select,
textarea {
- color: inherit; /* 1 */
- font: inherit; /* 2 */
- margin: 0; /* 3 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
- overflow: visible;
+ font-size: 100%;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ vertical-align: baseline;
+ /* 3 */
+ *vertical-align: middle;
+ /* 3 */
}
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
+/*
+ * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
*/
-
button,
-select {
- text-transform: none;
+input {
+ line-height: normal;
+ /* 1 */
}
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
+/*
+ * 1. Improves usability and consistency of cursor style between image-type 'input' and others
+ * 2. Corrects inability to style clickable 'input' types in iOS
+ * 3. Removes inner spacing in IE7 without affecting normal text inputs
+ * Known issue: inner spacing remains in IE6
*/
-
button,
-html input[type="button"], /* 1 */
+input[type="button"],
input[type="reset"],
input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
+ cursor: pointer;
+ /* 1 */
+ -webkit-appearance: button;
+ /* 2 */
+ *overflow: visible;
+ /* 3 */
}
-/**
- * Re-set default cursor for disabled elements.
+/*
+ * Re-set default cursor for disabled elements
*/
-
button[disabled],
-html input[disabled] {
+input[disabled] {
cursor: default;
}
-/**
- * Remove inner padding and border in Firefox 4+.
+/*
+ * 1. Addresses box sizing set to content-box in IE8/9
+ * 2. Removes excess padding in IE8/9
+ * 3. Removes excess padding in IE7
+ Known issue: excess padding remains in IE6
*/
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
- line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
input[type="checkbox"],
input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- height: auto;
+ box-sizing: border-box;
+ /* 1 */
+ padding: 0;
+ /* 2 */
+ *height: 13px;
+ /* 3 */
+ *width: 13px;
+ /* 3 */
}
-/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
- * (include `-moz` to future-proof).
+/*
+ * 1. Addresses appearance set to searchfield in S5, Chrome
+ * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
*/
-
input[type="search"] {
- -webkit-appearance: textfield; /* 1 */ /* 2 */
+ -webkit-appearance: textfield;
+ /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ /* 2 */
box-sizing: content-box;
}
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
+/*
+ * Removes inner padding and search cancel button in S5, Chrome on OS X
*/
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+/*
+ * Removes inner padding and border in FF3+
+ * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
*/
-
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
}
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
+/*
+ * 1. Removes default vertical scrollbar in IE6/7/8/9
+ * 2. Improves readability and alignment in all browsers
*/
-
textarea {
overflow: auto;
+ /* 1 */
+ vertical-align: top;
+ /* 2 */
}
-/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
- font-weight: bold;
-}
-
-/* Tables
+/* =============================================================================
+ Tables
========================================================================== */
-
-/**
- * Remove most spacing between table cells.
+/*
+ * Remove most spacing between table cells
*/
-
table {
border-collapse: collapse;
border-spacing: 0;
}
-
-td,
-th {
- padding: 0;
-}
diff --git a/stylesheets/styles.css b/stylesheets/styles.css
new file mode 100644
index 0000000..9f6e68e
--- /dev/null
+++ b/stylesheets/styles.css
@@ -0,0 +1,851 @@
+@font-face {
+ font-family: 'OpenSansLight';
+ src: url("../fonts/OpenSans-Light-webfont.eot");
+ src: url("../fonts/OpenSans-Light-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Light-webfont.woff") format("woff"), url("../fonts/OpenSans-Light-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Light-webfont.svg#OpenSansLight") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'OpenSansLightItalic';
+ src: url("../fonts/OpenSans-LightItalic-webfont.eot");
+ src: url("../fonts/OpenSans-LightItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-LightItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-LightItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-LightItalic-webfont.svg#OpenSansLightItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'OpenSansRegular';
+ src: url("../fonts/OpenSans-Regular-webfont.eot");
+ src: url("../fonts/OpenSans-Regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Regular-webfont.woff") format("woff"), url("../fonts/OpenSans-Regular-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansItalic';
+ src: url("../fonts/OpenSans-Italic-webfont.eot");
+ src: url("../fonts/OpenSans-Italic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Italic-webfont.woff") format("woff"), url("../fonts/OpenSans-Italic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Italic-webfont.svg#OpenSansItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansSemibold';
+ src: url("../fonts/OpenSans-Semibold-webfont.eot");
+ src: url("../fonts/OpenSans-Semibold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Semibold-webfont.woff") format("woff"), url("../fonts/OpenSans-Semibold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansSemiboldItalic';
+ src: url("../fonts/OpenSans-SemiboldItalic-webfont.eot");
+ src: url("../fonts/OpenSans-SemiboldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-SemiboldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-SemiboldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansBold';
+ src: url("../fonts/OpenSans-Bold-webfont.eot");
+ src: url("../fonts/OpenSans-Bold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-Bold-webfont.woff") format("woff"), url("../fonts/OpenSans-Bold-webfont.ttf") format("truetype"), url("../fonts/OpenSans-Bold-webfont.svg#OpenSansBold") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+@font-face {
+ font-family: 'OpenSansBoldItalic';
+ src: url("../fonts/OpenSans-BoldItalic-webfont.eot");
+ src: url("../fonts/OpenSans-BoldItalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/OpenSans-BoldItalic-webfont.woff") format("woff"), url("../fonts/OpenSans-BoldItalic-webfont.ttf") format("truetype"), url("../fonts/OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic") format("svg");
+ font-weight: normal;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+}
+
+/* normalize.css 2012-02-07T12:37 UTC - https://github.com/necolas/normalize.css */
+/* =============================================================================
+ HTML5 display definitions
+ ========================================================================== */
+/*
+ * Corrects block display not defined in IE6/7/8/9 & FF3
+ */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/*
+ * Corrects inline-block display not defined in IE6/7/8/9 & FF3
+ */
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+/*
+ * Prevents modern browsers from displaying 'audio' without controls
+ */
+audio:not([controls]) {
+ display: none;
+}
+
+/*
+ * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
+ * Known issue: no IE6 support
+ */
+[hidden] {
+ display: none;
+}
+
+/* =============================================================================
+ Base
+ ========================================================================== */
+/*
+ * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
+ * http://clagnut.com/blog/348/#c790
+ * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
+ * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
+ */
+html {
+ font-size: 100%;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -ms-text-size-adjust: 100%;
+ /* 2 */
+}
+
+/*
+ * Addresses font-family inconsistency between 'textarea' and other form elements.
+ */
+html,
+button,
+input,
+select,
+textarea {
+ font-family: sans-serif;
+}
+
+/*
+ * Addresses margins handled incorrectly in IE6/7
+ */
+body {
+ margin: 0;
+}
+
+/* =============================================================================
+ Links
+ ========================================================================== */
+/*
+ * Addresses outline displayed oddly in Chrome
+ */
+a:focus {
+ outline: thin dotted;
+}
+
+/*
+ * Improves readability when focused and also mouse hovered in all browsers
+ * people.opera.com/patrickl/experiments/keyboard/test
+ */
+a:hover,
+a:active {
+ outline: 0;
+}
+
+/* =============================================================================
+ Typography
+ ========================================================================== */
+/*
+ * Addresses font sizes and margins set differently in IE6/7
+ * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
+ */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+
+h3 {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+
+h4 {
+ font-size: 1em;
+ margin: 1.33em 0;
+}
+
+h5 {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+
+h6 {
+ font-size: 0.75em;
+ margin: 2.33em 0;
+}
+
+/*
+ * Addresses styling not present in IE7/8/9, S5, Chrome
+ */
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/*
+ * Addresses style set to 'bolder' in FF3+, S4/5, Chrome
+*/
+b,
+strong {
+ font-weight: bold;
+}
+
+blockquote {
+ margin: 1em 40px;
+}
+
+/*
+ * Addresses styling not present in S5, Chrome
+ */
+dfn {
+ font-style: italic;
+}
+
+/*
+ * Addresses styling not present in IE6/7/8/9
+ */
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/*
+ * Addresses margins set differently in IE6/7
+ */
+p,
+pre {
+ margin: 1em 0;
+}
+
+/*
+ * Corrects font family set oddly in IE6, S4/5, Chrome
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
+ */
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, serif;
+ _font-family: 'courier new', monospace;
+ font-size: 1em;
+}
+
+/*
+ * 1. Addresses CSS quotes not supported in IE6/7
+ * 2. Addresses quote property not supported in S4
+ */
+/* 1 */
+q {
+ quotes: none;
+}
+
+/* 2 */
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+small {
+ font-size: 75%;
+}
+
+/*
+ * Prevents sub and sup affecting line-height in all browsers
+ * gist.github.com/413930
+ */
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* =============================================================================
+ Lists
+ ========================================================================== */
+/*
+ * Addresses margins set differently in IE6/7
+ */
+dl,
+menu,
+ol,
+ul {
+ margin: 1em 0;
+}
+
+dd {
+ margin: 0 0 0 40px;
+}
+
+/*
+ * Addresses paddings set differently in IE6/7
+ */
+menu,
+ol,
+ul {
+ padding: 0 0 0 40px;
+}
+
+/*
+ * Corrects list images handled incorrectly in IE7
+ */
+nav ul,
+nav ol {
+ list-style: none;
+ list-style-image: none;
+}
+
+/* =============================================================================
+ Embedded content
+ ========================================================================== */
+/*
+ * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
+ * 2. Improves image quality when scaled in IE7
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
+ */
+img {
+ border: 0;
+ /* 1 */
+ -ms-interpolation-mode: bicubic;
+ /* 2 */
+}
+
+/*
+ * Corrects overflow displayed oddly in IE9
+ */
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* =============================================================================
+ Figures
+ ========================================================================== */
+/*
+ * Addresses margin not present in IE6/7/8/9, S5, O11
+ */
+figure {
+ margin: 0;
+}
+
+/* =============================================================================
+ Forms
+ ========================================================================== */
+/*
+ * Corrects margin displayed oddly in IE6/7
+ */
+form {
+ margin: 0;
+}
+
+/*
+ * Define consistent border, margin, and padding
+ */
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/*
+ * 1. Corrects color not being inherited in IE6/7/8/9
+ * 2. Corrects text not wrapping in FF3
+ * 3. Corrects alignment displayed oddly in IE6/7
+ */
+legend {
+ border: 0;
+ /* 1 */
+ padding: 0;
+ white-space: normal;
+ /* 2 */
+ *margin-left: -7px;
+ /* 3 */
+}
+
+/*
+ * 1. Corrects font size not being inherited in all browsers
+ * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
+ * 3. Improves appearance and consistency in all browsers
+ */
+button,
+input,
+select,
+textarea {
+ font-size: 100%;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ vertical-align: baseline;
+ /* 3 */
+ *vertical-align: middle;
+ /* 3 */
+}
+
+/*
+ * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
+ */
+button,
+input {
+ line-height: normal;
+ /* 1 */
+}
+
+/*
+ * 1. Improves usability and consistency of cursor style between image-type 'input' and others
+ * 2. Corrects inability to style clickable 'input' types in iOS
+ * 3. Removes inner spacing in IE7 without affecting normal text inputs
+ * Known issue: inner spacing remains in IE6
+ */
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ /* 1 */
+ -webkit-appearance: button;
+ /* 2 */
+ *overflow: visible;
+ /* 3 */
+}
+
+/*
+ * Re-set default cursor for disabled elements
+ */
+button[disabled],
+input[disabled] {
+ cursor: default;
+}
+
+/*
+ * 1. Addresses box sizing set to content-box in IE8/9
+ * 2. Removes excess padding in IE8/9
+ * 3. Removes excess padding in IE7
+ Known issue: excess padding remains in IE6
+ */
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box;
+ /* 1 */
+ padding: 0;
+ /* 2 */
+ *height: 13px;
+ /* 3 */
+ *width: 13px;
+ /* 3 */
+}
+
+/*
+ * 1. Addresses appearance set to searchfield in S5, Chrome
+ * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
+ */
+input[type="search"] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box;
+ /* 2 */
+ box-sizing: content-box;
+}
+
+/*
+ * Removes inner padding and search cancel button in S5, Chrome on OS X
+ */
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: none;
+}
+
+/*
+ * Removes inner padding and border in FF3+
+ * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
+ */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/*
+ * 1. Removes default vertical scrollbar in IE6/7/8/9
+ * 2. Improves readability and alignment in all browsers
+ */
+textarea {
+ overflow: auto;
+ /* 1 */
+ vertical-align: top;
+ /* 2 */
+}
+
+/* =============================================================================
+ Tables
+ ========================================================================== */
+/*
+ * Remove most spacing between table cells
+ */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+body {
+ padding: 0px 0 20px 0px;
+ margin: 0px;
+ font: 14px/1.5 "OpenSansRegular", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #f0e7d5;
+ font-weight: normal;
+ background: #252525;
+ background-attachment: fixed !important;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #2a2a29), color-stop(100%, #1c1c1c));
+ background: -webkit-linear-gradient(#2a2a29, #1c1c1c);
+ background: -moz-linear-gradient(#2a2a29, #1c1c1c);
+ background: -o-linear-gradient(#2a2a29, #1c1c1c);
+ background: -ms-linear-gradient(#2a2a29, #1c1c1c);
+ background: linear-gradient(#2a2a29, #1c1c1c);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #e8e8e8;
+ margin: 0 0 10px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+p, ul, ol, table, pre, dl {
+ margin: 0 0 20px;
+}
+
+h1, h2, h3 {
+ line-height: 1.1;
+}
+
+h1 {
+ font-size: 28px;
+}
+
+h2 {
+ font-size: 24px;
+}
+
+h4, h5, h6 {
+ color: #e8e8e8;
+}
+
+h3 {
+ font-size: 18px;
+ line-height: 24px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+ color: #b6b6b6;
+}
+
+a {
+ color: #ffcc00;
+ font-weight: 400;
+ text-decoration: none;
+}
+a:hover {
+ color: #ffeb9b;
+}
+
+a small {
+ font-size: 11px;
+ color: #666;
+ margin-top: -0.6em;
+ display: block;
+}
+
+ul {
+ list-style-image: url("../images/bullet.png");
+}
+
+strong {
+ font-family: 'OpenSansBold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+.wrapper {
+ max-width: 650px;
+ margin: 0 auto;
+ position: relative;
+ padding: 0 20px;
+}
+
+section img {
+ max-width: 100%;
+}
+
+blockquote {
+ border-left: 3px solid #ffcc00;
+ margin: 0;
+ padding: 0 0 0 20px;
+ font-style: italic;
+}
+
+code {
+ font-family: "Lucida Sans", Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal;
+ color: #efefef;
+ font-size: 13px;
+ margin: 0 4px;
+ padding: 4px 6px;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+}
+
+pre {
+ padding: 8px 15px;
+ background: #191919;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+ border: 1px solid #121212;
+ -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ -o-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3);
+ overflow: auto;
+ overflow-y: hidden;
+}
+pre code {
+ color: #efefef;
+ text-shadow: 0px 1px 0px #000;
+ margin: 0;
+ padding: 0;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+th {
+ text-align: left;
+ padding: 5px 10px;
+ border-bottom: 1px solid #434343;
+ color: #b6b6b6;
+ font-family: 'OpenSansSemibold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+td {
+ text-align: left;
+ padding: 5px 10px;
+ border-bottom: 1px solid #434343;
+}
+
+hr {
+ border: 0;
+ outline: none;
+ height: 3px;
+ background: transparent url("../images/hr.gif") center center repeat-x;
+ margin: 0 0 20px;
+}
+
+dt {
+ color: #F0E7D5;
+ font-family: 'OpenSansSemibold', "Helvetica Neue", Helvetica, Arial, sans-serif !important;
+ font-weight: normal;
+}
+
+#header {
+ z-index: 100;
+ left: 0;
+ top: 0px;
+ height: 60px;
+ width: 100%;
+ position: fixed;
+ background: url(../images/nav-bg.gif) #353535;
+ border-bottom: 4px solid #434343;
+ -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ -o-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+ box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);
+}
+#header nav {
+ max-width: 650px;
+ margin: 0 auto;
+ padding: 0 10px;
+ background: blue;
+ margin: 6px auto;
+}
+#header nav li {
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ list-style: none;
+ display: inline;
+ color: white;
+ line-height: 50px;
+ text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2);
+ font-size: 14px;
+}
+#header nav li a {
+ color: white;
+ border: 1px solid #5d910b;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #93bd20), color-stop(100%, #659e10));
+ background: -webkit-linear-gradient(#93bd20, #659e10);
+ background: -moz-linear-gradient(#93bd20, #659e10);
+ background: -o-linear-gradient(#93bd20, #659e10);
+ background: -ms-linear-gradient(#93bd20, #659e10);
+ background: linear-gradient(#93bd20, #659e10);
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ border-radius: 2px;
+ -moz-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ -webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ -o-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.3), 0px 3px 7px rgba(0, 0, 0, 0.7);
+ background-color: #93bd20;
+ padding: 10px 12px;
+ margin-top: 6px;
+ line-height: 14px;
+ font-size: 14px;
+ display: inline-block;
+ text-align: center;
+}
+#header nav li a:hover {
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #749619), color-stop(100%, #527f0e));
+ background: -webkit-linear-gradient(#749619, #527f0e);
+ background: -moz-linear-gradient(#749619, #527f0e);
+ background: -o-linear-gradient(#749619, #527f0e);
+ background: -ms-linear-gradient(#749619, #527f0e);
+ background: linear-gradient(#749619, #527f0e);
+ background-color: #659e10;
+ border: 1px solid #527f0e;
+ -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ -o-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+ box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 1px 0px rgba(0, 0, 0, 0);
+}
+#header nav li.fork {
+ float: left;
+ margin-left: 0px;
+}
+#header nav li.downloads {
+ float: right;
+ margin-left: 6px;
+}
+#header nav li.title {
+ float: right;
+ margin-right: 10px;
+ font-size: 11px;
+}
+
+section {
+ max-width: 650px;
+ padding: 30px 0px 50px 0px;
+ margin: 20px 0;
+ margin-top: 70px;
+}
+section #title {
+ border: 0;
+ outline: none;
+ margin: 0 0 50px 0;
+ padding: 0 0 5px 0;
+}
+section #title h1 {
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ font-size: 40px;
+ text-align: center;
+ line-height: 36px;
+}
+section #title p {
+ color: #d7cfbe;
+ font-family: 'OpenSansLight', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ font-size: 18px;
+ text-align: center;
+}
+section #title .credits {
+ font-size: 11px;
+ font-family: 'OpenSansRegular', "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: normal;
+ color: #696969;
+ margin-top: -10px;
+}
+section #title .credits.left {
+ float: left;
+}
+section #title .credits.right {
+ float: right;
+}
+
+@media print, screen and (max-width: 720px) {
+ #title .credits {
+ display: block;
+ width: 100%;
+ line-height: 30px;
+ text-align: center;
+ }
+ #title .credits .left {
+ float: none;
+ display: block;
+ }
+ #title .credits .right {
+ float: none;
+ display: block;
+ }
+}
+@media print, screen and (max-width: 480px) {
+ #header {
+ margin-top: -20px;
+ }
+
+ section {
+ margin-top: 40px;
+ }
+
+ nav {
+ display: none;
+ }
+}