diff --git a/images/bg_hr.png b/images/bg_hr.png new file mode 100644 index 0000000..514aee5 Binary files /dev/null and b/images/bg_hr.png differ diff --git a/images/blacktocat.png b/images/blacktocat.png new file mode 100644 index 0000000..e160053 Binary files /dev/null and b/images/blacktocat.png differ diff --git a/images/icon_download.png b/images/icon_download.png new file mode 100644 index 0000000..5a793f1 Binary files /dev/null and b/images/icon_download.png differ diff --git a/images/sprite_download.png b/images/sprite_download.png new file mode 100644 index 0000000..f9f8de2 Binary files /dev/null and b/images/sprite_download.png differ diff --git a/index.html b/index.html index 488d5be..677d18e 100644 --- a/index.html +++ b/index.html @@ -1,53 +1,58 @@ - + + - + - Anyproxy by alipay-ct-wd + - - - - + + + Anyproxy + -
-
-

Anyproxy

-

A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.

-

View the Project on GitHub alipay-ct-wd/anyproxy

+ +
+
+ View on GitHub +

Anyproxy

+

A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.

- -
-
+
+ Download this project as a .zip file + Download this project as a tar.gz file +
+
+
+ + +
+

-anyproxy

+anyproxy

A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.

-Feature

+Feature

screenshot

+ + +

screenshot

-Usage

+Usage

-step 1 - install

+step 1 - install

-step 2 - start server

+ + +

+step 2 - start server

-step 3 - launch web interface

+ + +

+step 3 - launch web interface

-How to write your own rule file

+ + +

