diff --git a/README.md b/README.md index 3fa1c57..ed78753 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ and capabilities, and capnproto-java is a work-in-progress pure Java implementation. -[Read more here.](https://capnproto.github.io/capnproto-java/index.html) +[Read more here.](https://dwrensha.github.io/capnproto-java/index.html) diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000..721e9c0 --- /dev/null +++ b/website/README.md @@ -0,0 +1,9 @@ +Slate +===== +Slate is responsive theme for GitHub Pages. [Fork it](https://github.com/jsncostello/slate/fork_select) and use it on your own site or generate one automatically using [GitHub Pages](http://pages.github.com). + +Slate in use: +![Slate](https://f.cloud.github.com/assets/416727/1730110/c72a2f96-62d3-11e3-9d6f-efc53e24aeb2.png) + + +Slate is available under ther Creative Commons Attribution 3.0 License. Basically, use it, modify it, and remix it. Attribution is not necessary but it is appreciated. \ No newline at end of file diff --git a/website/_config.yml b/website/_config.yml new file mode 100644 index 0000000..a8349bc --- /dev/null +++ b/website/_config.yml @@ -0,0 +1,4 @@ +name: Cap'n Proto for Java +markdown: rdiscount +baseurl: /capnproto-java +url: http://dwrensha.github.io/capnproto-java diff --git a/website/_includes/footer.html b/website/_includes/footer.html new file mode 100644 index 0000000..dd42255 --- /dev/null +++ b/website/_includes/footer.html @@ -0,0 +1,9 @@ + + + + + diff --git a/website/_includes/header.html b/website/_includes/header.html new file mode 100644 index 0000000..b721e49 --- /dev/null +++ b/website/_includes/header.html @@ -0,0 +1,34 @@ + + + + + + + + + + + {{page.title}} + + + + + +
+
+ View on GitHub + +

Cap'n Proto for Java

+

extremely efficient serialization in pure Java

+ + +
+
+ + +
+
diff --git a/website/_layouts/page.html b/website/_layouts/page.html new file mode 100644 index 0000000..4f0db4c --- /dev/null +++ b/website/_layouts/page.html @@ -0,0 +1,3 @@ +{% include header.html %} +{{ content }} +{% include footer.html %} diff --git a/website/_layouts/post.html b/website/_layouts/post.html new file mode 100644 index 0000000..9d97589 --- /dev/null +++ b/website/_layouts/post.html @@ -0,0 +1,15 @@ +{% include header.html %} +

+{{page.title}} +

+

+{{ page.date | date_to_string }} +

+ + +{{content}} + +

+ -- posted by {{ page.author }} +

+{% include footer.html %} diff --git a/website/_posts/2014-10-13-alpha-release.md b/website/_posts/2014-10-13-alpha-release.md new file mode 100644 index 0000000..b192601 --- /dev/null +++ b/website/_posts/2014-10-13-alpha-release.md @@ -0,0 +1,85 @@ +--- +layout: post +title: capnproto-java alpha release with benchmarks +author: dwrensha +--- + +I'm happy to announce that +[capnproto-java](https://github.com/dwrensha/capnproto-java) is now a +mostly complete implementation of +the [Cap'n Proto](http://capnproto.org) serialization protocol. +It supports all of the data features of the Cap'n Proto schema language, +including constants, default values, and arbitrarily nested list types. +Moreover, the runtime and the generated code consist entirely +of platform-independent, safe Java code. + +In the spirit of previous announcements about the +[Rust](http://dwrensha.github.io/capnproto-rust/2014/01/15/benchmark-update.html) +and +[OCaml](http://pelzlpj.github.io/capnp-ocaml/2014/09/02/capnp-ocaml-2.0/) +implementations, +I've made some informal measurements +with the [usual](https://github.com/kentonv/capnproto/tree/master/c%2B%2B/src/benchmark) +toy benchmark suite. +The results show +the Java implementation performing +at worst +3x slower than the C++ and Rust implementations, +and at best about 2x slower. +I find these results promising, +considering how difficult it can be to avoid +heap allocations and redundant bounds-checking +on the JVM. + +I ran each of the three benchmark cases +in five modes. In the "object" mode, +the data is passed in-process without any copying. +In the "bytes" mode, the data +is written to a flat array and then re-read in-process. +In the "pipe" mode, the data is passed +as a byte stream between separate processes. +In the "packed" sub-modes, +a [compression scheme](https://capnproto.org/encoding.html#packing) +is applied to the bytes before they are passed. + +To give the JVM a chance to amortize +the cost of just-in-time compilation, +I ran the benchmarks for +10x more iterations than +in the previous Rust vs. C++ benchmarks. + +Here are the results. + + + +The CarSales case does a lot of +iteration through lists of structs. +One way to improve Java's performance here +might be to implement list iterators +that update in-place, so that we don't +need to allocate a new `StructReader` for each +member of a list. + + + +The CatRank case emphasizes string processing. +One big difficulty faced by Java here is that +it uses UTF-16 encoding, while +Cap'n Proto uses UTF-8; +translating between the two requires +significant copying of memory. + + + +The Eval case seems to confirm that packing +costs proportionally more for Java +than for the other implementations. +There are almost certainly still +some optimizations we could apply to that +part of the Java implementation, +but we may be fundamentally limited +by the fact that Java bounds-checks +every array access. \ No newline at end of file diff --git a/website/assets/carsales.png b/website/assets/carsales.png new file mode 100644 index 0000000..cf4e59c Binary files /dev/null and b/website/assets/carsales.png differ diff --git a/website/assets/catrank.png b/website/assets/catrank.png new file mode 100644 index 0000000..de11871 Binary files /dev/null and b/website/assets/catrank.png differ diff --git a/website/assets/eval.png b/website/assets/eval.png new file mode 100644 index 0000000..ff69c7c Binary files /dev/null and b/website/assets/eval.png differ diff --git a/website/images/bg_hr.png b/website/images/bg_hr.png new file mode 100644 index 0000000..7973bd6 Binary files /dev/null and b/website/images/bg_hr.png differ diff --git a/website/images/blacktocat.png b/website/images/blacktocat.png new file mode 100644 index 0000000..6e264fe Binary files /dev/null and b/website/images/blacktocat.png differ diff --git a/website/images/icon_download.png b/website/images/icon_download.png new file mode 100644 index 0000000..a2a287f Binary files /dev/null and b/website/images/icon_download.png differ diff --git a/website/images/sprite_download.png b/website/images/sprite_download.png new file mode 100644 index 0000000..f2babd5 Binary files /dev/null and b/website/images/sprite_download.png differ diff --git a/website/index.md b/website/index.md new file mode 100644 index 0000000..ab42067 --- /dev/null +++ b/website/index.md @@ -0,0 +1,295 @@ +--- +layout: page +title: Cap'n Proto for Java +--- + +## Introduction + +This is a Java implementation of [Cap'n Proto](http://capnproto.org). +It has two main components: + +1. A C++ program `capnpc-java` that +generates Java source code from Cap'n Proto [schemas](https://capnproto.org/language.html) +by acting as a +[plugin](https://capnproto.org/otherlang.html#how-to-write-compiler-plugins) +to the Cap'n Proto schema compiler. + +2. A Java package `org.capnproto` that provides runtime support for `capnpc-java`'s generated code. + +These components let you make your data **mobile**, +so that you can manipulate your data in Java +and also easily communicate it +to distributed components written +in other programming languages. +Under the hood, all operations are +backed by `java.nio.ByteBuffer`. +If you, for example, want to communicate over a +network, you can just directly write the bytes to the wire. +There is no encode or decode step! + +We hope eventually to provide support in Java for a +[distributed object-capability layer](https://capnproto.org/rpc.html) +built on top of this serialization layer, +but we have not embarked on that project yet. + + +## Installation + +### Schema Compiler and Plugin + +You will need to [install](http://capnproto.org/install.html) the +latest release of the Cap'n Proto schema compiler. +Then, running `make` should build `capnpc-java`. + +On Windows, you can instead +grab a prebuilt win32 executable from here: + +
https://dwrensha.ws/capnproto/capnpc-java.exe.zip
+ + +For help on how to invoke the schema compiler: + +``` +capnp compile --help +``` + +Note that you'll need to include `java.capnp` so that you can use the `package` and `outerClassname` +annotations. This schema is located in `compiler/src/main/schema`. + +You might find useful [this Maven Plugin](https://github.com/expretio/capnp-maven-plugin). + +### Runtime + +The runtime is available on +[The Central Repository](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.capnproto%22). + +We use [sbt](http://scala-sbt.org) for building and testing the Java code. +Running `sbt compile` at the top-level directory should build +`org.capnproto` and `org.capnproto.examples`. +Running `sbt test` should run the test suite. + +## Example + +We can define types in a schema like this: + +``` +@0x9eb32e19f86ee174; +using Java = import "/capnp/java.capnp"; +$Java.package("org.capnproto.examples"); +$Java.outerClassname("Addressbook"); + +struct Person { + id @0 :UInt32; + name @1 :Text; + email @2 :Text; + phones @3 :List(PhoneNumber); + + struct PhoneNumber { + number @0 :Text; + type @1 :Type; + + enum Type { + mobile @0; + home @1; + work @2; + } + } + + employment :union { + unemployed @4 :Void; + employer @5 :Text; + school @6 :Text; + selfEmployed @7 :Void; + # We assume that a person is only one of these. + } +} + +struct AddressBook { + people @0 :List(Person); +} +``` + +Then, after running the schema compiler, +we can then use those types from Java like this: +{% highlight java %} +package org.capnproto.examples; + +import org.capnproto.StructList; +import org.capnproto.examples.Addressbook.AddressBook; +import org.capnproto.examples.Addressbook.Person; + +public class AddressbookMain { + + public static void writeAddressBook() throws java.io.IOException { + org.capnproto.MessageBuilder message = + new org.capnproto.MessageBuilder(); + + AddressBook.Builder addressbook = + message.initRoot(AddressBook.factory); + + StructList.Builder people = + addressbook.initPeople(2); + + Person.Builder alice = people.get(0); + alice.setId(123); + alice.setName("Alice"); + alice.setEmail("alice@example.com"); + + StructList.Builder alicePhones = + alice.initPhones(1); + alicePhones.get(0).setNumber("555-1212"); + alicePhones.get(0).setType(Person.PhoneNumber.Type.MOBILE); + alice.getEmployment().setSchool("MIT"); + + Person.Builder bob = people.get(1); + bob.setId(456); + bob.setName("Bob"); + bob.setEmail("bob@example.com"); + StructList.Builder bobPhones = + bob.initPhones(2); + bobPhones.get(0).setNumber("555-4567"); + bobPhones.get(0).setType(Person.PhoneNumber.Type.HOME); + bobPhones.get(1).setNumber("555-7654"); + bobPhones.get(1).setType(Person.PhoneNumber.Type.WORK); + bob.getEmployment().setUnemployed(org.capnproto.Void.VOID); + + org.capnproto.SerializePacked.writeToUnbuffered( + (new java.io.FileOutputStream( + java.io.FileDescriptor.out)).getChannel(), + message); + } + + public static void printAddressBook() throws java.io.IOException { + org.capnproto.MessageReader message = + org.capnproto.SerializePacked.readFromUnbuffered( + (new java.io.FileInputStream( + java.io.FileDescriptor.in)).getChannel()); + + AddressBook.Reader addressbook = + message.getRoot(AddressBook.factory); + + for(Person.Reader person : addressbook.getPeople()) { + System.out.println(person.getName() + ": " + person.getEmail()); + + for (Person.PhoneNumber.Reader phone : person.getPhones()) { + String typeName = "UNKNOWN"; + switch (phone.getType()) { + case MOBILE: + typeName = "mobile"; break; + case HOME: + typeName = "home"; break; + case WORK: + typeName = "work"; break; + } + System.out.println(" " + typeName + " phone: " + + phone.getNumber()); + } + + Person.Employment.Reader employment = person.getEmployment(); + switch (employment.which()) { + case UNEMPLOYED: + System.out.println(" unemployed"); + break; + case EMPLOYER: + System.out.println(" employer: " + employment.getEmployer()); + break; + case SCHOOL: + System.out.println(" student at: " + employment.getSchool()); + break; + case SELF_EMPLOYED: + System.out.println(" self-employed"); + break; + default : + break; + } + } + } + + public static void usage() { + System.out.println("usage: addressbook [write | read]"); + } + + public static void main(String[] args) { + try { + if (args.length < 1) { + usage(); + } else if (args[0].equals("write")) { + writeAddressBook(); + } else if (args[0].equals("read")) { + printAddressBook(); + } else { + usage(); + } + } catch (java.io.IOException e) { + System.out.println("io exception: " + e); + } + } +} +{% endhighlight %} + + +To read a message: + +``` +$ echo '(people = [(id = 123, name = "Alice",' \ +'email = "alice@example.com", employment = (school = "MIT"))])' \ +| capnp encode --packed examples/src/main/schema/addressbook.capnp \ +AddressBook \ +| java -cp runtime/target/classes:examples/target/classes \ +org.capnproto.examples.AddressbookMain read +``` + +To write a message: + +``` +$ java -cp runtime/target/classes:examples/target/classes \ +org.capnproto.examples.AddressbookMain write \ +| capnp decode --packed examples/src/main/schema/addressbook.capnp \ +AddressBook +``` + +## API + +The classes and methods provided by the +Java runtime and generated code +correspond directly to those +provided by the +[C++ implementation](https://capnproto.org/cxx.html), +with just a few adjustments. + +- Java does not have unsigned integer types, so a `UInt64` +in a schema gets mapped to a `long` in Java, a `UInt32` gets +mapped to an `int` in Java, and so on. +You are responsible for correctly handling +arithmetic on values of these types. Note that Java 8 has +standard functions that can help with this. + +- Because Java generics don't get monomorphized at compile time +like C++ templates do, generic methods +need to have an additional *factory* argument to +allow the proper dispatch to occur. +`MessageReader.getRoot()` and `MessageBuilder.initRoot()` are two examples, +as shown above. + +## Tips + +- The main I/O methods in +`Serialize` and `SerializePacked` are written in terms +of `WritableByteChannel` and `ReadableByteChannel`. +You should be very careful if you try to convert a +`java.io.OutputStream` +to a `WritableByteChannel` with the +`java.nio.channels.Channels.newChannel()` method. +If your `OutputStream` was buffered, the new channel-based +wrapper of it will have no way to flush it! +Note that the stream returned by `Process.getOutputStream()` is buffered. + +## Future Work + +There's a lot left to do, and we'd love to have your help! Here are some missing pieces: + +- [Orphans](https://capnproto.org/cxx.html#orphans). +- [Dynamic reflection](https://capnproto.org/cxx.html#dynamic-reflection). +- Optimizations, e.g. iterators for `StructList` that update in place instead of allocating for each element. +- Improvements for build and packaging, e.g. getting a distribution on Maven. +- The entire [object-capability RPC layer](https://capnproto.org/rpc.html). diff --git a/website/news.html b/website/news.html new file mode 100644 index 0000000..831cd14 --- /dev/null +++ b/website/news.html @@ -0,0 +1,19 @@ +--- +title: News +--- + +{% include header.html %} + +

News

+ +{% for post in site.posts %} +

{{ post.title }}

+

+ {{ post.author }} + on {{ post.date | date_to_string }} +

+{{ post.content }} +{% endfor %} + + +{% include footer.html %} diff --git a/website/stylesheets/normalize.css b/website/stylesheets/normalize.css new file mode 100644 index 0000000..c2de8df --- /dev/null +++ b/website/stylesheets/normalize.css @@ -0,0 +1,406 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +/** + * Correct `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9. + * Hide the `template` element in IE, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/** + * 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; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background: transparent; +} + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Correct font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/** + * Improve readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre-wrap; +} + +/** + * Set consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/** + * Correct overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/** + * 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. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * 1. Correct font family not being inherited in all browsers. + * 2. Correct font size not being inherited in all browsers. + * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * 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 Chrome, Safari 5+, and IE 8+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 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. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 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 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and 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; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 8/9. + * 2. Improve 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; +} diff --git a/website/stylesheets/pygment_trac.css b/website/stylesheets/pygment_trac.css new file mode 100644 index 0000000..e65cedf --- /dev/null +++ b/website/stylesheets/pygment_trac.css @@ -0,0 +1,70 @@ +.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: #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: #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: #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 } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/website/stylesheets/stylesheet.css b/website/stylesheets/stylesheet.css new file mode 100644 index 0000000..ca4db7a --- /dev/null +++ b/website/stylesheets/stylesheet.css @@ -0,0 +1,371 @@ +/******************************************************************************* +Slate Theme for GitHub Pages +by Jason Costello, @jsncostello +*******************************************************************************/ + +@import url(normalize.css); +@import url(pygment_trac.css); + +/******************************************************************************* +Theme Styles +*******************************************************************************/ + +*, *:before, *:after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +body { + color:#373737; + background: #212121; + font-size: 18px; + 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 { + font-size: 18px; + margin: 10px 0 15px 0; +} + +footer p { + color: #f2f2f2; +} + +a { + text-decoration: none; + color: #007edf; + text-shadow: none; +} + +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; + + box-shadow: 0 0 10px rgba(0,0,0,.1); +} + +pre { + padding: 10px; + overflow: auto; +} + +code { + padding: 3px; + margin: 0 3px; +} + +pre code { + display: block; + box-shadow: none; +} + +blockquote { + color: #666; + margin: 0 0 20px 2px; + padding-left: 20px; + border-left: 3px solid #bbb; + font-style: italic; +} + +ul, ol, dl { + margin: 0 0 15px 0; + padding-left: 20px; +} + +dl dt { + font-weight: bold; +} + +dl dd { + margin-left: 0; + padding-left: 0; + 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; +} + +#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; +} + +.menu_bar { + color: #fff; + font-size: 20px; + 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; + } +}