+How to write your own rule file

  • rule file scheme is as follows, you may also get it from rule__blank.js

  • -
    -module.exports = {
    -    /*
    -    these functions will overwrite the default ones, write your own when necessary.
    -    */
    +
     
    -    //whether to intercept this request by local logic
    -    //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore
    -    shouldUseLocalResponse : function(req,reqBody){
    -        return false;
    -    },
    +
    +module.exports = {
    +    /*
    +    these functions will overwrite the default ones, write your own when necessary.
    +    */
     
    -    //you may deal the response locally instead of sending it to server
    -    //this function be called when shouldUseLocalResponse returns true
    -    //callback(statusCode,resHeader,responseData)
    -    //e.g. callback(200,{"content-type":"text/html"},"hello world")
    -    dealLocalResponse : function(req,reqBody,callback){
    -        callback(statusCode,resHeader,responseData)
    -    },
    +    //whether to intercept this request by local logic
    +    //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore
    +    shouldUseLocalResponse : function(req,reqBody){
    +        return false;
    +    },
     
    -    //replace the request protocol when sending to the real server
    -    //protocol : "http" or "https"
    -    replaceRequestProtocol:function(req,protocol){
    -        var newProtocol = protocol;
    -        return newProtocol;
    -    },
    +    //you may deal the response locally instead of sending it to server
    +    //this function be called when shouldUseLocalResponse returns true
    +    //callback(statusCode,resHeader,responseData)
    +    //e.g. callback(200,{"content-type":"text/html"},"hello world")
    +    dealLocalResponse : function(req,reqBody,callback){
    +        callback(statusCode,resHeader,responseData)
    +    },
     
    -    //req is user's request sent to the proxy server
    -    //option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
    -    //you may return a customized option to replace the original option
    -    //you should not write content-length header in options, since anyproxy will handle it for you
    -    replaceRequestOption : function(req,option){
    -        var newOption = option;
    -        return newOption;
    -    },
    +    //replace the request protocol when sending to the real server
    +    //protocol : "http" or "https"
    +    replaceRequestProtocol:function(req,protocol){
    +        var newProtocol = protocol;
    +        return newProtocol;
    +    },
     
    -    //replace the request body
    -    replaceRequestData: function(req,data){
    -        return data;
    -    },
    +    //req is user's request sent to the proxy server
    +    //option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
    +    //you may return a customized option to replace the original option
    +    //you should not write content-length header in options, since anyproxy will handle it for you
    +    replaceRequestOption : function(req,option){
    +        var newOption = option;
    +        return newOption;
    +    },
     
    -    //replace the statusCode before it's sent to the user
    -    replaceResponseStatusCode: function(req,res,statusCode){
    -        var newStatusCode = statusCode;
    -        return newStatusCode;
    -    },
    +    //replace the request body
    +    replaceRequestData: function(req,data){
    +        return data;
    +    },
     
    -    //replace the httpHeader before it's sent to the user
    -    //Here header == res.headers
    -    replaceResponseHeader: function(req,res,header){
    -        var newHeader = header;
    -        return newHeader;
    -    },
    +    //replace the statusCode before it's sent to the user
    +    replaceResponseStatusCode: function(req,res,statusCode){
    +        var newStatusCode = statusCode;
    +        return newStatusCode;
    +    },
     
    -    //replace the response from the server before it's sent to the user
    -    //you may return either a Buffer or a string
    -    //serverResData is a Buffer, you may get its content by calling serverResData.toString()
    -    replaceServerResData: function(req,res,serverResData){
    -        return serverResData;
    -    },
    +    //replace the httpHeader before it's sent to the user
    +    //Here header == res.headers
    +    replaceResponseHeader: function(req,res,header){
    +        var newHeader = header;
    +        return newHeader;
    +    },
     
    -    //add a pause before sending response to user
    -    pauseBeforeSendingResponse : function(req,res){
    -        var timeInMS = 1; //delay all requests for 1ms
    -        return timeInMS; 
    -    },
    +    //replace the response from the server before it's sent to the user
    +    //you may return either a Buffer or a string
    +    //serverResData is a Buffer, you may get its content by calling serverResData.toString()
    +    replaceServerResData: function(req,res,serverResData){
    +        return serverResData;
    +    },
     
    -    //should intercept https request, or it will be forwarded to real server
    -    shouldInterceptHttpsReq :function(req){
    -        return false;
    -    }
    +    //add a pause before sending response to user
    +    pauseBeforeSendingResponse : function(req,res){
    +        var timeInMS = 1; //delay all requests for 1ms
    +        return timeInMS; 
    +    },
     
    -};
    +    //should intercept https request, or it will be forwarded to real server
    +    shouldInterceptHttpsReq :function(req){
    +        return false;
    +    }
     
    +};
     

    -Using https features

    +Using https features

    -step 1 - install openssl

    +step 1 - install openssl
    • install openssl ,if you want to use HTTPS-related features. After that, the command openssl should be exposed to your shell
    • -

    -step 2 - generate a rootCA and trust it

    + + +

    +step 2 - generate a rootCA and trust it

    • you should do this when it is the first time to start anyproxy
    • execute anyproxy --root ,follow the instructions on screen
    • you will see some tip like rootCA generated at : /usr/lib... . cd to that directory, add/trust the rootCA.crt file to your system keychain. In OSX, you may do that by open the *crt file directly
    • -

    -step 3 - start a https proxy

    + + +

    +step 3 - start a https proxy

    • anyproxy --type https --host my.domain.com
    • the param host is required with https proxy and it should be kept exactly what it it when you config your browser. Otherwise, you may get some warning about security.
    • -

    -Others

    + + +

    +Others

    -work as a module

    +work as a module
    npm install anyproxy --save
     
    -
    var proxy = require("anyproxy");
    -
    -!proxy.isRootCAFileExists() && proxy.generateRootCA(); //please manually trust this rootCA
    -new proxy.proxyServer("http","8001", "localhost" ,"path/to/rule/file.js");
    +
    var proxy = require("anyproxy");
     
    +!proxy.isRootCAFileExists() && proxy.generateRootCA(); //please manually trust this rootCA
    +new proxy.proxyServer("http","8001", "localhost" ,"path/to/rule/file.js");
     

    -clear all the temperary certificates

    +clear all the temperary certificates

    anyproxy --clear

    -Contact

    +Contact
    • Please feel free to raise any issue about this project, or give us some advice on this doc. :)
    -
    + + + - + + - \ No newline at end of file + diff --git a/javascripts/main.js b/javascripts/main.js new file mode 100644 index 0000000..d8135d3 --- /dev/null +++ b/javascripts/main.js @@ -0,0 +1 @@ +console.log('This would be the main JS file.'); diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css index c6a6452..e65cedf 100644 --- a/stylesheets/pygment_trac.css +++ b/stylesheets/pygment_trac.css @@ -1,64 +1,65 @@ -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f0f3f3; } +.highlight .c { color: #0099FF; font-style: italic } /* Comment */ +.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */ +.highlight .k { color: #006699; font-weight: bold } /* Keyword */ +.highlight .o { color: #555555 } /* Operator */ +.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #009999 } /* Comment.Preproc */ +.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */ +.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */ +.highlight .go { color: #AAAAAA } /* Generic.Output */ +.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #d14 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #0086B3 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #99CC66 } /* Generic.Traceback */ +.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #006699 } /* Keyword.Pseudo */ +.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #FF6600 } /* Literal.Number */ +.highlight .s { color: #CC3300 } /* Literal.String */ +.highlight .na { color: #330099 } /* Name.Attribute */ +.highlight .nb { color: #336666 } /* Name.Builtin */ +.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */ +.highlight .no { color: #336600 } /* Name.Constant */ +.highlight .nd { color: #9999FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #CC00FF } /* Name.Function */ +.highlight .nl { color: #9999FF } /* Name.Label */ +.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #003333 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #d14 } /* Literal.String.Backtick */ -.highlight .sc { color: #d14 } /* Literal.String.Char */ -.highlight .sd { color: #d14 } /* Literal.String.Doc */ -.highlight .s2 { color: #d14 } /* Literal.String.Double */ -.highlight .se { color: #d14 } /* Literal.String.Escape */ -.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ -.highlight .si { color: #d14 } /* Literal.String.Interpol */ -.highlight .sx { color: #d14 } /* Literal.String.Other */ -.highlight .sr { color: #009926 } /* Literal.String.Regex */ -.highlight .s1 { color: #d14 } /* Literal.String.Single */ -.highlight .ss { color: #990073 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ +.highlight .mf { color: #FF6600 } /* Literal.Number.Float */ +.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */ +.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */ +.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */ +.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */ +.highlight .sc { color: #CC3300 } /* Literal.String.Char */ +.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #CC3300 } /* Literal.String.Double */ +.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */ +.highlight .si { color: #AA0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #CC3300 } /* Literal.String.Other */ +.highlight .sr { color: #33AAAA } /* Literal.String.Regex */ +.highlight .s1 { color: #CC3300 } /* Literal.String.Single */ +.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */ +.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #003333 } /* Name.Variable.Class */ +.highlight .vg { color: #003333 } /* Name.Variable.Global */ +.highlight .vi { color: #003333 } /* Name.Variable.Instance */ +.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */ .type-csharp .highlight .k { color: #0000FF } .type-csharp .highlight .kt { color: #0000FF } diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css new file mode 100644 index 0000000..619d19d --- /dev/null +++ b/stylesheets/stylesheet.css @@ -0,0 +1,425 @@ +/******************************************************************************* +Slate Theme for GitHub Pages +by Jason Costello, @jsncostello +*******************************************************************************/ + +@import url(pygment_trac.css); + +/******************************************************************************* +MeyerWeb Reset +*******************************************************************************/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +ol, ul { + list-style: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +/******************************************************************************* +Theme Styles +*******************************************************************************/ + +body { + box-sizing: border-box; + color:#373737; + background: #212121; + font-size: 16px; + font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +h1, h2, h3, h4, h5, h6 { + margin: 10px 0; + font-weight: 700; + color:#222222; + font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; + letter-spacing: -1px; +} + +h1 { + font-size: 36px; + font-weight: 700; +} + +h2 { + padding-bottom: 10px; + font-size: 32px; + background: url('../images/bg_hr.png') repeat-x bottom; +} + +h3 { + font-size: 24px; +} + +h4 { + font-size: 21px; +} + +h5 { + font-size: 18px; +} + +h6 { + font-size: 16px; +} + +p { + margin: 10px 0 15px 0; +} + +footer p { + color: #f2f2f2; +} + +a { + text-decoration: none; + color: #007edf; + text-shadow: none; + + transition: color 0.5s ease; + transition: text-shadow 0.5s ease; + -webkit-transition: color 0.5s ease; + -webkit-transition: text-shadow 0.5s ease; + -moz-transition: color 0.5s ease; + -moz-transition: text-shadow 0.5s ease; + -o-transition: color 0.5s ease; + -o-transition: text-shadow 0.5s ease; + -ms-transition: color 0.5s ease; + -ms-transition: text-shadow 0.5s ease; +} + +a:hover, a:focus {text-decoration: underline;} + +footer a { + color: #F2F2F2; + text-decoration: underline; +} + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + +img { + position: relative; + margin: 0 auto; + max-width: 739px; + padding: 5px; + margin: 10px 0 10px 0; + border: 1px solid #ebebeb; + + box-shadow: 0 0 5px #ebebeb; + -webkit-box-shadow: 0 0 5px #ebebeb; + -moz-box-shadow: 0 0 5px #ebebeb; + -o-box-shadow: 0 0 5px #ebebeb; + -ms-box-shadow: 0 0 5px #ebebeb; +} + +p img { + display: inline; + margin: 0; + padding: 0; + vertical-align: middle; + text-align: center; + border: none; +} + +pre, code { + width: 100%; + color: #222; + background-color: #fff; + + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + font-size: 14px; + + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; +} + +pre { + width: 100%; + padding: 10px; + box-shadow: 0 0 10px rgba(0,0,0,.1); + overflow: auto; +} + +code { + padding: 3px; + margin: 0 3px; + box-shadow: 0 0 10px rgba(0,0,0,.1); +} + +pre code { + display: block; + box-shadow: none; +} + +blockquote { + color: #666; + margin-bottom: 20px; + padding: 0 0 0 20px; + border-left: 3px solid #bbb; +} + + +ul, ol, dl { + margin-bottom: 15px +} + +ul { + list-style-position: inside; + list-style: disc; + padding-left: 20px; +} + +ol { + list-style-position: inside; + list-style: decimal; + padding-left: 20px; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + height: 1px; + margin-bottom: 5px; + border: none; + background: url('../images/bg_hr.png') repeat-x center; +} + +table { + border: 1px solid #373737; + margin-bottom: 20px; + text-align: left; + } + +th { + font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; + padding: 10px; + background: #373737; + color: #fff; + } + +td { + padding: 10px; + border: 1px solid #373737; + } + +form { + background: #f2f2f2; + padding: 20px; +} + +/******************************************************************************* +Full-Width Styles +*******************************************************************************/ + +.outer { + width: 100%; +} + +.inner { + position: relative; + max-width: 640px; + padding: 20px 10px; + margin: 0 auto; +} + +#forkme_banner { + display: block; + position: absolute; + top:0; + right: 10px; + z-index: 10; + padding: 10px 50px 10px 10px; + color: #fff; + background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; + font-weight: 700; + box-shadow: 0 0 10px rgba(0,0,0,.5); + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +#header_wrap { + background: #212121; + background: -moz-linear-gradient(top, #373737, #212121); + background: -webkit-linear-gradient(top, #373737, #212121); + background: -ms-linear-gradient(top, #373737, #212121); + background: -o-linear-gradient(top, #373737, #212121); + background: linear-gradient(top, #373737, #212121); +} + +#header_wrap .inner { + padding: 50px 10px 30px 10px; +} + +#project_title { + margin: 0; + color: #fff; + font-size: 42px; + font-weight: 700; + text-shadow: #111 0px 0px 10px; +} + +#project_tagline { + color: #fff; + font-size: 24px; + font-weight: 300; + background: none; + text-shadow: #111 0px 0px 10px; +} + +#downloads { + position: absolute; + width: 210px; + z-index: 10; + bottom: -40px; + right: 0; + height: 70px; + background: url('../images/icon_download.png') no-repeat 0% 90%; +} + +.zip_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom left; +} + +.tar_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom right; + margin-left: 10px; +} + +.zip_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top left; +} + +.tar_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top right; +} + +#main_content_wrap { + background: #f2f2f2; + border-top: 1px solid #111; + border-bottom: 1px solid #111; +} + +#main_content { + padding-top: 40px; +} + +#footer_wrap { + background: #212121; +} + + + +/******************************************************************************* +Small Device Styles +*******************************************************************************/ + +@media screen and (max-width: 480px) { + body { + font-size:14px; + } + + #downloads { + display: none; + } + + .inner { + min-width: 320px; + max-width: 480px; + } + + #project_title { + font-size: 32px; + } + + h1 { + font-size: 28px; + } + + h2 { + font-size: 24px; + } + + h3 { + font-size: 21px; + } + + h4 { + font-size: 18px; + } + + h5 { + font-size: 14px; + } + + h6 { + font-size: 12px; + } + + code, pre { + min-width: 320px; + max-width: 480px; + font-size: 11px; + } + +}