]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #9389 : poiru/rust/issue-9333, r=alexcrichton
authorbors <bors@rust-lang.org>
Sun, 22 Sep 2013 19:45:52 +0000 (12:45 -0700)
committerbors <bors@rust-lang.org>
Sun, 22 Sep 2013 19:45:52 +0000 (12:45 -0700)
Closes #9333.

123 files changed:
Makefile.in
README.md
RELEASES.txt
doc/po/ja/rust.md.po
doc/po/ja/rustpkg.md.po
doc/po/ja/tutorial-borrowed-ptr.md.po
doc/po/ja/tutorial-container.md.po
doc/po/ja/tutorial-ffi.md.po
doc/po/ja/tutorial-macros.md.po
doc/po/ja/tutorial-tasks.md.po
doc/po/ja/tutorial.md.po
doc/po/rust.md.pot
doc/po/rustpkg.md.pot
doc/po/tutorial-borrowed-ptr.md.pot
doc/po/tutorial-container.md.pot
doc/po/tutorial-ffi.md.pot
doc/po/tutorial-macros.md.pot
doc/po/tutorial-tasks.md.pot
doc/po/tutorial.md.pot
doc/tutorial.md
mk/clean.mk
mk/dist.mk
mk/docs.mk
mk/install.mk
mk/rt.mk
mk/tests.mk
mk/tools.mk
src/etc/kate/rust.xml
src/etc/pkg/rust-logo.ico
src/libextra/base64.rs
src/libextra/container.rs
src/libextra/crypto/cryptoutil.rs
src/libextra/extra.rs
src/libextra/flate.rs
src/libextra/num/bigint.rs
src/libextra/sort.rs
src/libextra/tempfile.rs
src/libextra/treemap.rs
src/libextra/uuid.rs
src/librust/rust.rs
src/librustc/front/std_inject.rs
src/librustc/front/test.rs
src/librustc/rustc.rs
src/librustdoc/astsrv.rs [deleted file]
src/librustdoc/attr_parser.rs [deleted file]
src/librustdoc/attr_pass.rs [deleted file]
src/librustdoc/clean.rs [new file with mode: 0644]
src/librustdoc/config.rs [deleted file]
src/librustdoc/core.rs [new file with mode: 0644]
src/librustdoc/demo.rs [deleted file]
src/librustdoc/desc_to_brief_pass.rs [deleted file]
src/librustdoc/doc.rs [deleted file]
src/librustdoc/doctree.rs [new file with mode: 0644]
src/librustdoc/escape_pass.rs [deleted file]
src/librustdoc/extract.rs [deleted file]
src/librustdoc/fold.rs
src/librustdoc/html/format.rs [new file with mode: 0644]
src/librustdoc/html/layout.rs [new file with mode: 0644]
src/librustdoc/html/markdown.rs [new file with mode: 0644]
src/librustdoc/html/render.rs [new file with mode: 0644]
src/librustdoc/html/static/jquery-2.0.3.min.js [new file with mode: 0644]
src/librustdoc/html/static/main.css [new file with mode: 0644]
src/librustdoc/html/static/main.js [new file with mode: 0644]
src/librustdoc/html/static/normalize.css [new file with mode: 0644]
src/librustdoc/markdown_index_pass.rs [deleted file]
src/librustdoc/markdown_pass.rs [deleted file]
src/librustdoc/markdown_writer.rs [deleted file]
src/librustdoc/page_pass.rs [deleted file]
src/librustdoc/parse.rs [deleted file]
src/librustdoc/pass.rs [deleted file]
src/librustdoc/passes.rs [new file with mode: 0644]
src/librustdoc/path_pass.rs [deleted file]
src/librustdoc/plugins.rs [new file with mode: 0644]
src/librustdoc/prune_hidden_pass.rs [deleted file]
src/librustdoc/prune_private_pass.rs [deleted file]
src/librustdoc/rustdoc.rs
src/librustdoc/sectionalize_pass.rs [deleted file]
src/librustdoc/sort_item_name_pass.rs [deleted file]
src/librustdoc/sort_item_type_pass.rs [deleted file]
src/librustdoc/sort_pass.rs [deleted file]
src/librustdoc/text_pass.rs [deleted file]
src/librustdoc/trim_pass.rs [deleted file]
src/librustdoc/tystr_pass.rs [deleted file]
src/librustdoc/unindent_pass.rs [deleted file]
src/librustdoc/visit_ast.rs [new file with mode: 0644]
src/librusti/rusti.rs
src/librustpkg/rustpkg.rs
src/libstd/hashmap.rs
src/libstd/num/strconv.rs
src/libstd/os.rs
src/libstd/rand.rs [deleted file]
src/libstd/rand/mod.rs [new file with mode: 0644]
src/libstd/rt/comm.rs
src/libstd/rt/sched.rs
src/libstd/std.rs
src/libsyntax/syntax.rs
src/rt/isaac/rand.h [deleted file]
src/rt/isaac/randport.cpp [deleted file]
src/rt/isaac/standard.h [deleted file]
src/rt/rust_builtin.cpp
src/rt/rust_rng.cpp
src/rt/rust_rng.h
src/rt/rustrt.def.in
src/rustdoc_ng/.gitignore [deleted file]
src/rustdoc_ng/clean.rs [deleted file]
src/rustdoc_ng/core.rs [deleted file]
src/rustdoc_ng/doctree.rs [deleted file]
src/rustdoc_ng/fold.rs [deleted file]
src/rustdoc_ng/html/format.rs [deleted file]
src/rustdoc_ng/html/layout.rs [deleted file]
src/rustdoc_ng/html/markdown.rs [deleted file]
src/rustdoc_ng/html/render.rs [deleted file]
src/rustdoc_ng/html/static/jquery-2.0.3.min.js [deleted file]
src/rustdoc_ng/html/static/main.css [deleted file]
src/rustdoc_ng/html/static/main.js [deleted file]
src/rustdoc_ng/html/static/normalize.css [deleted file]
src/rustdoc_ng/passes.rs [deleted file]
src/rustdoc_ng/plugins.rs [deleted file]
src/rustdoc_ng/rustdoc_ng.rs [deleted file]
src/rustdoc_ng/visit_ast.rs [deleted file]
src/test/bench/core-std.rs
src/test/bench/noise.rs
src/test/run-pass/use.rs

index ebcd5c7960344cb8c6a38c4fca70fed841976de8..eca5c3453e69180a121c26f73586a93779a6fdba 100644 (file)
@@ -140,7 +140,7 @@ endif
 
 # version-string calculation
 CFG_GIT_DIR := $(CFG_SRC_DIR).git
-CFG_RELEASE = 0.8-pre
+CFG_RELEASE = 0.8
 CFG_VERSION = $(CFG_RELEASE)
 # windows exe's need numeric versions - don't use anything but
 # numbers and dots here
@@ -214,7 +214,6 @@ CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc)
 CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax)
 CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg)
 CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc)
-CFG_LIBRUSTDOCNG_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc_ng)
 CFG_LIBRUSTI_$(1) :=$(call CFG_LIB_NAME_$(1),rusti)
 CFG_LIBRUST_$(1) :=$(call CFG_LIB_NAME_$(1),rust)
 
@@ -224,7 +223,6 @@ LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc)
 LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax)
 LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg)
 LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc)
-LIBRUSTDOCNG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc_ng)
 LIBRUSTI_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rusti)
 LIBRUST_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rust)
 EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra)
@@ -233,7 +231,6 @@ LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc)
 LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax)
 LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg)
 LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc)
-LIBRUSTDOCNG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc_ng)
 LIBRUSTI_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rusti)
 LIBRUST_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rust)
 
@@ -442,12 +439,10 @@ CSREQ$(1)_T_$(2)_H_$(3) = \
        $$(TSREQ$(1)_T_$(2)_H_$(3)) \
        $$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \
        $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
-       $$(HBIN$(1)_H_$(3))/rustdoc_ng$$(X_$(3)) \
        $$(HBIN$(1)_H_$(3))/rusti$$(X_$(3)) \
        $$(HBIN$(1)_H_$(3))/rust$$(X_$(3)) \
        $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \
        $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \
-       $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(3)) \
        $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTI_$(3)) \
        $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUST_$(3)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
@@ -456,7 +451,6 @@ CSREQ$(1)_T_$(2)_H_$(3) = \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \
-       $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(2)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2)) \
        $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUST_$(2))
 
index aed730c3a2d164b5ff30eae25ebc8b0a5da314bd..ed3a353f0e689ee5439f3efcf72352797e550b62 100644 (file)
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ documentation.
 
 [tutorial]: http://static.rust-lang.org/doc/tutorial.html
 [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
-[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe
+[win-exe]: http://static.rust-lang.org/dist/rust-0.8-install.exe
 
 ### Linux / OS X
 
@@ -33,9 +33,9 @@ documentation.
     
     To build from the [tarball] do:
     
-        $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz
-        $ tar -xzf rust-0.7.tar.gz
-        $ cd rust-0.7
+        $ curl -O http://static.rust-lang.org/dist/rust-0.8.tar.gz
+        $ tar -xzf rust-0.8.tar.gz
+        $ cd rust-0.8
     
     Or to build from the [repo] do:
 
@@ -60,8 +60,8 @@ documentation.
 4. Enjoy!
 
 [repo]: https://github.com/mozilla/rust
-[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz
-[tutorial]: http://static.rust-lang.org/doc/0.7/tutorial.html
+[tarball]: http://static.rust-lang.org/dist/rust-0.8.tar.gz
+[tutorial]: http://static.rust-lang.org/doc/0.8/tutorial.html
 
 ## Notes
 
index 71243df3f6c52d6f63db74eafe6b320290c940a7..63080fe65284c7574d499771fdfdef6ae39f6174 100644 (file)
@@ -143,7 +143,8 @@ Version 0.8 (October 2013)
       * The runtime uses jemalloc for allocations.
       * Segmented stacks are temporarily disabled as part of the transition to
         the new runtime. Stack overflows are possible!
-      * A new documentation backend, rustdoc_ng, is available for use
+      * A new documentation backend, rustdoc_ng, is available for use. It is
+        still invoked through the normal `rustdoc` command.
 
 Version 0.7 (July 2013)
 -----------------------
index c74030f225857d6547a0148ef38db353b20457cf..b21ddfe3e65d12333acf41a2bb6f4248fe9534e5 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: 2013-08-05 19:40+0900\n"
 "Last-Translator: Automatically generated\n"
index b633d8a117e01980ea1147276d30734d79dcecd0..699e17eb9520fcc0a847cf50cb6557c536b87dcf 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-30 07:07+0900\n"
 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
 "Last-Translator: Automatically generated\n"
index 110d7127d955581d42fa105455b284635523ea37..19bf3adeb0b24ae96bf8633a54c02bb61faf22d0 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
 "Last-Translator: Automatically generated\n"
index 9e6df6821087d37443068f227b5899f69a9ebf28..02513417844f784825f925c615247edd6edfe8b6 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-05 19:40+0900\n"
 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
 "Last-Translator: Automatically generated\n"
index 8b1c4c6b67885284ec37e6e7784fc9ba52b45c66..a9bd3842558997953d039fcfac051c6d045eb151 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-10 07:44+0900\n"
 "PO-Revision-Date: 2013-07-22 23:37+0900\n"
 "Last-Translator: Automatically generated\n"
index 2ca6a26e5ab0a3dbc54389583e27d73f63794874..a7704bc94c1d2a111d3915384d9349c08d12761a 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-28 20:32+0900\n"
 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
 "Last-Translator: Automatically generated\n"
index 8566b71d81a699d3c14f6d6a130394f51b3b553c..e0cf7467db90b8df87af7edee92842196c3a7b98 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-08 22:27+0900\n"
 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
 "Last-Translator: Automatically generated\n"
index 3c523e29ff84cfd25e11d4e0ab23e1033fa1ef57..34575c014e0b820a37ebb1414628decbc0698b41 100644 (file)
@@ -5,7 +5,7 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: 2013-08-08 22:27+0900\n"
 "Last-Translator: Automatically generated\n"
index 9bc3fb1d16e2abd04888315bb56e21a2daa85f5f..942fd953ec0c804f48bc4f1cf4b1e4cccdae9666 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 9c4fa4b6c2a9d7ed8c289b19ba3b51ac6295d0e5..76e49aa64f2241dfe296151f65b79580c433f2da 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-30 07:07+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 4678d3ae366023c9957b760a2e0af14ffcca6a6c..49e49fdfae2b30fe160c0453f4e1279bc179d3b1 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index a93d5801dccf8b26a68426a672516dc5830dbfe1..6e7606f67060ce99a7841294b17884d6cf927ff5 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-05 19:40+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 97d3a44d7088437ff5d40a598d45db8a27c7fdd1..62bbd921cb8ad58cab604e0ccf0fb4342f6f5c18 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-10 07:44+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 1b540ea8b1e85eb3ade8fb8df0a02261853f17d0..829db70bfcc3ae60038ec6a3664fe4f9825174af 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 893b3dc149193fd6f39eebada743b7fce959861a..f4dde0cb4e3cfc5315aea142a5d8a615a9834eaa 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-08 22:27+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
index 2aea69cc57332e98140d80ad3ab10fce558fd323..3fd4543b95639ca9810cb2cf73e21388cae5ea6c 100644 (file)
@@ -6,7 +6,7 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: Rust 0.8-pre\n"
+"Project-Id-Version: Rust 0.8\n"
 "POT-Creation-Date: 2013-08-12 02:06+0900\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
@@ -271,8 +271,8 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:108
 msgid ""
-"~~~~ {.notrust} $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz $ "
-"tar -xzf rust-0.7.tar.gz $ cd rust-0.7 $ ./configure $ make && make install "
+"~~~~ {.notrust} $ curl -O http://static.rust-lang.org/dist/rust-0.8.tar.gz $ "
+"tar -xzf rust-0.8.tar.gz $ cd rust-0.8 $ ./configure $ make && make install "
 "~~~~"
 msgstr ""
 
@@ -298,8 +298,8 @@ msgstr ""
 #. type: Plain text
 #: doc/tutorial.md:123
 msgid ""
-"[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz [win-exe]: "
-"http://static.rust-lang.org/dist/rust-0.7-install.exe"
+"[tarball]: http://static.rust-lang.org/dist/rust-0.8.tar.gz [win-exe]: "
+"http://static.rust-lang.org/dist/rust-0.8-install.exe"
 msgstr ""
 
 #. type: Plain text
index 6802d155750e9f39c2b537c3cd4d4d64727007e6..e1ae219159dac61bbf0d36b445c26d00c7e8cb02 100644 (file)
@@ -98,9 +98,9 @@ If you've fulfilled those prerequisites, something along these lines
 should work.
 
 ~~~~ {.notrust}
-$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz
-$ tar -xzf rust-0.7.tar.gz
-$ cd rust-0.7
+$ curl -O http://static.rust-lang.org/dist/rust-0.8.tar.gz
+$ tar -xzf rust-0.8.tar.gz
+$ cd rust-0.8
 $ ./configure
 $ make && make install
 ~~~~
@@ -117,8 +117,8 @@ API-documentation tool; `rustpkg`, the Rust package manager;
 `rusti`, the Rust REPL; and `rust`, a tool which acts both as a unified
 interface for them, and for a few common command line scenarios.
 
-[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz
-[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe
+[tarball]: http://static.rust-lang.org/dist/rust-0.8.tar.gz
+[win-exe]: http://static.rust-lang.org/dist/rust-0.8-install.exe
 
 ## Compiling your first program
 
index 30ec6b15bfefe701b14e586a5b2607ff9311277b..cb8861f659761982d20d3d1a3b583b4ef5c12982 100644 (file)
@@ -68,12 +68,10 @@ clean$(1)_H_$(2):
        $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X_$(2))
        $(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X_$(2))
        $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X_$(2))
-       $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc_ng$(X_$(2))
        $(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X_$(2))
        $(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOCNG_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_STDLIB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_EXTRALIB_$(2))
@@ -87,7 +85,6 @@ clean$(1)_H_$(2):
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOCNG_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUST_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM_$(2))
@@ -106,12 +103,10 @@ clean$(1)_T_$(2)_H_$(3):
        $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X_$(2))
        $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X_$(2))
        $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X_$(2))
-       $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc_ng$(X_$(2))
        $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rusti$(X_$(2))
        $(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rust$(X_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
@@ -125,7 +120,6 @@ clean$(1)_T_$(2)_H_$(3):
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOCNG_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTI_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUST_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(2))
index 34230e6a5aaff3d143ad3b6fa50e7d3e0a130ab8..4a980edf7673141df16ae7895f9c14c37e9b5f7e 100644 (file)
@@ -39,7 +39,6 @@ PKG_FILES := \
       libsyntax                                \
       rt                                       \
       librustdoc                               \
-      rustdoc_ng                               \
       rustllvm                                 \
       snapshots.txt                            \
       test)                                    \
index d7b5d6855adce10105673eee2f10a68c5db27fe7..b89bf3483fce7d51e53f285d63e4b18c35dd6925 100644 (file)
@@ -213,40 +213,21 @@ else
 
 # The rustdoc executable
 RUSTDOC = $(HBIN2_H_$(CFG_BUILD_TRIPLE))/rustdoc$(X_$(CFG_BUILD_TRIPLE))
-RUSTDOC_NG = $(HBIN2_H_$(CFG_BUILD_TRIPLE))/rustdoc_ng$(X_$(CFG_BUILD_TRIPLE))
 
 # The library documenting macro
-# $(1) - The output directory
+# $(1) - The crate name (std/extra)
 # $(2) - The crate file
-# $(3) - The crate soruce files
+# $(3) - The relevant host build triple (to depend on libstd)
 define libdoc
-doc/$(1)/index.html: $(2) $(3) $$(RUSTDOC) doc/$(1)/rust.css
+doc/$(1)/index.html: $$(RUSTDOC) $$(TLIB2_T_$(3)_H_$(3))/$(CFG_STDLIB_$(3))
        @$$(call E, rustdoc: $$@)
-       $(Q)$(RUSTDOC) $(2) --output-dir=doc/$(1)
-
-doc/$(1)/rust.css: rust.css
-       @$$(call E, cp: $$@)
-       $(Q)cp $$< $$@
+       $(Q)$(RUSTDOC) html $(2)
 
 DOCS += doc/$(1)/index.html
 endef
 
-# The "next generation" library documenting macro
-# $(1) - The crate name (std/extra)
-# $(2) - The crate file
-# $(3) - The relevant host build triple (to depend on libstd)
-define libdocng
-doc/ng/$(1)/index.html: $$(RUSTDOC_NG) $$(TLIB2_T_$(3)_H_$(3))/$(CFG_STDLIB_$(3))
-       @$$(call E, rustdoc_ng: $$@)
-       $(Q)$(RUSTDOC_NG) html $(2) -o doc/ng
-
-DOCS += doc/ng/$(1)/index.html
-endef
-
-$(eval $(call libdoc,std,$(STDLIB_CRATE),$(STDLIB_INPUTS)))
-$(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(EXTRALIB_INPUTS)))
-$(eval $(call libdocng,std,$(STDLIB_CRATE),$(CFG_BUILD_TRIPLE)))
-$(eval $(call libdocng,extra,$(EXTRALIB_CRATE),$(CFG_BUILD_TRIPLE)))
+$(eval $(call libdoc,std,$(STDLIB_CRATE),$(CFG_BUILD_TRIPLE)))
+$(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(CFG_BUILD_TRIPLE)))
 endif
 
 
index 3989e4f8119c8de74fa23db457bfba30e3edb3fb..4b50c5aa7963f2d3ddea4107a5bd800913a183e9 100644 (file)
@@ -104,7 +104,6 @@ install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $$(Q)$$(call INSTALL_LIB,$$(LIBSYNTAX_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTPKG_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTDOC_GLOB_$(1)))
-       $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTDOCNG_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTI_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(LIBRUST_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,libmorestack.a)
@@ -140,7 +139,6 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rustc$(X_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD_TRIPLE)))
-       $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc_ng$(X_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL_LIB,$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE)))
@@ -151,7 +149,6 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE))
        $(Q)$(call INSTALL_LIB,$(LIBRUST_GLOB_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD_TRIPLE)))
-       $(Q)$(call INSTALL_LIB,$(LIBRUSTDOCNG_GLOB_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE)))
        $(Q)$(call INSTALL,$(S)/man, $(PREFIX_ROOT)/share/man/man1,rust.1)
@@ -172,7 +169,6 @@ uninstall:
        $(Q)rm -f $(PHB)/rusti$(X_$(CFG_BUILD_TRIPLE))
        $(Q)rm -f $(PHB)/rust$(X_$(CFG_BUILD_TRIPLE))
        $(Q)rm -f $(PHB)/rustdoc$(X_$(CFG_BUILD_TRIPLE))
-       $(Q)rm -f $(PHB)/rustdoc_ng$(X_$(CFG_BUILD_TRIPLE))
        $(Q)rm -f $(PHL)/$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE))
        $(Q)rm -f $(PHL)/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE))
        $(Q)for i in \
@@ -182,7 +178,6 @@ uninstall:
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB_$(CFG_BUILD_TRIPLE))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD_TRIPLE))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD_TRIPLE))) \
-          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOCNG_GLOB_$(CFG_BUILD_TRIPLE))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTI_GLOB_$(CFG_BUILD_TRIPLE))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUST_GLOB_$(CFG_BUILD_TRIPLE))) \
         ; \
index d1a4b2bc87a2c9f9f5af109d8008c47237b38056..1b818bfee415103d642f0c8a1c9f5bd5cd1644c9 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -74,7 +74,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
               rt/rust_rng.cpp \
               rt/rust_upcall.cpp \
               rt/rust_uv.cpp \
-              rt/isaac/randport.cpp \
               rt/miniz.cpp \
               rt/memory_region.cpp \
               rt/boxed_region.cpp \
index 14b06bf047ee12f53f5842902ab613b30d45d1df..9fe163e509b5e627abcee457c5bc7a3a0f05b7c6 100644 (file)
@@ -15,7 +15,7 @@
 
 # The names of crates that must be tested
 TEST_TARGET_CRATES = std extra
-TEST_HOST_CRATES = rust rusti rustpkg rustc rustdoc rustdocng syntax
+TEST_HOST_CRATES = rust rusti rustpkg rustc rustdoc syntax
 TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
 
 # Markdown files under doc/ that should have their code extracted and run
@@ -393,14 +393,6 @@ $(3)/stage$(1)/test/rustdoctest-$(2)$$(X_$(2)):                                    \
        @$$(call E, compile_and_link: $$@)
        $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
 
-$(3)/stage$(1)/test/rustdocngtest-$(2)$$(X_$(2)):                          \
-               $$(RUSTDOCNG_LIB) $$(RUSTDOCNG_INPUTS)          \
-               $$(SREQ$(1)_T_$(2)_H_$(3)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
-               $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
-
 endef
 
 $(foreach host,$(CFG_HOST_TRIPLES), \
index 212b7e570f7820ad1bf5a175bf099d959921c5a0..09c3de014782d3b0f1e1e4dd3d2265ca27f01e86 100644 (file)
@@ -23,11 +23,6 @@ RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs)
 RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rs
 RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs)
 
-# rustdoc_ng, the next generation documentation tool
-
-RUSTDOCNG_LIB := $(S)src/rustdoc_ng/rustdoc_ng.rs
-RUSTDOCNG_INPUTS := $(wildcard $(S)src/rustdoc_ng/*.rs)
-
 # Rusti, the JIT REPL
 RUSTI_LIB := $(S)src/librusti/rusti.rs
 RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs)
@@ -83,24 +78,6 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)):                        \
        @$$(call E, compile_and_link: $$@)
        $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustdoc -o $$@ $$<
 
-$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(4)):           \
-               $$(RUSTDOCNG_LIB) $$(RUSTDOCNG_INPUTS)                  \
-               $$(SREQ$(1)_T_$(4)_H_$(3))                      \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
-               | $$(TLIB$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOCNG_GLOB_$(4)),$$(notdir $$@))
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --out-dir $$(@D) $$< && touch $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOCNG_GLOB_$(4)),$$(notdir $$@))
-
-$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc_ng$$(X_$(4)):                       \
-               $$(DRIVER_CRATE)                                                        \
-               $$(TSREQ$(1)_T_$(4)_H_$(3))                                             \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(4))                     \
-               | $$(TBIN$(1)_T_$(4)_H_$(3))/
-       @$$(call E, compile_and_link: $$@)
-       $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustdoc_ng -o $$@ $$<
-
 $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)):               \
                $$(RUSTI_LIB) $$(RUSTI_INPUTS)                  \
                $$(SREQ$(1)_T_$(4)_H_$(3))                      \
@@ -125,7 +102,6 @@ $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)):             \
                $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))       \
                $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4))         \
                $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))       \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(4))     \
                $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))         \
                | $$(TLIB$(1)_T_$(4)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
@@ -195,27 +171,6 @@ $$(HBIN$(2)_H_$(4))/rustdoc$$(X_$(4)):                             \
        @$$(call E, cp: $$@)
        $$(Q)cp $$< $$@
 
-$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOCNG_$(4)):                                  \
-               $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOCNG_$(4))     \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4))                        \
-               $$(HSREQ$(2)_H_$(4)) \
-               | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOCNG_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp $$< $$@
-       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTDOCNG_GLOB_$(4)),$$(notdir $$@))
-       $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOCNG_GLOB_$(4)) \
-               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOCNG_DSYM_GLOB_$(4))) \
-               $$(HLIB$(2)_H_$(4))
-
-$$(HBIN$(2)_H_$(4))/rustdoc_ng$$(X_$(4)):                              \
-               $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc_ng$$(X_$(4)) \
-               $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOCNG_$(4))    \
-               $$(HSREQ$(2)_H_$(4))                            \
-               | $$(HBIN$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
 $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTI_$(4)):                                      \
                $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)) \
                $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4))                        \
index 8f02ee6a1dd3699f7a83a3e59a03e5b6f15ebe6f..6a60368553741995f7614bac36eac7b7ac708cc7 100644 (file)
@@ -7,7 +7,7 @@
        <!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
        <!ENTITY rustIntSuf "([iu](8|16|32|64)?)?">
 ]>
-<language name="Rust" version="0.8-pre" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
+<language name="Rust" version="0.8" kateversion="2.4" section="Sources" extensions="*.rs;*.rc" mimetype="text/x-rust" priority="15">
 <highlighting>
        <list name="fn">
                <item> fn </item>
index 4749b398c2d2c063219f8e5b5c99bf1547ec0d99..4de8f87ae269c423b08cab18c5e98b5c23496e87 100644 (file)
Binary files a/src/etc/pkg/rust-logo.ico and b/src/etc/pkg/rust-logo.ico differ
index f50108d4eae78e8d5592162c00bb308daa3ab472..191ecbe8d16b42969b9ce7e6ff5c50f95b7be28f 100644 (file)
@@ -311,11 +311,11 @@ fn test_from_base64_invalid_padding() {
 
     #[test]
     fn test_base64_random() {
-        use std::rand::{task_rng, random, RngUtil};
+        use std::rand::{task_rng, random, Rng};
         use std::vec;
 
         do 1000.times {
-            let times = task_rng().gen_uint_range(1, 100);
+            let times = task_rng().gen_integer_range(1u, 100);
             let v = vec::from_fn(times, |_| random::<u8>());
             assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
         }
index 623a9d5f452358cb7930883470c6b942d00489dc..c5311d210ab9bb513a3480f19ecd2c0e70129cfc 100644 (file)
@@ -43,7 +43,7 @@ pub trait Deque<T> : Mutable {
 mod bench {
     use std::container::MutableMap;
     use std::{vec, rand};
-    use std::rand::RngUtil;
+    use std::rand::Rng;
     use test::BenchHarness;
 
     pub fn insert_rand_n<M:MutableMap<uint,uint>>(n: uint,
index 9516517d9f7bebdc361378b5ae77b6aa8dcb62a8..4eba3e13eea5985e3978bc190cd89c733bb1d5bf 100644 (file)
@@ -347,8 +347,7 @@ fn standard_padding(&mut self, rem: uint, func: &fn(&[u8])) {
 
 #[cfg(test)]
 mod test {
-    use std::rand::IsaacRng;
-    use std::rand::RngUtil;
+    use std::rand::{IsaacRng, Rng};
     use std::vec;
 
     use cryptoutil::{add_bytes_to_bits, add_bytes_to_bits_tuple};
@@ -365,7 +364,7 @@ pub fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, e
         digest.reset();
 
         while count < total_size {
-            let next: uint = rng.gen_uint_range(0, 2 * blocksize + 1);
+            let next: uint = rng.gen_integer_range(0, 2 * blocksize + 1);
             let remaining = total_size - count;
             let size = if next > remaining { remaining } else { next };
             digest.input(buffer.slice_to(size));
index 046eaa92c1182307571abcbeb08a9fb8deca6ff5..fc4b2947d1b3402b6415c8abfc26e5958494e804 100644 (file)
@@ -21,7 +21,7 @@
 */
 
 #[link(name = "extra",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
        url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
 
index 65d4f79c640249e01008fd71e39b37f75cbf9998..e12ac276482436666901023a02ec63a6991c4ffc 100644 (file)
@@ -106,15 +106,15 @@ pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
 mod tests {
     use super::*;
     use std::rand;
-    use std::rand::RngUtil;
+    use std::rand::Rng;
 
     #[test]
     fn test_flate_round_trip() {
         let mut r = rand::rng();
         let mut words = ~[];
         do 20.times {
-            let range = r.gen_uint_range(1, 10);
-            words.push(r.gen_bytes(range));
+            let range = r.gen_integer_range(1u, 10);
+            words.push(r.gen_vec::<u8>(range));
         }
         do 20.times {
             let mut input = ~[];
index 936efed94e474c2012a780db72b0789e4dd9476a..f7462ae29438b02e850a8314ff3741baeb594eac 100644 (file)
@@ -23,7 +23,7 @@
 use std::int;
 use std::num;
 use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
-use std::rand::{Rng, RngUtil};
+use std::rand::Rng;
 use std::str;
 use std::uint;
 use std::vec;
index bea7868fd32b7c96d0dbd4196ced81b76d5336fa..bab889ff9245a42a725b8875faa50649c41117d4 100644 (file)
@@ -909,7 +909,7 @@ fn ile(x: &(&'static str), y: &(&'static str)) -> bool
 mod test_tim_sort {
 
     use sort::tim_sort;
-    use std::rand::RngUtil;
+    use std::rand::Rng;
     use std::rand;
     use std::vec;
 
@@ -1008,7 +1008,7 @@ mod big_tests {
 
     use sort::*;
 
-    use std::rand::RngUtil;
+    use std::rand::Rng;
     use std::rand;
     use std::vec;
 
@@ -1069,8 +1069,8 @@ fn isSorted<T:Ord>(arr: &[T]) {
             isSorted(arr);
 
             do 3.times {
-                let i1 = rng.gen_uint_range(0, n);
-                let i2 = rng.gen_uint_range(0, n);
+                let i1 = rng.gen_integer_range(0u, n);
+                let i2 = rng.gen_integer_range(0u, n);
                 arr.swap(i1, i2);
             }
             tim_sort(arr); // 3sort
@@ -1088,7 +1088,7 @@ fn isSorted<T:Ord>(arr: &[T]) {
             isSorted(arr);
 
             do (n/100).times {
-                let idx = rng.gen_uint_range(0, n);
+                let idx = rng.gen_integer_range(0u, n);
                 arr[idx] = rng.gen();
             }
             tim_sort(arr);
@@ -1141,8 +1141,8 @@ fn isSorted<T:Ord>(arr: &[@T]) {
             isSorted(arr);
 
             do 3.times {
-                let i1 = rng.gen_uint_range(0, n);
-                let i2 = rng.gen_uint_range(0, n);
+                let i1 = rng.gen_integer_range(0u, n);
+                let i2 = rng.gen_integer_range(0u, n);
                 arr.swap(i1, i2);
             }
             tim_sort(arr); // 3sort
@@ -1160,7 +1160,7 @@ fn isSorted<T:Ord>(arr: &[@T]) {
             isSorted(arr);
 
             do (n/100).times {
-                let idx = rng.gen_uint_range(0, n);
+                let idx = rng.gen_integer_range(0u, n);
                 arr[idx] = @rng.gen();
             }
             tim_sort(arr);
index 9044c23ff7a40409fe075c8a20dad569097cc7d6..13e0c47433f684a01f32e89c395a36ff276e0ea9 100644 (file)
@@ -12,7 +12,7 @@
 
 
 use std::os;
-use std::rand::RngUtil;
+use std::rand::Rng;
 use std::rand;
 
 /// Attempts to make a temporary directory inside of `tmpdir` whose name will
@@ -20,7 +20,7 @@
 pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
     let mut r = rand::rng();
     for _ in range(0u, 1000) {
-        let p = tmpdir.push(r.gen_str(16) + suffix);
+        let p = tmpdir.push(r.gen_ascii_str(16) + suffix);
         if os::make_dir(&p, 0x1c0) { // 700
             return Some(p);
         }
index 99643e643b7bb480ec6579765581629a516ee5f1..8ddc0413aa3c71efe33de61e7c26f8667ce32aa1 100644 (file)
@@ -874,7 +874,7 @@ mod test_treemap {
 
     use super::*;
 
-    use std::rand::RngUtil;
+    use std::rand::Rng;
     use std::rand;
 
     #[test]
@@ -1028,7 +1028,7 @@ fn test_rand_int() {
             }
 
             do 30.times {
-                let r = rng.gen_uint_range(0, ctrl.len());
+                let r = rng.gen_integer_range(0, ctrl.len());
                 let (key, _) = ctrl.remove(r);
                 assert!(map.remove(&key));
                 check_structure(&map);
index 2641c1379e4f60d8528d86e9d47356e91c567def..8eff9a022995a7f193b3ddfad52afe1aa70f31a8 100644 (file)
@@ -62,7 +62,7 @@ fn main() {
 use std::container::Container;
 use std::to_str::ToStr;
 use std::rand;
-use std::rand::RngUtil;
+use std::rand::Rng;
 use std::cmp::Eq;
 use std::cast::{transmute,transmute_copy};
 
@@ -170,7 +170,7 @@ pub fn new(v: UuidVersion) -> Option<Uuid> {
     /// of random numbers. Use the rand::Rand trait to supply
     /// a custom generator if required.
     pub fn new_v4() -> Uuid {
-        let ub = rand::task_rng().gen_bytes(16);
+        let ub = rand::task_rng().gen_vec(16);
         let mut uuid = Uuid{ bytes: [0, .. 16] };
         vec::bytes::copy_memory(uuid.bytes, ub, 16);
         uuid.set_variant(VariantRFC4122);
@@ -488,7 +488,7 @@ fn equals(&self, other: &Uuid) -> bool {
 impl rand::Rand for Uuid {
     #[inline]
     fn rand<R: rand::Rng>(rng: &mut R) -> Uuid {
-        let ub = rng.gen_bytes(16);
+        let ub = rng.gen_vec(16);
         let mut uuid = Uuid{ bytes: [0, .. 16] };
         vec::bytes::copy_memory(uuid.bytes, ub, 16);
         uuid.set_variant(VariantRFC4122);
index ffaa7f74800f6131b213dfa7724034df857bfc36..eb82cfcc0b2e24b85bbfae2d5ab5894058de7feb 100644 (file)
@@ -13,7 +13,7 @@
 // FIXME #2238 Make run only accept source that emits an executable
 
 #[link(name = "rust",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
        url = "https://github.com/mozilla/rust/tree/master/src/rust")];
 
@@ -92,7 +92,7 @@ struct Command<'self> {
         cmd: "doc",
         action: CallMain("rustdoc", rustdoc::main_args),
         usage_line: "generate documentation from doc comments",
-        usage_full: UsgCall(rustdoc::config::usage),
+        usage_full: UsgCall(rustdoc_help),
     },
     Command {
         cmd: "pkg",
@@ -122,6 +122,10 @@ fn rustc_help() {
     rustc::usage(os::args()[0].clone())
 }
 
+fn rustdoc_help() {
+    rustdoc::usage(os::args()[0].clone())
+}
+
 fn find_cmd(command_string: &str) -> Option<Command> {
     do COMMANDS.iter().find |command| {
         command.cmd == command_string
index d685b8a3e766765bfc7e025d30387eacd73329ff..79e554090f310030b76c287f2874c43a93ef6c9d 100644 (file)
@@ -19,7 +19,7 @@
 use syntax::fold;
 use syntax::opt_vec;
 
-static STD_VERSION: &'static str = "0.8-pre";
+static STD_VERSION: &'static str = "0.8";
 
 pub fn maybe_inject_libstd_ref(sess: Session, crate: @ast::Crate)
                                -> @ast::Crate {
index 49176c7bc17d53559ab858c81fd85b40092c0303..f0d7f6c892ba240109448d4e175a96b3f3c82885 100644 (file)
@@ -282,7 +282,7 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item {
                                             path_node(~[id_extra]),
                                             ast::DUMMY_NODE_ID))])
     } else {
-        let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre");
+        let mi = attr::mk_name_value_item_str(@"vers", @"0.8");
         ast::view_item_extern_mod(id_extra, None, ~[mi], ast::DUMMY_NODE_ID)
     };
     ast::view_item {
index 8c3e198e5d6f495a0c32ab7af4290a3d09eddff7..a90ab11535e6fa1a0582b94506ac355559ba9728 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[link(name = "rustc",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "0ce89b41-2f92-459e-bbc1-8f5fe32f16cf",
        url = "https://github.com/mozilla/rust/tree/master/src/rustc")];
 
diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs
deleted file mode 100644 (file)
index b2b7599..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Provides all access to AST-related, non-sendable info
-
-Rustdoc is intended to be parallel, and the rustc AST is filled with
-shared boxes. The AST service attempts to provide a single place to
-query AST-related information, shielding the rest of Rustdoc from its
-non-sendableness.
-*/
-
-
-use parse;
-
-use std::cell::Cell;
-use std::comm::{stream, SharedChan, Port};
-use std::task;
-use rustc::driver::driver;
-use rustc::driver::session::Session;
-use rustc::driver::session::{basic_options, options};
-use rustc::front;
-use syntax::ast;
-use syntax::ast_map;
-use syntax::ast_util;
-use syntax;
-
-pub struct Ctxt {
-    ast: @ast::Crate,
-    ast_map: ast_map::map
-}
-
-type SrvOwner<'self,T> = &'self fn(srv: Srv) -> T;
-pub type CtxtHandler<T> = ~fn(ctxt: Ctxt) -> T;
-type Parser = ~fn(Session, s: @str) -> @ast::Crate;
-
-enum Msg {
-    HandleRequest(~fn(Ctxt)),
-    Exit
-}
-
-#[deriving(Clone)]
-pub struct Srv {
-    ch: SharedChan<Msg>
-}
-
-pub fn from_str<T>(source: ~str, owner: SrvOwner<T>) -> T {
-    run(owner, source.clone(), parse::from_str_sess)
-}
-
-pub fn from_file<T>(file: ~str, owner: SrvOwner<T>) -> T {
-    run(owner, file.clone(), |sess, f| parse::from_file_sess(sess, &Path(f)))
-}
-
-fn run<T>(owner: SrvOwner<T>, source: ~str, parse: Parser) -> T {
-
-    let (po, ch) = stream();
-
-    let source = Cell::new(source);
-    let parse = Cell::new(parse);
-    do task::spawn {
-        act(&po, source.take().to_managed(), parse.take());
-    }
-
-    let srv_ = Srv {
-        ch: SharedChan::new(ch)
-    };
-
-    let res = owner(srv_.clone());
-    srv_.ch.send(Exit);
-    res
-}
-
-fn act(po: &Port<Msg>, source: @str, parse: Parser) {
-    let sess = build_session();
-
-    let ctxt = build_ctxt(
-        sess,
-        parse(sess, source)
-    );
-
-    let mut keep_going = true;
-    while keep_going {
-        match po.recv() {
-          HandleRequest(f) => {
-            f(ctxt);
-          }
-          Exit => {
-            keep_going = false;
-          }
-        }
-    }
-}
-
-pub fn exec<T:Send>(
-    srv: Srv,
-    f: ~fn(ctxt: Ctxt) -> T
-) -> T {
-    let (po, ch) = stream();
-    let msg = HandleRequest(|ctxt| ch.send(f(ctxt)));
-    srv.ch.send(msg);
-    po.recv()
-}
-
-fn assign_node_ids(crate: @ast::Crate) -> @ast::Crate {
-    let next_id = @mut 0;
-    let fold = ast_util::node_id_assigner(|| {
-            let i = *next_id;
-            *next_id += 1;
-            i
-        });
-    @fold.fold_crate(crate)
-}
-
-fn build_ctxt(sess: Session,
-              ast: @ast::Crate) -> Ctxt {
-
-    use rustc::front::config;
-
-    let ast = syntax::ext::expand::inject_std_macros(sess.parse_sess,
-                                                     sess.opts.cfg.clone(),
-                                                     ast);
-    let ast = config::strip_unconfigured_items(ast);
-    let ast = syntax::ext::expand::expand_crate(sess.parse_sess,
-                                                sess.opts.cfg.clone(),
-                                                ast);
-    let ast = front::test::modify_for_testing(sess, ast);
-    let ast = assign_node_ids(ast);
-    let ast_map = ast_map::map_crate(sess.diagnostic(), ast);
-
-    Ctxt {
-        ast: ast,
-        ast_map: ast_map,
-    }
-}
-
-fn build_session() -> Session {
-    let sopts: @options = basic_options();
-    let emitter = syntax::diagnostic::emit;
-
-    let session = driver::build_session(sopts, emitter);
-    session
-}
-
-#[test]
-fn should_prune_unconfigured_items() {
-    let source = ~"#[cfg(shut_up_and_leave_me_alone)]fn a() { }";
-    do from_str(source) |srv| {
-        do exec(srv) |ctxt| {
-            // one item: the __std_macros secret module
-            assert_eq!(ctxt.ast.module.items.len(), 1);
-        }
-    }
-}
-
-#[test]
-fn srv_should_build_ast_map() {
-    let source = ~"fn a() { }";
-    do from_str(source) |srv| {
-        do exec(srv) |ctxt| {
-            assert!(!ctxt.ast_map.is_empty())
-        };
-    }
-}
-
-#[test]
-fn should_ignore_external_import_paths_that_dont_exist() {
-    let source = ~"use forble; use forble::bippy;";
-    from_str(source, |_srv| { } )
-}
-
-#[test]
-fn srv_should_return_request_result() {
-    let source = ~"fn a() { }";
-    do from_str(source) |srv| {
-        let result = exec(srv, |_ctxt| 1000 );
-        assert_eq!(result, 1000);
-    }
-}
diff --git a/src/librustdoc/attr_parser.rs b/src/librustdoc/attr_parser.rs
deleted file mode 100644 (file)
index ce8d197..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Attribute parsing
-
-The attribute parser provides methods for pulling documentation out of
-an AST's attributes.
-*/
-
-
-use syntax::ast;
-use syntax::attr;
-use syntax::attr::{AttrMetaMethods, AttributeMethods};
-
-pub struct CrateAttrs {
-    name: Option<~str>
-}
-
-fn doc_metas(attrs: ~[ast::Attribute]) -> ~[@ast::MetaItem] {
-    attrs.iter()
-        .filter(|at| "doc" == at.name())
-        .map(|at| at.desugar_doc().meta())
-        .collect()
-}
-
-pub fn parse_crate(attrs: ~[ast::Attribute]) -> CrateAttrs {
-    let link_metas = attr::find_linkage_metas(attrs);
-    let name = attr::last_meta_item_value_str_by_name(link_metas, "name");
-
-    CrateAttrs {
-        name: name.map(|s| s.to_owned())
-    }
-}
-
-pub fn parse_desc(attrs: ~[ast::Attribute]) -> Option<~str> {
-    let doc_strs = do doc_metas(attrs).move_iter().filter_map |meta| {
-        meta.value_str()
-    }.collect::<~[@str]>();
-    if doc_strs.is_empty() {
-        None
-    } else {
-        Some(doc_strs.connect("\n"))
-    }
-}
-
-pub fn parse_hidden(attrs: ~[ast::Attribute]) -> bool {
-    let r = doc_metas(attrs);
-    do r.iter().any |meta| {
-        match meta.meta_item_list() {
-            Some(metas) => attr::contains_name(metas, "hidden"),
-            None => false
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use syntax::ast;
-    use syntax;
-    use super::{parse_hidden, parse_crate, parse_desc};
-
-    fn parse_attributes(source: @str) -> ~[ast::Attribute] {
-        use syntax::parse;
-        use syntax::parse::attr::parser_attr;
-
-        let parse_sess = syntax::parse::new_parse_sess(None);
-        let parser = parse::new_parser_from_source_str(
-            parse_sess, ~[], @"-", source);
-
-        parser.parse_outer_attributes()
-    }
-
-
-    #[test]
-    fn should_extract_crate_name_from_link_attribute() {
-        let source = @"#[link(name = \"snuggles\")]";
-        let attrs = parse_attributes(source);
-        let attrs = parse_crate(attrs);
-        assert!(attrs.name == Some(~"snuggles"));
-    }
-
-    #[test]
-    fn should_not_extract_crate_name_if_no_link_attribute() {
-        let source = @"";
-        let attrs = parse_attributes(source);
-        let attrs = parse_crate(attrs);
-        assert!(attrs.name == None);
-    }
-
-    #[test]
-    fn should_not_extract_crate_name_if_no_name_value_in_link_attribute() {
-        let source = @"#[link(whatever)]";
-        let attrs = parse_attributes(source);
-        let attrs = parse_crate(attrs);
-        assert!(attrs.name == None);
-    }
-
-    #[test]
-    fn parse_desc_should_handle_undocumented_mods() {
-        let source = @"";
-        let attrs = parse_attributes(source);
-        let attrs = parse_desc(attrs);
-        assert!(attrs == None);
-    }
-
-    #[test]
-    fn parse_desc_should_parse_simple_doc_attributes() {
-        let source = @"#[doc = \"basic\"]";
-        let attrs = parse_attributes(source);
-        let attrs = parse_desc(attrs);
-        assert!(attrs == Some(~"basic"));
-    }
-
-    #[test]
-    fn should_parse_hidden_attribute() {
-        let source = @"#[doc(hidden)]";
-        let attrs = parse_attributes(source);
-        assert!(parse_hidden(attrs) == true);
-    }
-
-    #[test]
-    fn should_parse_hidden_attribute_with_other_docs() {
-        let source = @"#[doc = \"foo\"] #[doc(hidden)] #[doc = \"foo\"]";
-        let attrs = parse_attributes(source);
-        assert!(parse_hidden(attrs) == true);
-    }
-
-    #[test]
-    fn should_not_parse_non_hidden_attribute() {
-        let source = @"#[doc = \"\"]";
-        let attrs = parse_attributes(source);
-        assert!(parse_hidden(attrs) == false);
-    }
-
-    #[test]
-    fn should_concatenate_multiple_doc_comments() {
-        let source = @"/// foo\n/// bar";
-        let desc = parse_desc(parse_attributes(source));
-        assert!(desc == Some(~" foo\n bar"));
-    }
-}
diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs
deleted file mode 100644 (file)
index bd8d9a6..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-The attribute parsing pass
-
-Traverses the document tree, pulling relevant documention out of the
-corresponding AST nodes. The information gathered here is the basis
-of the natural-language documentation for a crate.
-*/
-
-
-use astsrv;
-use attr_parser;
-use doc::ItemUtils;
-use doc;
-use extract::to_str;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-use syntax::ast;
-use syntax::ast_map;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"attr",
-        f: run
-    }
-}
-
-pub fn run(
-    srv: astsrv::Srv,
-    doc: doc::Doc
-) -> doc::Doc {
-    let fold = Fold {
-        ctxt: srv.clone(),
-        fold_crate: fold_crate,
-        fold_item: fold_item,
-        fold_enum: fold_enum,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        .. fold::default_any_fold(srv)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_crate(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::CrateDoc
-) -> doc::CrateDoc {
-
-    let srv = fold.ctxt.clone();
-    let doc = fold::default_seq_fold_crate(fold, doc);
-
-    let attrs = do astsrv::exec(srv) |ctxt| {
-        let attrs = ctxt.ast.attrs.clone();
-        attr_parser::parse_crate(attrs)
-    };
-
-    doc::CrateDoc {
-        topmod: doc::ModDoc {
-            item: doc::ItemDoc {
-                name: attrs.name.clone().unwrap_or(doc.topmod.name_()),
-                .. doc.topmod.item.clone()
-            },
-            .. doc.topmod.clone()
-        }
-    }
-}
-
-fn fold_item(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ItemDoc
-) -> doc::ItemDoc {
-
-    let srv = fold.ctxt.clone();
-    let doc = fold::default_seq_fold_item(fold, doc);
-
-    let desc = if doc.id == ast::CRATE_NODE_ID {
-        // This is the top-level mod, use the crate attributes
-        do astsrv::exec(srv) |ctxt| {
-            attr_parser::parse_desc(ctxt.ast.attrs.clone())
-        }
-    } else {
-        parse_item_attrs(srv, doc.id, attr_parser::parse_desc)
-    };
-
-    doc::ItemDoc {
-        desc: desc,
-        .. doc
-    }
-}
-
-fn parse_item_attrs<T:Send>(
-    srv: astsrv::Srv,
-    id: doc::AstId,
-    parse_attrs: ~fn(a: ~[ast::Attribute]) -> T) -> T {
-    do astsrv::exec(srv) |ctxt| {
-        let attrs = match ctxt.ast_map.get_copy(&id) {
-            ast_map::node_item(item, _) => item.attrs.clone(),
-            ast_map::node_foreign_item(item, _, _, _) => item.attrs.clone(),
-            _ => fail!("parse_item_attrs: not an item")
-        };
-        parse_attrs(attrs)
-    }
-}
-
-fn fold_enum(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::EnumDoc
-) -> doc::EnumDoc {
-
-    let srv = fold.ctxt.clone();
-    let doc_id = doc.id();
-    let doc = fold::default_seq_fold_enum(fold, doc);
-
-    doc::EnumDoc {
-        variants: do doc.variants.iter().map |variant| {
-            let variant = (*variant).clone();
-            let desc = {
-                let variant = variant.clone();
-                do astsrv::exec(srv.clone()) |ctxt| {
-                    match ctxt.ast_map.get_copy(&doc_id) {
-                        ast_map::node_item(@ast::item {
-                            node: ast::item_enum(ref enum_definition, _), _
-                        }, _) => {
-                            let ast_variant =
-                                (*enum_definition.variants.iter().find(|v| {
-                                    to_str(v.node.name) == variant.name
-                                }).unwrap()).clone();
-
-                            attr_parser::parse_desc(
-                                ast_variant.node.attrs.clone())
-                        }
-                        _ => {
-                            fail!("Enum variant %s has id that's not bound to an enum item",
-                                  variant.name)
-                        }
-                    }
-                }
-            };
-
-            doc::VariantDoc {
-                desc: desc,
-                .. variant
-            }
-        }.collect(),
-        .. doc
-    }
-}
-
-fn fold_trait(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::TraitDoc
-) -> doc::TraitDoc {
-    let srv = fold.ctxt.clone();
-    let doc = fold::default_seq_fold_trait(fold, doc);
-
-    doc::TraitDoc {
-        methods: merge_method_attrs(srv, doc.id(), doc.methods.clone()),
-        .. doc
-    }
-}
-
-fn merge_method_attrs(
-    srv: astsrv::Srv,
-    item_id: doc::AstId,
-    docs: ~[doc::MethodDoc]
-) -> ~[doc::MethodDoc] {
-
-    // Create an assoc list from method name to attributes
-    let attrs: ~[(~str, Option<~str>)] = do astsrv::exec(srv) |ctxt| {
-        match ctxt.ast_map.get_copy(&item_id) {
-            ast_map::node_item(@ast::item {
-                node: ast::item_trait(_, _, ref methods), _
-            }, _) => {
-                methods.iter().map(|method| {
-                    match (*method).clone() {
-                        ast::required(ty_m) => {
-                            (to_str(ty_m.ident),
-                             attr_parser::parse_desc(ty_m.attrs.clone()))
-                        }
-                        ast::provided(m) => {
-                            (to_str(m.ident), attr_parser::parse_desc(m.attrs.clone()))
-                        }
-                    }
-                }).collect()
-            }
-            ast_map::node_item(@ast::item {
-                node: ast::item_impl(_, _, _, ref methods), _
-            }, _) => {
-                methods.iter().map(|method| {
-                    (to_str(method.ident),
-                     attr_parser::parse_desc(method.attrs.clone()))
-                }).collect()
-            }
-            _ => fail!("unexpected item")
-        }
-    };
-
-    do docs.iter().zip(attrs.iter()).map |(doc, attrs)| {
-        assert!(doc.name == attrs.first());
-        let desc = attrs.second();
-
-        doc::MethodDoc {
-            desc: desc,
-            .. (*doc).clone()
-        }
-    }.collect()
-}
-
-
-fn fold_impl(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ImplDoc
-) -> doc::ImplDoc {
-    let srv = fold.ctxt.clone();
-    let doc = fold::default_seq_fold_impl(fold, doc);
-
-    doc::ImplDoc {
-        methods: merge_method_attrs(srv, doc.id(), doc.methods.clone()),
-        .. doc
-    }
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass::run;
-    use doc;
-    use extract;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_replace_top_module_name_with_crate_name() {
-        let doc = mk_doc(~"#[link(name = \"bond\")];");
-        assert!(doc.cratemod().name_() == ~"bond");
-    }
-
-    #[test]
-    fn should_should_extract_mod_attributes() {
-        let doc = mk_doc(~"#[doc = \"test\"] mod a { }");
-        // hidden __std_macros module at the start.
-        assert!(doc.cratemod().mods()[1].desc() == Some(~"test"));
-    }
-
-    #[test]
-    fn should_extract_top_mod_attributes() {
-        let doc = mk_doc(~"#[doc = \"test\"];");
-        assert!(doc.cratemod().desc() == Some(~"test"));
-    }
-
-    #[test]
-    fn should_extract_foreign_fn_attributes() {
-        let doc = mk_doc(~"extern { #[doc = \"test\"] fn a(); }");
-        assert!(doc.cratemod().nmods()[0].fns[0].desc() == Some(~"test"));
-    }
-
-    #[test]
-    fn should_extract_fn_attributes() {
-        let doc = mk_doc(~"#[doc = \"test\"] fn a() -> int { }");
-        assert!(doc.cratemod().fns()[0].desc() == Some(~"test"));
-    }
-
-    #[test]
-    fn should_extract_enum_docs() {
-        let doc = mk_doc(~"#[doc = \"b\"]\
-                                 enum a { v }");
-        debug!("%?", doc);
-        assert!(doc.cratemod().enums()[0].desc() == Some(~"b"));
-    }
-
-    #[test]
-    fn should_extract_variant_docs() {
-        let doc = mk_doc(~"enum a { #[doc = \"c\"] v }");
-        assert!(doc.cratemod().enums()[0].variants[0].desc == Some(~"c"));
-    }
-
-    #[test]
-    fn should_extract_trait_docs() {
-        let doc = mk_doc(~"#[doc = \"whatever\"] trait i { fn a(); }");
-        assert!(doc.cratemod().traits()[0].desc() == Some(~"whatever"));
-    }
-
-    #[test]
-    fn should_extract_trait_method_docs() {
-        let doc = mk_doc(
-            ~"trait i {\
-              #[doc = \"desc\"]\
-              fn f(a: bool) -> bool;\
-              }");
-        assert!(doc.cratemod().traits()[0].methods[0].desc == Some(~"desc"));
-    }
-
-    #[test]
-    fn should_extract_impl_docs() {
-        let doc = mk_doc(
-            ~"#[doc = \"whatever\"] impl int { fn a() { } }");
-        assert!(doc.cratemod().impls()[0].desc() == Some(~"whatever"));
-    }
-
-    #[test]
-    fn should_extract_impl_method_docs() {
-        let doc = mk_doc(
-            ~"impl int {\
-              #[doc = \"desc\"]\
-              fn f(a: bool) -> bool { }\
-              }");
-        assert!(doc.cratemod().impls()[0].methods[0].desc == Some(~"desc"));
-    }
-}
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
new file mode 100644 (file)
index 0000000..97a5991
--- /dev/null
@@ -0,0 +1,1094 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module contains the "cleaned" pieces of the AST, and the functions
+//! that clean them.
+
+use its = syntax::parse::token::ident_to_str;
+
+use syntax;
+use syntax::ast;
+use syntax::attr::AttributeMethods;
+
+use std;
+use doctree;
+use visit_ast;
+use std::local_data;
+
+pub trait Clean<T> {
+    fn clean(&self) -> T;
+}
+
+impl<T: Clean<U>, U> Clean<~[U]> for ~[T] {
+    fn clean(&self) -> ~[U] {
+        self.iter().map(|x| x.clean()).collect()
+    }
+}
+impl<T: Clean<U>, U> Clean<U> for @T {
+    fn clean(&self) -> U {
+        (**self).clean()
+    }
+}
+
+impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
+    fn clean(&self) -> Option<U> {
+        match self {
+            &None => None,
+            &Some(ref v) => Some(v.clean())
+        }
+    }
+}
+
+impl<T: Clean<U>, U> Clean<~[U]> for syntax::opt_vec::OptVec<T> {
+    fn clean(&self) -> ~[U] {
+        match self {
+            &syntax::opt_vec::Empty => ~[],
+            &syntax::opt_vec::Vec(ref v) => v.clean()
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Crate {
+    name: ~str,
+    module: Option<Item>,
+}
+
+impl Clean<Crate> for visit_ast::RustdocVisitor {
+    fn clean(&self) -> Crate {
+        use syntax::attr::{find_linkage_metas, last_meta_item_value_str_by_name};
+        let maybe_meta = last_meta_item_value_str_by_name(find_linkage_metas(self.attrs), "name");
+
+        Crate {
+            name: match maybe_meta {
+                Some(x) => x.to_owned(),
+                None => fail!("rustdoc_ng requires a #[link(name=\"foo\")] crate attribute"),
+            },
+            module: Some(self.module.clean()),
+        }
+    }
+}
+
+/// Anything with a source location and set of attributes and, optionally, a
+/// name. That is, anything that can be documented. This doesn't correspond
+/// directly to the AST's concept of an item; it's a strict superset.
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Item {
+    /// Stringified span
+    source: ~str,
+    /// Not everything has a name. E.g., impls
+    name: Option<~str>,
+    attrs: ~[Attribute],
+    inner: ItemEnum,
+    visibility: Option<Visibility>,
+    id: ast::NodeId,
+}
+
+impl Item {
+    /// Finds the `doc` attribute as a List and returns the list of attributes
+    /// nested inside.
+    pub fn doc_list<'a>(&'a self) -> Option<&'a [Attribute]> {
+        for attr in self.attrs.iter() {
+            match *attr {
+                List(~"doc", ref list) => { return Some(list.as_slice()); }
+                _ => {}
+            }
+        }
+        return None;
+    }
+
+    /// Finds the `doc` attribute as a NameValue and returns the corresponding
+    /// value found.
+    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
+        for attr in self.attrs.iter() {
+            match *attr {
+                NameValue(~"doc", ref v) => { return Some(v.as_slice()); }
+                _ => {}
+            }
+        }
+        return None;
+    }
+
+    pub fn is_mod(&self) -> bool {
+        match self.inner { ModuleItem(*) => true, _ => false }
+    }
+    pub fn is_trait(&self) -> bool {
+        match self.inner { TraitItem(*) => true, _ => false }
+    }
+    pub fn is_struct(&self) -> bool {
+        match self.inner { StructItem(*) => true, _ => false }
+    }
+    pub fn is_enum(&self) -> bool {
+        match self.inner { EnumItem(*) => true, _ => false }
+    }
+    pub fn is_fn(&self) -> bool {
+        match self.inner { FunctionItem(*) => true, _ => false }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum ItemEnum {
+    StructItem(Struct),
+    EnumItem(Enum),
+    FunctionItem(Function),
+    ModuleItem(Module),
+    TypedefItem(Typedef),
+    StaticItem(Static),
+    TraitItem(Trait),
+    ImplItem(Impl),
+    ViewItemItem(ViewItem),
+    TyMethodItem(TyMethod),
+    MethodItem(Method),
+    StructFieldItem(StructField),
+    VariantItem(Variant),
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Module {
+    items: ~[Item],
+}
+
+impl Clean<Item> for doctree::Module {
+    fn clean(&self) -> Item {
+        let name = if self.name.is_some() {
+            self.name.unwrap().clean()
+        } else {
+            ~""
+        };
+        Item {
+            name: Some(name),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            visibility: self.vis.clean(),
+            id: self.id,
+            inner: ModuleItem(Module {
+               items: std::vec::concat(&[self.structs.clean(),
+                              self.enums.clean(), self.fns.clean(),
+                              self.mods.clean(), self.typedefs.clean(),
+                              self.statics.clean(), self.traits.clean(),
+                              self.impls.clean(), self.view_items.clean()])
+            })
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum Attribute {
+    Word(~str),
+    List(~str, ~[Attribute]),
+    NameValue(~str, ~str)
+}
+
+impl Clean<Attribute> for ast::MetaItem {
+    fn clean(&self) -> Attribute {
+        match self.node {
+            ast::MetaWord(s) => Word(s.to_owned()),
+            ast::MetaList(ref s, ref l) => List(s.to_owned(), l.clean()),
+            ast::MetaNameValue(s, ref v) => NameValue(s.to_owned(), lit_to_str(v))
+        }
+    }
+}
+
+impl Clean<Attribute> for ast::Attribute {
+    fn clean(&self) -> Attribute {
+        self.desugar_doc().node.value.clean()
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct TyParam {
+    name: ~str,
+    id: ast::NodeId,
+    bounds: ~[TyParamBound]
+}
+
+impl Clean<TyParam> for ast::TyParam {
+    fn clean(&self) -> TyParam {
+        TyParam {
+            name: self.ident.clean(),
+            id: self.id,
+            bounds: self.bounds.clean(),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum TyParamBound {
+    RegionBound,
+    TraitBound(Type)
+}
+
+impl Clean<TyParamBound> for ast::TyParamBound {
+    fn clean(&self) -> TyParamBound {
+        match *self {
+            ast::RegionTyParamBound => RegionBound,
+            ast::TraitTyParamBound(ref t) => TraitBound(t.clean()),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Lifetime(~str);
+
+impl Clean<Lifetime> for ast::Lifetime {
+    fn clean(&self) -> Lifetime {
+        Lifetime(self.ident.clean())
+    }
+}
+
+// maybe use a Generic enum and use ~[Generic]?
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Generics {
+    lifetimes: ~[Lifetime],
+    type_params: ~[TyParam]
+}
+
+impl Generics {
+    fn new() -> Generics {
+        Generics {
+            lifetimes: ~[],
+            type_params: ~[]
+        }
+    }
+}
+
+impl Clean<Generics> for ast::Generics {
+    fn clean(&self) -> Generics {
+        Generics {
+            lifetimes: self.lifetimes.clean(),
+            type_params: self.ty_params.clean(),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Method {
+    generics: Generics,
+    self_: SelfTy,
+    purity: ast::purity,
+    decl: FnDecl,
+}
+
+impl Clean<Item> for ast::method {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.ident.clean()),
+            attrs: self.attrs.clean(),
+            source: self.span.clean(),
+            id: self.self_id.clone(),
+            visibility: None,
+            inner: MethodItem(Method {
+                generics: self.generics.clean(),
+                self_: self.explicit_self.clean(),
+                purity: self.purity.clone(),
+                decl: self.decl.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct TyMethod {
+    purity: ast::purity,
+    decl: FnDecl,
+    generics: Generics,
+    self_: SelfTy,
+}
+
+impl Clean<Item> for ast::TypeMethod {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.ident.clean()),
+            attrs: self.attrs.clean(),
+            source: self.span.clean(),
+            id: self.id,
+            visibility: None,
+            inner: TyMethodItem(TyMethod {
+                purity: self.purity.clone(),
+                decl: self.decl.clean(),
+                self_: self.explicit_self.clean(),
+                generics: self.generics.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum SelfTy {
+    SelfStatic,
+    SelfValue,
+    SelfBorrowed(Option<Lifetime>, Mutability),
+    SelfManaged(Mutability),
+    SelfOwned,
+}
+
+impl Clean<SelfTy> for ast::explicit_self {
+    fn clean(&self) -> SelfTy {
+        match self.node {
+            ast::sty_static => SelfStatic,
+            ast::sty_value => SelfValue,
+            ast::sty_uniq => SelfOwned,
+            ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
+            ast::sty_box(mt) => SelfManaged(mt.clean()),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Function {
+    decl: FnDecl,
+    generics: Generics,
+}
+
+impl Clean<Item> for doctree::Function {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            visibility: self.vis.clean(),
+            id: self.id,
+            inner: FunctionItem(Function {
+                decl: self.decl.clean(),
+                generics: self.generics.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct ClosureDecl {
+    sigil: ast::Sigil,
+    region: Option<Lifetime>,
+    lifetimes: ~[Lifetime],
+    decl: FnDecl,
+    onceness: ast::Onceness,
+    purity: ast::purity,
+    bounds: ~[TyParamBound]
+}
+
+impl Clean<ClosureDecl> for ast::TyClosure {
+    fn clean(&self) -> ClosureDecl {
+        ClosureDecl {
+            sigil: self.sigil,
+            region: self.region.clean(),
+            lifetimes: self.lifetimes.clean(),
+            decl: self.decl.clean(),
+            onceness: self.onceness,
+            purity: self.purity,
+            bounds: match self.bounds {
+                Some(ref x) => x.clean(),
+                None        => ~[]
+            },
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct FnDecl {
+    inputs: ~[Argument],
+    output: Type,
+    cf: RetStyle,
+    attrs: ~[Attribute]
+}
+
+impl Clean<FnDecl> for ast::fn_decl {
+    fn clean(&self) -> FnDecl {
+        FnDecl {
+            inputs: self.inputs.iter().map(|x| x.clean()).collect(),
+            output: (self.output.clean()),
+            cf: self.cf.clean(),
+            attrs: ~[]
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Argument {
+    type_: Type,
+    name: ~str,
+    id: ast::NodeId
+}
+
+impl Clean<Argument> for ast::arg {
+    fn clean(&self) -> Argument {
+        Argument {
+            name: name_from_pat(self.pat),
+            type_: (self.ty.clean()),
+            id: self.id
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum RetStyle {
+    NoReturn,
+    Return
+}
+
+impl Clean<RetStyle> for ast::ret_style {
+    fn clean(&self) -> RetStyle {
+        match *self {
+            ast::return_val => Return,
+            ast::noreturn => NoReturn
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Trait {
+    methods: ~[TraitMethod],
+    generics: Generics,
+    parents: ~[Type],
+}
+
+impl Clean<Item> for doctree::Trait {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: TraitItem(Trait {
+                methods: self.methods.clean(),
+                generics: self.generics.clean(),
+                parents: self.parents.clean(),
+            }),
+        }
+    }
+}
+
+impl Clean<Type> for ast::trait_ref {
+    fn clean(&self) -> Type {
+        let t = Unresolved(self.path.clean(), None, self.ref_id);
+        resolve_type(&t)
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum TraitMethod {
+    Required(Item),
+    Provided(Item),
+}
+
+impl TraitMethod {
+    pub fn is_req(&self) -> bool {
+        match self {
+            &Required(*) => true,
+            _ => false,
+        }
+    }
+    pub fn is_def(&self) -> bool {
+        match self {
+            &Provided(*) => true,
+            _ => false,
+        }
+    }
+    pub fn item<'a>(&'a self) -> &'a Item {
+        match *self {
+            Required(ref item) => item,
+            Provided(ref item) => item,
+        }
+    }
+}
+
+impl Clean<TraitMethod> for ast::trait_method {
+    fn clean(&self) -> TraitMethod {
+        match self {
+            &ast::required(ref t) => Required(t.clean()),
+            &ast::provided(ref t) => Provided(t.clean()),
+        }
+    }
+}
+
+/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
+/// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
+/// it does not preserve mutability or boxes.
+#[deriving(Clone, Encodable, Decodable)]
+pub enum Type {
+    /// Most types start out as "Unresolved". It serves as an intermediate stage between cleaning
+    /// and type resolution.
+    Unresolved(Path, Option<~[TyParamBound]>, ast::NodeId),
+    /// structs/enums/traits (anything that'd be an ast::ty_path)
+    ResolvedPath { path: Path, typarams: Option<~[TyParamBound]>, id: ast::NodeId },
+    /// Reference to an item in an external crate (fully qualified path)
+    External(~str, ~str),
+    // I have no idea how to usefully use this.
+    TyParamBinder(ast::NodeId),
+    /// For parameterized types, so the consumer of the JSON don't go looking
+    /// for types which don't exist anywhere.
+    Generic(ast::NodeId),
+    /// For references to self
+    Self(ast::NodeId),
+    /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
+    Primitive(ast::prim_ty),
+    Closure(~ClosureDecl),
+    /// extern "ABI" fn
+    BareFunction(~BareFunctionDecl),
+    Tuple(~[Type]),
+    Vector(~Type),
+    FixedVector(~Type, ~str),
+    String,
+    Bool,
+    /// aka ty_nil
+    Unit,
+    /// aka ty_bot
+    Bottom,
+    Unique(~Type),
+    Managed(Mutability, ~Type),
+    RawPointer(Mutability, ~Type),
+    BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: ~Type},
+    // region, raw, other boxes, mutable
+}
+
+impl Clean<Type> for ast::Ty {
+    fn clean(&self) -> Type {
+        use syntax::ast::*;
+        debug!("cleaning type `%?`", self);
+        let codemap = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess.codemap;
+        debug!("span corresponds to `%s`", codemap.span_to_str(self.span));
+        let t = match self.node {
+            ty_nil => Unit,
+            ty_ptr(ref m) =>  RawPointer(m.mutbl.clean(), ~resolve_type(&m.ty.clean())),
+            ty_rptr(ref l, ref m) =>
+                BorrowedRef {lifetime: l.clean(), mutability: m.mutbl.clean(),
+                             type_: ~resolve_type(&m.ty.clean())},
+            ty_box(ref m) => Managed(m.mutbl.clean(), ~resolve_type(&m.ty.clean())),
+            ty_uniq(ref m) => Unique(~resolve_type(&m.ty.clean())),
+            ty_vec(ref m) => Vector(~resolve_type(&m.ty.clean())),
+            ty_fixed_length_vec(ref m, ref e) => FixedVector(~resolve_type(&m.ty.clean()),
+                                                             e.span.to_src()),
+            ty_tup(ref tys) => Tuple(tys.iter().map(|x| resolve_type(&x.clean())).collect()),
+            ty_path(ref p, ref tpbs, id) => Unresolved(p.clean(), tpbs.clean(), id),
+            ty_closure(ref c) => Closure(~c.clean()),
+            ty_bare_fn(ref barefn) => BareFunction(~barefn.clean()),
+            ty_bot => Bottom,
+            ref x => fail!("Unimplemented type %?", x),
+        };
+        resolve_type(&t)
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct StructField {
+    type_: Type,
+}
+
+impl Clean<Item> for ast::struct_field {
+    fn clean(&self) -> Item {
+        let (name, vis) = match self.node.kind {
+            ast::named_field(id, vis) => (Some(id), Some(vis)),
+            _ => (None, None)
+        };
+        Item {
+            name: name.clean(),
+            attrs: self.node.attrs.clean(),
+            source: self.span.clean(),
+            visibility: vis,
+            id: self.node.id,
+            inner: StructFieldItem(StructField {
+                type_: self.node.ty.clean(),
+            }),
+        }
+    }
+}
+
+pub type Visibility = ast::visibility;
+
+impl Clean<Option<Visibility>> for ast::visibility {
+    fn clean(&self) -> Option<Visibility> {
+        Some(*self)
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Struct {
+    struct_type: doctree::StructType,
+    generics: Generics,
+    fields: ~[Item],
+}
+
+impl Clean<Item> for doctree::Struct {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: StructItem(Struct {
+                struct_type: self.struct_type,
+                generics: self.generics.clean(),
+                fields: self.fields.clean(),
+            }),
+        }
+    }
+}
+
+/// This is a more limited form of the standard Struct, different in that it
+/// it lacks the things most items have (name, id, parameterization). Found
+/// only as a variant in an enum.
+#[deriving(Clone, Encodable, Decodable)]
+pub struct VariantStruct {
+    struct_type: doctree::StructType,
+    fields: ~[Item],
+}
+
+impl Clean<VariantStruct> for syntax::ast::struct_def {
+    fn clean(&self) -> VariantStruct {
+        VariantStruct {
+            struct_type: doctree::struct_type_from_def(self),
+            fields: self.fields.clean(),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Enum {
+    variants: ~[Item],
+    generics: Generics,
+}
+
+impl Clean<Item> for doctree::Enum {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: EnumItem(Enum {
+                variants: self.variants.clean(),
+                generics: self.generics.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Variant {
+    kind: VariantKind,
+}
+
+impl Clean<Item> for doctree::Variant {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            visibility: self.vis.clean(),
+            id: self.id,
+            inner: VariantItem(Variant {
+                kind: self.kind.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum VariantKind {
+    CLikeVariant,
+    TupleVariant(~[Type]),
+    StructVariant(VariantStruct),
+}
+
+impl Clean<VariantKind> for ast::variant_kind {
+    fn clean(&self) -> VariantKind {
+        match self {
+            &ast::tuple_variant_kind(ref args) => {
+                if args.len() == 0 {
+                    CLikeVariant
+                } else {
+                    TupleVariant(args.iter().map(|x| x.ty.clean()).collect())
+                }
+            },
+            &ast::struct_variant_kind(ref sd) => StructVariant(sd.clean()),
+        }
+    }
+}
+
+impl Clean<~str> for syntax::codemap::Span {
+    fn clean(&self) -> ~str {
+        let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap;
+        cm.span_to_str(*self)
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Path {
+    global: bool,
+    segments: ~[PathSegment],
+}
+
+impl Clean<Path> for ast::Path {
+    fn clean(&self) -> Path {
+        Path {
+            global: self.global,
+            segments: self.segments.clean()
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct PathSegment {
+    name: ~str,
+    lifetime: Option<Lifetime>,
+    types: ~[Type],
+}
+
+impl Clean<PathSegment> for ast::PathSegment {
+    fn clean(&self) -> PathSegment {
+        PathSegment {
+            name: self.identifier.clean(),
+            lifetime: self.lifetime.clean(),
+            types: self.types.clean()
+        }
+    }
+}
+
+fn path_to_str(p: &ast::Path) -> ~str {
+    use syntax::parse::token::interner_get;
+
+    let mut s = ~"";
+    let mut first = true;
+    for i in p.segments.iter().map(|x| interner_get(x.identifier.name)) {
+        if !first || p.global {
+            s.push_str("::");
+        } else {
+            first = false;
+        }
+        s.push_str(i);
+    }
+    s
+}
+
+impl Clean<~str> for ast::Ident {
+    fn clean(&self) -> ~str {
+        its(self).to_owned()
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Typedef {
+    type_: Type,
+    generics: Generics,
+}
+
+impl Clean<Item> for doctree::Typedef {
+    fn clean(&self) -> Item {
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id.clone(),
+            visibility: self.vis.clean(),
+            inner: TypedefItem(Typedef {
+                type_: self.ty.clean(),
+                generics: self.gen.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct BareFunctionDecl {
+    purity: ast::purity,
+    generics: Generics,
+    decl: FnDecl,
+    abi: ~str
+}
+
+impl Clean<BareFunctionDecl> for ast::TyBareFn {
+    fn clean(&self) -> BareFunctionDecl {
+        BareFunctionDecl {
+            purity: self.purity,
+            generics: Generics {
+                lifetimes: self.lifetimes.clean(),
+                type_params: ~[],
+            },
+            decl: self.decl.clean(),
+            abi: self.abis.to_str(),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Static {
+    type_: Type,
+    mutability: Mutability,
+    /// It's useful to have the value of a static documented, but I have no
+    /// desire to represent expressions (that'd basically be all of the AST,
+    /// which is huge!). So, have a string.
+    expr: ~str,
+}
+
+impl Clean<Item> for doctree::Static {
+    fn clean(&self) -> Item {
+        debug!("claning static %s: %?", self.name.clean(), self);
+        Item {
+            name: Some(self.name.clean()),
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: StaticItem(Static {
+                type_: self.type_.clean(),
+                mutability: self.mutability.clean(),
+                expr: self.expr.span.to_src(),
+            }),
+        }
+    }
+}
+
+#[deriving(ToStr, Clone, Encodable, Decodable)]
+pub enum Mutability {
+    Mutable,
+    Immutable,
+}
+
+impl Clean<Mutability> for ast::Mutability {
+    fn clean(&self) -> Mutability {
+        match self {
+            &ast::MutMutable => Mutable,
+            &ast::MutImmutable => Immutable,
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct Impl {
+    generics: Generics,
+    trait_: Option<Type>,
+    for_: Type,
+    methods: ~[Item],
+}
+
+impl Clean<Item> for doctree::Impl {
+    fn clean(&self) -> Item {
+        Item {
+            name: None,
+            attrs: self.attrs.clean(),
+            source: self.where.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: ImplItem(Impl {
+                generics: self.generics.clean(),
+                trait_: self.trait_.clean(),
+                for_: self.for_.clean(),
+                methods: self.methods.clean(),
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub struct ViewItem {
+    inner: ViewItemInner
+}
+
+impl Clean<Item> for ast::view_item {
+    fn clean(&self) -> Item {
+        Item {
+            name: None,
+            attrs: self.attrs.clean(),
+            source: self.span.clean(),
+            id: 0,
+            visibility: self.vis.clean(),
+            inner: ViewItemItem(ViewItem {
+                inner: self.node.clean()
+            }),
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum ViewItemInner {
+    ExternMod(~str, Option<~str>, ~[Attribute], ast::NodeId),
+    Import(~[ViewPath])
+}
+
+impl Clean<ViewItemInner> for ast::view_item_ {
+    fn clean(&self) -> ViewItemInner {
+        match self {
+            &ast::view_item_extern_mod(ref i, ref p, ref mi, ref id) =>
+                ExternMod(i.clean(), p.map(|x| x.to_owned()),  mi.clean(), *id),
+            &ast::view_item_use(ref vp) => Import(vp.clean())
+        }
+    }
+}
+
+#[deriving(Clone, Encodable, Decodable)]
+pub enum ViewPath {
+    SimpleImport(~str, Path, ast::NodeId),
+    GlobImport(Path, ast::NodeId),
+    ImportList(Path, ~[ViewListIdent], ast::NodeId)
+}
+
+impl Clean<ViewPath> for ast::view_path {
+    fn clean(&self) -> ViewPath {
+        match self.node {
+            ast::view_path_simple(ref i, ref p, ref id) => SimpleImport(i.clean(), p.clean(), *id),
+            ast::view_path_glob(ref p, ref id) => GlobImport(p.clean(), *id),
+            ast::view_path_list(ref p, ref pl, ref id) => ImportList(p.clean(), pl.clean(), *id),
+        }
+    }
+}
+
+pub type ViewListIdent = ~str;
+
+impl Clean<ViewListIdent> for ast::path_list_ident {
+    fn clean(&self) -> ViewListIdent {
+        self.node.name.clean()
+    }
+}
+
+// Utilities
+
+trait ToSource {
+    fn to_src(&self) -> ~str;
+}
+
+impl ToSource for syntax::codemap::Span {
+    fn to_src(&self) -> ~str {
+        debug!("converting span %s to snippet", self.clean());
+        let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap.clone();
+        let sn = match cm.span_to_snippet(*self) {
+            Some(x) => x,
+            None    => ~""
+        };
+        debug!("got snippet %s", sn);
+        sn
+    }
+}
+
+fn lit_to_str(lit: &ast::lit) -> ~str {
+    match lit.node {
+        ast::lit_str(st) => st.to_owned(),
+        ast::lit_char(c) => ~"'" + std::char::from_u32(c).unwrap().to_str() + "'",
+        ast::lit_int(i, _t) => i.to_str(),
+        ast::lit_uint(u, _t) => u.to_str(),
+        ast::lit_int_unsuffixed(i) => i.to_str(),
+        ast::lit_float(f, _t) => f.to_str(),
+        ast::lit_float_unsuffixed(f) => f.to_str(),
+        ast::lit_bool(b) => b.to_str(),
+        ast::lit_nil => ~"",
+    }
+}
+
+fn name_from_pat(p: &ast::Pat) -> ~str {
+    use syntax::ast::*;
+    match p.node {
+        PatWild => ~"_",
+        PatIdent(_, ref p, _) => path_to_str(p),
+        PatEnum(ref p, _) => path_to_str(p),
+        PatStruct(*) => fail!("tried to get argument name from pat_struct, \
+                                which is not allowed in function arguments"),
+        PatTup(*) => ~"(tuple arg NYI)",
+        PatBox(p) => name_from_pat(p),
+        PatUniq(p) => name_from_pat(p),
+        PatRegion(p) => name_from_pat(p),
+        PatLit(*) => fail!("tried to get argument name from pat_lit, \
+                            which is not allowed in function arguments"),
+        PatRange(*) => fail!("tried to get argument name from pat_range, \
+                              which is not allowed in function arguments"),
+        PatVec(*) => fail!("tried to get argument name from pat_vec, \
+                             which is not allowed in function arguments")
+    }
+}
+
+fn remove_comment_tags(s: &str) -> ~str {
+    if s.starts_with("/") {
+        match s.slice(0,3) {
+            &"///" => return s.slice(3, s.len()).trim().to_owned(),
+            &"/**" | &"/*!" => return s.slice(3, s.len() - 2).trim().to_owned(),
+            _ => return s.trim().to_owned()
+        }
+    } else {
+        return s.to_owned();
+    }
+}
+
+/// Given a Type, resolve it using the def_map
+fn resolve_type(t: &Type) -> Type {
+    use syntax::ast::*;
+
+    let (path, tpbs, id) = match t {
+        &Unresolved(ref path, ref tbps, id) => (path, tbps, id),
+        _ => return (*t).clone(),
+    };
+
+    let dm = local_data::get(super::ctxtkey, |x| *x.unwrap()).tycx.def_map;
+    debug!("searching for %? in defmap", id);
+    let d = match dm.find(&id) {
+        Some(k) => k,
+        None => {
+            let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+            debug!("could not find %? in defmap (`%s`)", id,
+                   syntax::ast_map::node_id_to_str(ctxt.tycx.items, id, ctxt.sess.intr()));
+            fail!("Unexpected failure: unresolved id not in defmap (this is a bug!)")
+        }
+    };
+
+    let def_id = match *d {
+        DefFn(i, _) => i,
+        DefSelf(i) | DefSelfTy(i) => return Self(i),
+        DefTy(i) => i,
+        DefTrait(i) => {
+            debug!("saw DefTrait in def_to_id");
+            i
+        },
+        DefPrimTy(p) => match p {
+            ty_str => return String,
+            ty_bool => return Bool,
+            _ => return Primitive(p)
+        },
+        DefTyParam(i, _) => return Generic(i.node),
+        DefStruct(i) => i,
+        DefTyParamBinder(i) => {
+            debug!("found a typaram_binder, what is it? %d", i);
+            return TyParamBinder(i);
+        },
+        x => fail!("resolved type maps to a weird def %?", x),
+    };
+
+    if def_id.crate != ast::CRATE_NODE_ID {
+        use rustc::metadata::decoder::*;
+
+        let sess = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess;
+        let cratedata = ::rustc::metadata::cstore::get_crate_data(sess.cstore, def_id.crate);
+        let doc = lookup_item(def_id.node, cratedata.data);
+        let path = syntax::ast_map::path_to_str_with_sep(item_path(doc), "::", sess.intr());
+        let ty = match def_like_to_def(item_to_def_like(doc, def_id, def_id.crate)) {
+            DefFn(*) => ~"fn",
+            DefTy(*) => ~"enum",
+            DefTrait(*) => ~"trait",
+            DefPrimTy(p) => match p {
+                ty_str => ~"str",
+                ty_bool => ~"bool",
+                ty_int(t) => match t.to_str() {
+                    ~"" => ~"i",
+                    s => s
+                },
+                ty_uint(t) => t.to_str(),
+                ty_float(t) => t.to_str(),
+                ty_char => ~"char",
+            },
+            DefTyParam(*) => ~"generic",
+            DefStruct(*) => ~"struct",
+            DefTyParamBinder(*) => ~"typaram_binder",
+            x => fail!("resolved external maps to a weird def %?", x),
+        };
+        let cname = cratedata.name.to_owned();
+        External(cname + "::" + path, ty)
+    } else {
+        ResolvedPath {path: path.clone(), typarams: tpbs.clone(), id: def_id.node}
+    }
+}
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
deleted file mode 100644 (file)
index 71ece17..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use std::cell::Cell;
-use std::os;
-use std::result::Result;
-use std::result;
-use std::run::ProcessOutput;
-use std::run;
-use std::vec;
-use extra::getopts;
-
-/// The type of document to output
-#[deriving(Clone, Eq)]
-pub enum OutputFormat {
-    /// Markdown
-    Markdown,
-    /// HTML, via markdown and pandoc
-    PandocHtml
-}
-
-/// How to organize the output
-#[deriving(Clone, Eq)]
-pub enum OutputStyle {
-    /// All in a single document
-    DocPerCrate,
-    /// Each module in its own document
-    DocPerMod
-}
-
-/// The configuration for a rustdoc session
-#[deriving(Clone)]
-pub struct Config {
-    input_crate: Path,
-    output_dir: Path,
-    output_format: OutputFormat,
-    output_style: OutputStyle,
-    pandoc_cmd: Option<~str>
-}
-
-fn opt_output_dir() -> ~str { ~"output-dir" }
-fn opt_output_format() -> ~str { ~"output-format" }
-fn opt_output_style() -> ~str { ~"output-style" }
-fn opt_pandoc_cmd() -> ~str { ~"pandoc-cmd" }
-fn opt_help() -> ~str { ~"h" }
-
-fn opts() -> ~[(getopts::Opt, ~str)] {
-    ~[
-        (getopts::optopt(opt_output_dir()),
-         ~"--output-dir <val>     Put documents here (default: .)"),
-        (getopts::optopt(opt_output_format()),
-         ~"--output-format <val>  'markdown' or 'html' (default)"),
-        (getopts::optopt(opt_output_style()),
-         ~"--output-style <val>   'doc-per-crate' or 'doc-per-mod' (default)"),
-        (getopts::optopt(opt_pandoc_cmd()),
-         ~"--pandoc-cmd <val>     Command for running pandoc"),
-        (getopts::optflag(opt_help()),
-         ~"-h, --help             Print help")
-    ]
-}
-
-pub fn usage() {
-    use std::io::println;
-
-    println("Usage: rustdoc [options] <cratefile>\n");
-    println("Options:\n");
-    let r = opts();
-    for opt in r.iter() {
-        printfln!("    %s", opt.second());
-    }
-    println("");
-}
-
-pub fn default_config(input_crate: &Path) -> Config {
-    Config {
-        input_crate: (*input_crate).clone(),
-        output_dir: Path("."),
-        output_format: PandocHtml,
-        output_style: DocPerMod,
-        pandoc_cmd: None
-    }
-}
-
-type Process = ~fn((&str), (&[~str])) -> ProcessOutput;
-
-pub fn mock_process_output(_prog: &str, _args: &[~str]) -> ProcessOutput {
-    ProcessOutput {
-        status: 0,
-        output: ~[],
-        error: ~[]
-    }
-}
-
-pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
-    run::process_output(prog, args)
-}
-
-pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
-    parse_config_(args, process_output)
-}
-
-pub fn parse_config_(
-    args: &[~str],
-    process_output: Process
-) -> Result<Config, ~str> {
-    let args = args.tail();
-    let opts = vec::unzip(opts().move_iter()).first();
-    match getopts::getopts(args, opts) {
-        Ok(matches) => {
-            if matches.free.len() == 1 {
-                let input_crate = Path(*matches.free.head());
-                config_from_opts(&input_crate, &matches, process_output)
-            } else if matches.free.is_empty() {
-                Err(~"no crates specified")
-            } else {
-                Err(~"multiple crates specified")
-            }
-        }
-        Err(f) => {
-            Err(f.to_err_msg())
-        }
-    }
-}
-
-fn config_from_opts(
-    input_crate: &Path,
-    matches: &getopts::Matches,
-    process_output: Process
-) -> Result<Config, ~str> {
-
-    let config = default_config(input_crate);
-    let result = result::Ok(config);
-    let result = do result.and_then |config| {
-        let output_dir = matches.opt_str(opt_output_dir());
-        let output_dir = output_dir.map_move(|s| Path(s));
-        result::Ok(Config {
-            output_dir: output_dir.unwrap_or(config.output_dir.clone()),
-            .. config
-        })
-    };
-    let result = do result.and_then |config| {
-        let output_format = matches.opt_str(opt_output_format());
-        do output_format.map_move_default(result::Ok(config.clone())) |output_format| {
-            do parse_output_format(output_format).and_then |output_format| {
-                result::Ok(Config {
-                    output_format: output_format,
-                    .. config.clone()
-                })
-            }
-        }
-    };
-    let result = do result.and_then |config| {
-        let output_style =
-            matches.opt_str(opt_output_style());
-        do output_style.map_move_default(result::Ok(config.clone())) |output_style| {
-            do parse_output_style(output_style).and_then |output_style| {
-                result::Ok(Config {
-                    output_style: output_style,
-                    .. config.clone()
-                })
-            }
-        }
-    };
-    let process_output = Cell::new(process_output);
-    let result = do result.and_then |config| {
-        let pandoc_cmd = matches.opt_str(opt_pandoc_cmd());
-        let pandoc_cmd = maybe_find_pandoc(
-            &config, pandoc_cmd, process_output.take());
-        do pandoc_cmd.and_then |pandoc_cmd| {
-            result::Ok(Config {
-                pandoc_cmd: pandoc_cmd,
-                .. config.clone()
-            })
-        }
-    };
-    return result;
-}
-
-fn parse_output_format(output_format: &str) -> Result<OutputFormat, ~str> {
-    match output_format.to_str() {
-      ~"markdown" => result::Ok(Markdown),
-      ~"html" => result::Ok(PandocHtml),
-      _ => result::Err(fmt!("unknown output format '%s'", output_format))
-    }
-}
-
-fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
-    match output_style.to_str() {
-      ~"doc-per-crate" => result::Ok(DocPerCrate),
-      ~"doc-per-mod" => result::Ok(DocPerMod),
-      _ => result::Err(fmt!("unknown output style '%s'", output_style))
-    }
-}
-
-pub fn maybe_find_pandoc(
-    config: &Config,
-    maybe_pandoc_cmd: Option<~str>,
-    process_output: Process
-) -> Result<Option<~str>, ~str> {
-    if config.output_format != PandocHtml {
-        return result::Ok(maybe_pandoc_cmd);
-    }
-
-    let possible_pandocs = match maybe_pandoc_cmd {
-      Some(pandoc_cmd) => ~[pandoc_cmd],
-      None => {
-        ~[~"pandoc"] + match os::homedir() {
-          Some(dir) => {
-            ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()]
-          }
-          None => ~[]
-        }
-      }
-    };
-
-    let pandoc = do possible_pandocs.iter().find |&pandoc| {
-        let output = process_output(*pandoc, [~"--version"]);
-        debug!("testing pandoc cmd %s: %?", *pandoc, output);
-        output.status == 0
-    };
-
-    match pandoc {
-        Some(x) => Ok(Some((*x).clone())), // ugly, shouldn't be doubly wrapped
-        None => Err(~"couldn't find pandoc")
-    }
-}
-
-#[cfg(test)]
-mod test {
-
-    use config::*;
-    use std::result;
-    use std::run::ProcessOutput;
-
-    fn parse_config(args: &[~str]) -> Result<Config, ~str> {
-        parse_config_(args, mock_process_output)
-    }
-
-    #[test]
-    fn should_find_pandoc() {
-        let config = Config {
-            output_format: PandocHtml,
-            .. default_config(&Path("test"))
-        };
-        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
-            ProcessOutput { status: 0, output: "pandoc 1.8.2.1".as_bytes().to_owned(), error: ~[] }
-        };
-        let result = maybe_find_pandoc(&config, None, mock_process_output);
-        assert!(result == result::Ok(Some(~"pandoc")));
-    }
-
-    #[test]
-    fn should_error_with_no_pandoc() {
-        let config = Config {
-            output_format: PandocHtml,
-            .. default_config(&Path("test"))
-        };
-        let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
-            ProcessOutput { status: 1, output: ~[], error: ~[] }
-        };
-        let result = maybe_find_pandoc(&config, None, mock_process_output);
-        assert!(result == result::Err(~"couldn't find pandoc"));
-    }
-
-    #[test]
-    fn should_error_with_no_crates() {
-        let config = parse_config([~"rustdoc"]);
-        assert!(config.unwrap_err() == ~"no crates specified");
-    }
-
-    #[test]
-    fn should_error_with_multiple_crates() {
-        let config =
-            parse_config([~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
-        assert!(config.unwrap_err() == ~"multiple crates specified");
-    }
-
-    #[test]
-    fn should_set_output_dir_to_cwd_if_not_provided() {
-        let config = parse_config([~"rustdoc", ~"crate.rc"]);
-        assert!(config.unwrap().output_dir == Path("."));
-    }
-
-    #[test]
-    fn should_set_output_dir_if_provided() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
-        ]);
-        assert!(config.unwrap().output_dir == Path("snuggles"));
-    }
-
-    #[test]
-    fn should_set_output_format_to_pandoc_html_if_not_provided() {
-        let config = parse_config([~"rustdoc", ~"crate.rc"]);
-        assert!(config.unwrap().output_format == PandocHtml);
-    }
-
-    #[test]
-    fn should_set_output_format_to_markdown_if_requested() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
-        ]);
-        assert!(config.unwrap().output_format == Markdown);
-    }
-
-    #[test]
-    fn should_set_output_format_to_pandoc_html_if_requested() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
-        ]);
-        assert!(config.unwrap().output_format == PandocHtml);
-    }
-
-    #[test]
-    fn should_error_on_bogus_format() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
-        ]);
-        assert!(config.unwrap_err() == ~"unknown output format 'bogus'");
-    }
-
-    #[test]
-    fn should_set_output_style_to_doc_per_mod_by_default() {
-        let config = parse_config([~"rustdoc", ~"crate.rc"]);
-        assert!(config.unwrap().output_style == DocPerMod);
-    }
-
-    #[test]
-    fn should_set_output_style_to_one_doc_if_requested() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
-        ]);
-        assert!(config.unwrap().output_style == DocPerCrate);
-    }
-
-    #[test]
-    fn should_set_output_style_to_doc_per_mod_if_requested() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
-        ]);
-        assert!(config.unwrap().output_style == DocPerMod);
-    }
-
-    #[test]
-    fn should_error_on_bogus_output_style() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
-        ]);
-        assert!(config.unwrap_err() == ~"unknown output style 'bogus'");
-    }
-
-    #[test]
-    fn should_set_pandoc_command_if_requested() {
-        let config = parse_config([
-            ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
-        ]);
-        assert!(config.unwrap().pandoc_cmd == Some(~"panda-bear-doc"));
-    }
-
-    #[test]
-    fn should_set_pandoc_command_when_using_pandoc() {
-        let config = parse_config([~"rustdoc", ~"crate.rc"]);
-        assert!(config.unwrap().pandoc_cmd == Some(~"pandoc"));
-    }
-}
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
new file mode 100644 (file)
index 0000000..9fb5e8c
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc;
+use rustc::{driver, middle};
+
+use syntax;
+use syntax::parse;
+use syntax::ast;
+
+use std::os;
+use std::local_data;
+
+use visit_ast::RustdocVisitor;
+use clean;
+use clean::Clean;
+
+pub struct DocContext {
+    crate: @ast::Crate,
+    tycx: middle::ty::ctxt,
+    sess: driver::session::Session
+}
+
+/// Parses, resolves, and typechecks the given crate
+fn get_ast_and_resolve(cpath: &Path, libs: ~[Path]) -> DocContext {
+    use syntax::codemap::dummy_spanned;
+    use rustc::driver::driver::*;
+
+    let parsesess = parse::new_parse_sess(None);
+    let input = file_input(cpath.clone());
+
+    let sessopts = @driver::session::options {
+        binary: @"rustdoc",
+        maybe_sysroot: Some(@os::self_exe_path().unwrap().pop()),
+        addl_lib_search_paths: @mut libs,
+        .. (*rustc::driver::session::basic_options()).clone()
+    };
+
+
+    let diagnostic_handler = syntax::diagnostic::mk_handler(None);
+    let span_diagnostic_handler =
+        syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
+
+    let sess = driver::driver::build_session_(sessopts, parsesess.cm,
+                                                  syntax::diagnostic::emit,
+                                                  span_diagnostic_handler);
+
+    let mut cfg = build_configuration(sess);
+    cfg.push(@dummy_spanned(ast::MetaWord(@"stage2")));
+
+    let mut crate = phase_1_parse_input(sess, cfg.clone(), &input);
+    crate = phase_2_configure_and_expand(sess, cfg, crate);
+    let analysis = phase_3_run_analysis_passes(sess, crate);
+
+    debug!("crate: %?", crate);
+    DocContext { crate: crate, tycx: analysis.ty_cx, sess: sess }
+}
+
+pub fn run_core (libs: ~[Path], path: &Path) -> clean::Crate {
+    let ctxt = @get_ast_and_resolve(path, libs);
+    debug!("defmap:");
+    for (k, v) in ctxt.tycx.def_map.iter() {
+        debug!("%?: %?", k, v);
+    }
+    local_data::set(super::ctxtkey, ctxt);
+
+    let v = @mut RustdocVisitor::new();
+    v.visit(ctxt.crate);
+
+    v.clean()
+}
diff --git a/src/librustdoc/demo.rs b/src/librustdoc/demo.rs
deleted file mode 100644 (file)
index 23c5548..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-reformat
-
-/*!
- * A demonstration module
- *
- * Contains documentation in various forms that rustdoc understands,
- * for testing purposes. It doesn't surve any functional
- * purpose. This here, for instance, is just some filler text.
- *
- * FIXME (#3731): It would be nice if we could run some automated
- * tests on this file
- */
-
-
-/// The base price of a muffin on a non-holiday
-static PRICE_OF_A_MUFFIN: float = 70f;
-
-struct WaitPerson {
-    hair_color: ~str
-}
-
-/// The type of things that produce omnomnom
-enum OmNomNomy {
-    /// Delicious sugar cookies
-    Cookie,
-    /// It's pizza
-    PizzaPie(~[uint])
-}
-
-fn take_my_order_please(
-    _waitperson: WaitPerson,
-    _order: ~[OmNomNomy]
-) -> uint {
-
-    /*!
-     * OMG would you take my order already?
-     *
-     * # Arguments
-     *
-     * * _waitperson - The waitperson that you want to bother
-     * * _order - The order vector. It should be filled with food
-     *
-     * # Return
-     *
-     * The price of the order, including tax
-     *
-     * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
-     * molestie nisl. Duis massa risus, pharetra a scelerisque a,
-     * molestie eu velit. Donec mattis ligula at ante imperdiet ut
-     * dapibus mauris malesuada.
-     *
-     * Sed gravida nisi a metus elementum sit amet hendrerit dolor
-     * bibendum. Aenean sit amet neque massa, sed tempus tortor. Sed ut
-     * lobortis enim. Proin a mauris quis nunc fermentum ultrices eget a
-     * erat. Mauris in lectus vitae metus sodales auctor. Morbi nunc
-     * quam, ultricies at venenatis non, pellentesque ac dui.
-     *
-     * # Failure
-     *
-     * This function is full of fail
-     */
-
-    fail!();
-}
-
-mod fortress_of_solitude {
-    /*!
-     * Superman's vacation home
-     *
-     * The fortress of solitude is located in the Arctic and it is
-     * cold. What you may not know about the fortress of solitude
-     * though is that it contains two separate bowling alleys. One of
-     * them features bumper-bowling and is kind of lame.
-     *
-     * Really, it's pretty cool.
-     */
-
-}
-
-mod blade_runner {
-    /*!
-     * Blade Runner is probably the best movie ever
-     *
-     * I like that in the world of Blade Runner it is always
-     * raining, and that it's always night time. And Aliens
-     * was also a really good movie.
-     *
-     * Alien 3 was crap though.
-     */
-}
-
-/**
- * Bored
- *
- * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec
- * molestie nisl. Duis massa risus, pharetra a scelerisque a,
- * molestie eu velit. Donec mattis ligula at ante imperdiet ut
- * dapibus mauris malesuada. Sed gravida nisi a metus elementum sit
- * amet hendrerit dolor bibendum. Aenean sit amet neque massa, sed
- * tempus tortor. Sed ut lobortis enim. Proin a mauris quis nunc
- * fermentum ultrices eget a erat. Mauris in lectus vitae metus
- * sodales auctor. Morbi nunc quam, ultricies at venenatis non,
- * pellentesque ac dui.
- *
- * Quisque vitae est id eros placerat laoreet sit amet eu
- * nisi. Curabitur suscipit neque porttitor est euismod
- * lacinia. Curabitur non quam vitae ipsum adipiscing
- * condimentum. Mauris ut ante eget metus sollicitudin
- * blandit. Aliquam erat volutpat. Morbi sed nisl mauris. Nulla
- * facilisi. Phasellus at mollis ipsum. Maecenas sed convallis
- * sapien. Nullam in ligula turpis. Pellentesque a neque augue. Sed
- * eget ante feugiat tortor congue auctor ac quis ante. Proin
- * condimentum lacinia tincidunt.
- */
-struct Bored {
-  bored: bool,
-}
-
-impl Drop for Bored {
-  fn drop(&mut self) { }
-}
-
-/**
- * The Shunned House
- *
- * From even the greatest of horrors irony is seldom absent. Sometimes it
- * enters directly into the composition of the events, while sometimes it
- * relates only to their fortuitous position among persons and
- * places. The latter sort is splendidly exemplified by a case in the
- * ancient city of Providence, where in the late forties Edgar Allan Poe
- * used to sojourn often during his unsuccessful wooing of the gifted
- * poetess, Mrs.  Whitman. Poe generally stopped at the Mansion House in
- * Benefit Street--the renamed Golden Ball Inn whose roof has sheltered
- * Washington, Jefferson, and Lafayette--and his favorite walk led
- * northward along the same street to Mrs. Whitman's home and the
- * neighboring hillside churchyard of St. John's, whose hidden expanse of
- * Eighteenth Century gravestones had for him a peculiar fascination.
- */
-trait TheShunnedHouse {
-    /**
-     * Now the irony is this. In this walk, so many times repeated, the
-     * world's greatest master of the terrible and the bizarre was
-     * obliged to pass a particular house on the eastern side of the
-     * street; a dingy, antiquated structure perched on the abruptly
-     * rising side hill, with a great unkempt yard dating from a time
-     * when the region was partly open country. It does not appear that
-     * he ever wrote or spoke of it, nor is there any evidence that he
-     * even noticed it. And yet that house, to the two persons in
-     * possession of certain information, equals or outranks in horror
-     * the wildest fantasy of the genius who so often passed it
-     * unknowingly, and stands starkly leering as a symbol of all that is
-     * unutterably hideous.
-     *
-     * # Arguments
-     *
-     * * unkempt_yard - A yard dating from a time when the region was partly
-     *                  open country
-     */
-    fn dingy_house(&self, unkempt_yard: int);
-
-    /**
-     * The house was--and for that matter still is--of a kind to attract
-     * the attention of the curious. Originally a farm or semi-farm
-     * building, it followed the average New England colonial lines of
-     * the middle Eighteenth Century--the prosperous peaked-roof sort,
-     * with two stories and dormerless attic, and with the Georgian
-     * doorway and interior panelling dictated by the progress of taste
-     * at that time. It faced south, with one gable end buried to the
-     * lower windows in the eastward rising hill, and the other exposed
-     * to the foundations toward the street. Its construction, over a
-     * century and a half ago, had followed the grading and straightening
-     * of the road in that especial vicinity; for Benefit Street--at
-     * first called Back Street--was laid out as a lane winding amongst
-     * the graveyards of the first settlers, and straightened only when
-     * the removal of the bodies to the North Burial Ground made it
-     * decently possible to cut through the old family plots.
-     */
-    fn construct(&self) -> bool;
-}
-
-/// Whatever
-impl TheShunnedHouse for OmNomNomy {
-    fn dingy_house(&self, _unkempt_yard: int) {
-    }
-
-    fn construct(&self) -> bool {
-        fail!();
-    }
-}
diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs
deleted file mode 100644 (file)
index 9f80417..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Pulls a brief description out of a long description.
-
-If the first paragraph of a long description is short enough then it
-is interpreted as the brief description.
-*/
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-use std::util;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"desc_to_brief",
-        f: run
-    }
-}
-
-pub fn run(
-    _srv: astsrv::Srv,
-    doc: doc::Doc
-) -> doc::Doc {
-    let fold = Fold {
-        fold_item: fold_item,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        .. fold::default_any_fold(())
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_item(fold: &fold::Fold<()>, doc: doc::ItemDoc) -> doc::ItemDoc {
-    let doc = fold::default_seq_fold_item(fold, doc);
-
-    doc::ItemDoc {
-        brief: extract(doc.desc.clone()),
-        .. doc
-    }
-}
-
-fn fold_trait(fold: &fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc {
-    let doc =fold::default_seq_fold_trait(fold, doc);
-
-    doc::TraitDoc {
-        methods: doc.methods.map(|doc| doc::MethodDoc {
-            brief: extract(doc.desc.clone()),
-            .. (*doc).clone()
-        }),
-        .. doc
-    }
-}
-
-fn fold_impl(fold: &fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc {
-    let doc =fold::default_seq_fold_impl(fold, doc);
-
-    doc::ImplDoc {
-        methods: doc.methods.map(|doc| doc::MethodDoc {
-            brief: extract(doc.desc.clone()),
-            .. (*doc).clone()
-        }),
-        .. doc
-    }
-}
-
-pub fn extract(desc: Option<~str>) -> Option<~str> {
-    if desc.is_none() {
-        return None
-    }
-
-    parse_desc(desc.clone().unwrap())
-}
-
-fn parse_desc(desc: ~str) -> Option<~str> {
-    static MAX_BRIEF_LEN: uint = 120u;
-
-    match first_sentence(desc.clone()) {
-      Some(first_sentence) => {
-        if first_sentence.len() <= MAX_BRIEF_LEN {
-            Some(first_sentence)
-        } else {
-            None
-        }
-      }
-      None => None
-    }
-}
-
-fn first_sentence(s: ~str) -> Option<~str> {
-    let paras = paragraphs(s);
-    if !paras.is_empty() {
-        let first_para = paras.head();
-        Some(first_sentence_(*first_para).replace("\n", " "))
-    } else {
-        None
-    }
-}
-
-fn first_sentence_(s: &str) -> ~str {
-    let mut dotcount = 0;
-    // The index of the character following a single dot. This allows
-    // Things like [0..1) to appear in the brief description
-    let idx = s.find(|ch: char| {
-        if ch == '.' {
-            dotcount += 1;
-            false
-        } else if dotcount == 1 {
-            true
-        } else {
-            dotcount = 0;
-            false
-        }
-    });
-    match idx {
-        Some(idx) if idx > 2u => s.slice(0, idx - 1).to_owned(),
-        _ => {
-            if s.ends_with(".") {
-                s.to_owned()
-            } else {
-                s.to_owned()
-            }
-        }
-    }
-}
-
-pub fn paragraphs(s: &str) -> ~[~str] {
-    let mut whitespace_lines = 0;
-    let mut accum = ~"";
-    let mut paras = do s.any_line_iter().fold(~[]) |paras, line| {
-        let mut res = paras;
-
-        if line.is_whitespace() {
-            whitespace_lines += 1;
-        } else {
-            if whitespace_lines > 0 {
-                if !accum.is_empty() {
-                    let v = util::replace(&mut accum, ~"");
-                    res.push(v);
-                }
-            }
-
-            whitespace_lines = 0;
-
-            accum = if accum.is_empty() {
-                line.to_owned()
-            } else {
-                fmt!("%s\n%s", accum, line)
-            }
-        }
-
-        res
-    };
-
-    if !accum.is_empty() { paras.push(accum); }
-    paras
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass;
-    use super::{extract, paragraphs, run};
-    use doc;
-    use extract;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_promote_desc() {
-        let doc = mk_doc(~"#[doc = \"desc\"] mod m { }");
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().mods()[1].brief(), Some(~"desc"));
-    }
-
-    #[test]
-    fn should_promote_trait_method_desc() {
-        let doc = mk_doc(~"trait i { #[doc = \"desc\"] fn a(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].brief ==
-                Some(~"desc"));
-    }
-
-    #[test]
-    fn should_promote_impl_method_desc() {
-        let doc = mk_doc(
-            ~"impl int { #[doc = \"desc\"] fn a() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].brief == Some(~"desc"));
-    }
-
-    #[test]
-    fn test_paragraphs_1() {
-        let paras = paragraphs("1\n\n2");
-        assert_eq!(paras, ~[~"1", ~"2"]);
-    }
-
-    #[test]
-    fn test_paragraphs_2() {
-        let paras = paragraphs("\n\n1\n1\n\n2\n\n");
-        assert_eq!(paras, ~[~"1\n1", ~"2"]);
-    }
-
-    #[test]
-    fn should_promote_short_descs() {
-        let desc = Some(~"desc");
-        let brief = extract(desc.clone());
-        assert_eq!(brief, desc);
-    }
-
-    #[test]
-    fn should_not_promote_long_descs() {
-        let desc = Some(~"Warkworth Castle is a ruined medieval building
-in the town of the same name in the English county of Northumberland,
-and the town and castle occupy a loop of the River Coquet, less than a mile
-from England's north-east coast. When the castle was founded is uncertain,
-but traditionally its construction has been ascribed to Prince Henry of
-Scotland in the mid 12th century, although it may have been built by
-King Henry II of England when he took control of England'snorthern
-counties.");
-        let brief = extract(desc);
-        assert_eq!(brief, None);
-    }
-
-    #[test]
-    fn should_promote_first_sentence() {
-        let desc = Some(~"Warkworth Castle is a ruined medieval building
-in the town. of the same name in the English county of Northumberland,
-and the town and castle occupy a loop of the River Coquet, less than a mile
-from England's north-east coast. When the castle was founded is uncertain,
-but traditionally its construction has been ascribed to Prince Henry of
-Scotland in the mid 12th century, although it may have been built by
-King Henry II of England when he took control of England'snorthern
-counties.");
-        let brief = extract(desc);
-        assert!(brief == Some(
-            ~"Warkworth Castle is a ruined medieval building in the town"));
-    }
-
-    #[test]
-    fn should_not_consider_double_period_to_end_sentence() {
-        let desc = Some(~"Warkworth..Castle is a ruined medieval building
-in the town. of the same name in the English county of Northumberland,
-and the town and castle occupy a loop of the River Coquet, less than a mile
-from England's north-east coast. When the castle was founded is uncertain,
-but traditionally its construction has been ascribed to Prince Henry of
-Scotland in the mid 12th century, although it may have been built by
-King Henry II of England when he took control of England'snorthern
-counties.");
-        let brief = extract(desc);
-        assert!(brief == Some(
-            ~"Warkworth..Castle is a ruined medieval building in the town"));
-    }
-
-    #[test]
-    fn should_not_consider_triple_period_to_end_sentence() {
-        let desc = Some(~"Warkworth... Castle is a ruined medieval building
-in the town. of the same name in the English county of Northumberland,
-and the town and castle occupy a loop of the River Coquet, less than a mile
-from England's north-east coast. When the castle was founded is uncertain,
-but traditionally its construction has been ascribed to Prince Henry of
-Scotland in the mid 12th century, although it may have been built by
-King Henry II of England when he took control of England'snorthern
-counties.");
-        let brief = extract(desc);
-        assert!(brief == Some(
-            ~"Warkworth... Castle is a ruined medieval building in the town"));
-    }
-}
diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs
deleted file mode 100644 (file)
index aba7ea1..0000000
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! The document model
-
-
-use doc;
-
-pub type AstId = int;
-
-#[deriving(Clone, Eq)]
-pub struct Doc {
-    pages: ~[Page]
-}
-
-#[deriving(Clone, Eq)]
-pub enum Page {
-    CratePage(CrateDoc),
-    ItemPage(ItemTag)
-}
-
-#[deriving(Clone, Eq)]
-pub enum Implementation {
-    Required,
-    Provided,
-}
-
-/**
- * Most rustdocs can be parsed into 'sections' according to their markdown
- * headers
- */
-#[deriving(Clone, Eq)]
-pub struct Section {
-    header: ~str,
-    body: ~str
-}
-
-// FIXME (#2596): We currently give topmod the name of the crate.  There
-// would probably be fewer special cases if the crate had its own name
-// and topmod's name was the empty string.
-#[deriving(Clone, Eq)]
-pub struct CrateDoc {
-    topmod: ModDoc
-}
-
-#[deriving(Clone, Eq)]
-pub enum ItemTag {
-    ModTag(ModDoc),
-    NmodTag(NmodDoc),
-    StaticTag(StaticDoc),
-    FnTag(FnDoc),
-    EnumTag(EnumDoc),
-    TraitTag(TraitDoc),
-    ImplTag(ImplDoc),
-    TyTag(TyDoc),
-    StructTag(StructDoc)
-}
-
-#[deriving(Clone, Eq)]
-pub struct ItemDoc {
-    id: AstId,
-    name: ~str,
-    path: ~[~str],
-    brief: Option<~str>,
-    desc: Option<~str>,
-    sections: ~[Section],
-    // Indicates that this node is a reexport of a different item
-    reexport: bool
-}
-
-#[deriving(Clone, Eq)]
-pub struct SimpleItemDoc {
-    item: ItemDoc,
-    sig: Option<~str>
-}
-
-#[deriving(Clone, Eq)]
-pub struct ModDoc {
-    item: ItemDoc,
-    items: ~[ItemTag],
-    index: Option<Index>
-}
-
-#[deriving(Clone, Eq)]
-pub struct NmodDoc {
-    item: ItemDoc,
-    fns: ~[FnDoc],
-    index: Option<Index>
-}
-
-pub type StaticDoc = SimpleItemDoc;
-
-pub type FnDoc = SimpleItemDoc;
-
-#[deriving(Clone, Eq)]
-pub struct EnumDoc {
-    item: ItemDoc,
-    variants: ~[VariantDoc]
-}
-
-#[deriving(Clone, Eq)]
-pub struct VariantDoc {
-    name: ~str,
-    desc: Option<~str>,
-    sig: Option<~str>
-}
-
-#[deriving(Clone, Eq)]
-pub struct TraitDoc {
-    item: ItemDoc,
-    methods: ~[MethodDoc]
-}
-
-#[deriving(Clone, Eq)]
-pub struct MethodDoc {
-    name: ~str,
-    brief: Option<~str>,
-    desc: Option<~str>,
-    sections: ~[Section],
-    sig: Option<~str>,
-    implementation: Implementation,
-}
-
-#[deriving(Clone, Eq)]
-pub struct ImplDoc {
-    item: ItemDoc,
-    bounds_str: Option<~str>,
-    trait_types: ~[~str],
-    self_ty: Option<~str>,
-    methods: ~[MethodDoc]
-}
-
-pub type TyDoc = SimpleItemDoc;
-
-#[deriving(Clone, Eq)]
-pub struct StructDoc {
-    item: ItemDoc,
-    fields: ~[~str],
-    sig: Option<~str>
-}
-
-#[deriving(Clone, Eq)]
-pub struct Index {
-    entries: ~[IndexEntry]
-}
-
-/**
- * A single entry in an index
- *
- * Fields:
- *
- * * kind - The type of thing being indexed, e.g. 'Module'
- * * name - The name of the thing
- * * brief - The brief description
- * * link - A format-specific string representing the link target
- */
-#[deriving(Clone, Eq)]
-pub struct IndexEntry {
-    kind: ~str,
-    name: ~str,
-    brief: Option<~str>,
-    link: ~str
-}
-
-impl Doc {
-    pub fn CrateDoc(&self) -> CrateDoc {
-        self.pages.iter().fold(None, |_m, page| {
-            match (*page).clone() {
-              doc::CratePage(doc) => Some(doc),
-              _ => None
-            }
-        }).unwrap()
-    }
-
-    pub fn cratemod(&self) -> ModDoc {
-        self.CrateDoc().topmod.clone()
-    }
-}
-
-macro_rules! filt_mapper {
-    ($vec:expr, $pat:pat) => {
-        do ($vec).iter().filter_map |thing| {
-            match thing {
-                &$pat => Some((*x).clone()),
-                _ => None
-            }
-        }.collect()
-    }
-}
-
-macro_rules! md {
-    ($id:ident) => {
-        filt_mapper!(self.items, $id(ref x))
-    }
-}
-/// Some helper methods on ModDoc, mostly for testing
-impl ModDoc {
-    pub fn mods(&self) -> ~[ModDoc] {
-        md!(ModTag)
-    }
-
-    pub fn nmods(&self) -> ~[NmodDoc] {
-        md!(NmodTag)
-    }
-
-    pub fn fns(&self) -> ~[FnDoc] {
-        md!(FnTag)
-    }
-
-    pub fn statics(&self) -> ~[StaticDoc] {
-        md!(StaticTag)
-    }
-
-    pub fn enums(&self) -> ~[EnumDoc] {
-        md!(EnumTag)
-    }
-
-    pub fn traits(&self) -> ~[TraitDoc] {
-        md!(TraitTag)
-    }
-
-    pub fn impls(&self) -> ~[ImplDoc] {
-        md!(ImplTag)
-    }
-
-    pub fn types(&self) -> ~[TyDoc] {
-        md!(TyTag)
-    }
-
-    pub fn structs(&self) -> ~[StructDoc] {
-        md!(StructTag)
-    }
-}
-
-macro_rules! pu {
-    ($id:ident) => {
-        filt_mapper!(*self, ItemPage($id(ref x)))
-    }
-}
-
-pub trait PageUtils {
-    fn mods(&self) -> ~[ModDoc];
-    fn nmods(&self) -> ~[NmodDoc];
-    fn fns(&self) -> ~[FnDoc];
-    fn statics(&self) -> ~[StaticDoc];
-    fn enums(&self) -> ~[EnumDoc];
-    fn traits(&self) -> ~[TraitDoc];
-    fn impls(&self) -> ~[ImplDoc];
-    fn types(&self) -> ~[TyDoc];
-}
-
-impl PageUtils for ~[Page] {
-
-    fn mods(&self) -> ~[ModDoc] {
-        pu!(ModTag)
-    }
-
-    fn nmods(&self) -> ~[NmodDoc] {
-        pu!(NmodTag)
-    }
-
-    fn fns(&self) -> ~[FnDoc] {
-        pu!(FnTag)
-    }
-
-    fn statics(&self) -> ~[StaticDoc] {
-        pu!(StaticTag)
-    }
-
-    fn enums(&self) -> ~[EnumDoc] {
-        pu!(EnumTag)
-    }
-
-    fn traits(&self) -> ~[TraitDoc] {
-        pu!(TraitTag)
-    }
-
-    fn impls(&self) -> ~[ImplDoc] {
-        pu!(ImplTag)
-    }
-
-    fn types(&self) -> ~[TyDoc] {
-        pu!(TyTag)
-    }
-}
-
-pub trait Item {
-    fn item(&self) -> ItemDoc;
-}
-
-impl Item for ItemTag {
-    fn item(&self) -> ItemDoc {
-        match self {
-          &doc::ModTag(ref doc) => doc.item.clone(),
-          &doc::NmodTag(ref doc) => doc.item.clone(),
-          &doc::FnTag(ref doc) => doc.item.clone(),
-          &doc::StaticTag(ref doc) => doc.item.clone(),
-          &doc::EnumTag(ref doc) => doc.item.clone(),
-          &doc::TraitTag(ref doc) => doc.item.clone(),
-          &doc::ImplTag(ref doc) => doc.item.clone(),
-          &doc::TyTag(ref doc) => doc.item.clone(),
-          &doc::StructTag(ref doc) => doc.item.clone(),
-        }
-    }
-}
-
-impl Item for SimpleItemDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for ModDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for NmodDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for EnumDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for TraitDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for ImplDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-impl Item for StructDoc {
-    fn item(&self) -> ItemDoc {
-        self.item.clone()
-    }
-}
-
-pub trait ItemUtils {
-    fn id(&self) -> AstId;
-    /// FIXME #5898: This conflicts with
-    /// syntax::attr::AttrMetaMethods.name; This rustdoc seems to be on
-    /// the way out so I'm making this one look bad rather than the
-    /// new methods in attr.
-    fn name_(&self) -> ~str;
-    fn path(&self) -> ~[~str];
-    fn brief(&self) -> Option<~str>;
-    fn desc(&self) -> Option<~str>;
-    fn sections(&self) -> ~[Section];
-}
-
-impl<A:Item> ItemUtils for A {
-    fn id(&self) -> AstId {
-        self.item().id
-    }
-
-    fn name_(&self) -> ~str {
-        self.item().name.clone()
-    }
-
-    fn path(&self) -> ~[~str] {
-        self.item().path.clone()
-    }
-
-    fn brief(&self) -> Option<~str> {
-        self.item().brief.clone()
-    }
-
-    fn desc(&self) -> Option<~str> {
-        self.item().desc.clone()
-    }
-
-    fn sections(&self) -> ~[Section] {
-        self.item().sections.clone()
-    }
-}
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
new file mode 100644 (file)
index 0000000..67722b1
--- /dev/null
@@ -0,0 +1,168 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module is used to store stuff from Rust's AST in a more convenient
+//! manner (and with prettier names) before cleaning.
+
+use syntax;
+use syntax::codemap::Span;
+use syntax::ast;
+use syntax::ast::{Ident, NodeId};
+
+pub struct Module {
+    name: Option<Ident>,
+    attrs: ~[ast::Attribute],
+    where: Span,
+    structs: ~[Struct],
+    enums: ~[Enum],
+    fns: ~[Function],
+    mods: ~[Module],
+    id: NodeId,
+    typedefs: ~[Typedef],
+    statics: ~[Static],
+    traits: ~[Trait],
+    vis: ast::visibility,
+    impls: ~[Impl],
+    view_items: ~[ast::view_item],
+}
+
+impl Module {
+    pub fn new(name: Option<Ident>) -> Module {
+        Module {
+            name       : name,
+            id: 0,
+            vis: ast::private,
+            where: syntax::codemap::dummy_sp(),
+            attrs      : ~[],
+            structs    : ~[],
+            enums      : ~[],
+            fns        : ~[],
+            mods       : ~[],
+            typedefs   : ~[],
+            statics    : ~[],
+            traits     : ~[],
+            impls      : ~[],
+            view_items : ~[],
+        }
+    }
+}
+
+#[deriving(ToStr, Clone, Encodable, Decodable)]
+pub enum StructType {
+    /// A normal struct
+    Plain,
+    /// A tuple struct
+    Tuple,
+    /// A newtype struct (tuple struct with one element)
+    Newtype,
+    /// A unit struct
+    Unit
+}
+
+pub enum TypeBound {
+    RegionBound,
+    TraitBound(ast::trait_ref)
+}
+
+pub struct Struct {
+    vis: ast::visibility,
+    id: NodeId,
+    struct_type: StructType,
+    name: Ident,
+    generics: ast::Generics,
+    attrs: ~[ast::Attribute],
+    fields: ~[@ast::struct_field],
+    where: Span,
+}
+
+pub struct Enum {
+    vis: ast::visibility,
+    variants: ~[Variant],
+    generics: ast::Generics,
+    attrs: ~[ast::Attribute],
+    id: NodeId,
+    where: Span,
+    name: Ident,
+}
+
+pub struct Variant {
+    name: Ident,
+    attrs: ~[ast::Attribute],
+    kind: ast::variant_kind,
+    id: ast::NodeId,
+    vis: ast::visibility,
+    where: Span,
+}
+
+pub struct Function {
+    decl: ast::fn_decl,
+    attrs: ~[ast::Attribute],
+    id: NodeId,
+    name: Ident,
+    vis: ast::visibility,
+    where: Span,
+    generics: ast::Generics,
+}
+
+pub struct Typedef {
+    ty: ast::Ty,
+    gen: ast::Generics,
+    name: Ident,
+    id: ast::NodeId,
+    attrs: ~[ast::Attribute],
+    where: Span,
+    vis: ast::visibility,
+}
+
+pub struct Static {
+    type_: ast::Ty,
+    mutability: ast::Mutability,
+    expr: @ast::Expr,
+    name: Ident,
+    attrs: ~[ast::Attribute],
+    vis: ast::visibility,
+    id: ast::NodeId,
+    where: Span,
+}
+
+pub struct Trait {
+    name: Ident,
+    methods: ~[ast::trait_method], //should be TraitMethod
+    generics: ast::Generics,
+    parents: ~[ast::trait_ref],
+    attrs: ~[ast::Attribute],
+    id: ast::NodeId,
+    where: Span,
+    vis: ast::visibility,
+}
+
+pub struct Impl {
+    generics: ast::Generics,
+    trait_: Option<ast::trait_ref>,
+    for_: ast::Ty,
+    methods: ~[@ast::method],
+    attrs: ~[ast::Attribute],
+    where: Span,
+    vis: ast::visibility,
+    id: ast::NodeId,
+}
+
+pub fn struct_type_from_def(sd: &ast::struct_def) -> StructType {
+    if sd.ctor_id.is_some() {
+        // We are in a tuple-struct
+        match sd.fields.len() {
+            0 => Unit,
+            1 => Newtype,
+            _ => Tuple
+        }
+    } else {
+        Plain
+    }
+}
diff --git a/src/librustdoc/escape_pass.rs b/src/librustdoc/escape_pass.rs
deleted file mode 100644 (file)
index 2f09e0a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Escapes text sequences
-
-use pass::Pass;
-use text_pass;
-
-pub fn mk_pass() -> Pass {
-    text_pass::mk_pass(~"escape", escape)
-}
-
-fn escape(s: &str) -> ~str {
-    s.replace("\\", "\\\\")
-}
-
-#[test]
-fn should_escape_backslashes() {
-    let s = ~"\\n";
-    let r = escape(s);
-    assert_eq!(r, ~"\\\\n");
-}
diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs
deleted file mode 100644 (file)
index 2ab0530..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Converts the Rust AST to the rustdoc document model
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-
-use syntax::ast;
-use syntax::parse::token::{ident_interner, ident_to_str};
-use syntax::parse::token;
-
-// Hack; rather than thread an interner through everywhere, rely on
-// thread-local data
-// Hack-Becomes-Feature: using thread-local-state everywhere...
-pub fn to_str(id: ast::Ident) -> ~str {
-    /* bad */ ident_to_str(&id).to_owned()
-}
-
-// get rid of this pointless function:
-pub fn interner() -> @ident_interner {
-    return token::get_ident_interner();
-}
-
-pub fn from_srv(
-    srv: astsrv::Srv,
-    default_name: ~str
-) -> doc::Doc {
-
-    //! Use the AST service to create a document tree
-
-    do astsrv::exec(srv) |ctxt| {
-        extract(ctxt.ast, default_name.clone())
-    }
-}
-
-pub fn extract(
-    crate: @ast::Crate,
-    default_name: ~str
-) -> doc::Doc {
-    doc::Doc {
-        pages: ~[
-            doc::CratePage(doc::CrateDoc {
-                topmod: top_moddoc_from_crate(crate, default_name),
-            })
-        ]
-    }
-}
-
-fn top_moddoc_from_crate(
-    crate: @ast::Crate,
-    default_name: ~str
-) -> doc::ModDoc {
-    moddoc_from_mod(mk_itemdoc(ast::CRATE_NODE_ID, default_name),
-                    crate.module.clone())
-}
-
-fn mk_itemdoc(id: ast::NodeId, name: ~str) -> doc::ItemDoc {
-    doc::ItemDoc {
-        id: id,
-        name: name,
-        path: ~[],
-        brief: None,
-        desc: None,
-        sections: ~[],
-        reexport: false
-    }
-}
-
-fn moddoc_from_mod(
-    itemdoc: doc::ItemDoc,
-    module_: ast::_mod
-) -> doc::ModDoc {
-    doc::ModDoc {
-        item: itemdoc,
-        items: do module_.items.iter().filter_map |item| {
-            let ItemDoc = mk_itemdoc(item.id, to_str(item.ident));
-            match item.node.clone() {
-              ast::item_mod(m) => {
-                Some(doc::ModTag(
-                    moddoc_from_mod(ItemDoc, m)
-                ))
-              }
-              ast::item_foreign_mod(nm) => {
-                Some(doc::NmodTag(
-                    nmoddoc_from_mod(ItemDoc, nm)
-                ))
-              }
-              ast::item_fn(*) => {
-                Some(doc::FnTag(
-                    fndoc_from_fn(ItemDoc)
-                ))
-              }
-              ast::item_static(*) => {
-                Some(doc::StaticTag(
-                    staticdoc_from_static(ItemDoc)
-                ))
-              }
-              ast::item_enum(enum_definition, _) => {
-                Some(doc::EnumTag(
-                    enumdoc_from_enum(ItemDoc, enum_definition.variants.clone())
-                ))
-              }
-              ast::item_trait(_, _, methods) => {
-                Some(doc::TraitTag(
-                    traitdoc_from_trait(ItemDoc, methods)
-                ))
-              }
-              ast::item_impl(_, _, _, methods) => {
-                Some(doc::ImplTag(
-                    impldoc_from_impl(ItemDoc, methods)
-                ))
-              }
-              ast::item_ty(_, _) => {
-                Some(doc::TyTag(
-                    tydoc_from_ty(ItemDoc)
-                ))
-              }
-              ast::item_struct(def, _) => {
-                Some(doc::StructTag(
-                    structdoc_from_struct(ItemDoc, def)
-                ))
-              }
-              _ => None
-            }
-        }.collect(),
-        index: None
-    }
-}
-
-fn nmoddoc_from_mod(
-    itemdoc: doc::ItemDoc,
-    module_: ast::foreign_mod
-) -> doc::NmodDoc {
-    let mut fns = ~[];
-    for item in module_.items.iter() {
-        let ItemDoc = mk_itemdoc(item.id, to_str(item.ident));
-        match item.node {
-          ast::foreign_item_fn(*) => {
-            fns.push(fndoc_from_fn(ItemDoc));
-          }
-          ast::foreign_item_static(*) => {} // XXX: Not implemented.
-        }
-    }
-    doc::NmodDoc {
-        item: itemdoc,
-        fns: fns,
-        index: None
-    }
-}
-
-fn fndoc_from_fn(itemdoc: doc::ItemDoc) -> doc::FnDoc {
-    doc::SimpleItemDoc {
-        item: itemdoc,
-        sig: None
-    }
-}
-
-fn staticdoc_from_static(itemdoc: doc::ItemDoc) -> doc::StaticDoc {
-    doc::SimpleItemDoc {
-        item: itemdoc,
-        sig: None
-    }
-}
-
-fn enumdoc_from_enum(
-    itemdoc: doc::ItemDoc,
-    variants: ~[ast::variant]
-) -> doc::EnumDoc {
-    doc::EnumDoc {
-        item: itemdoc,
-        variants: variantdocs_from_variants(variants)
-    }
-}
-
-fn variantdocs_from_variants(
-    variants: ~[ast::variant]
-) -> ~[doc::VariantDoc] {
-    variants.iter().map(variantdoc_from_variant).collect()
-}
-
-fn variantdoc_from_variant(variant: &ast::variant) -> doc::VariantDoc {
-    doc::VariantDoc {
-        name: to_str(variant.node.name),
-        desc: None,
-        sig: None
-    }
-}
-
-fn traitdoc_from_trait(
-    itemdoc: doc::ItemDoc,
-    methods: ~[ast::trait_method]
-) -> doc::TraitDoc {
-    doc::TraitDoc {
-        item: itemdoc,
-        methods: do methods.iter().map |method| {
-            match (*method).clone() {
-              ast::required(ty_m) => {
-                doc::MethodDoc {
-                    name: to_str(ty_m.ident),
-                    brief: None,
-                    desc: None,
-                    sections: ~[],
-                    sig: None,
-                    implementation: doc::Required,
-                }
-              }
-              ast::provided(m) => {
-                doc::MethodDoc {
-                    name: to_str(m.ident),
-                    brief: None,
-                    desc: None,
-                    sections: ~[],
-                    sig: None,
-                    implementation: doc::Provided,
-                }
-              }
-            }
-        }.collect()
-    }
-}
-
-fn impldoc_from_impl(
-    itemdoc: doc::ItemDoc,
-    methods: ~[@ast::method]
-) -> doc::ImplDoc {
-    doc::ImplDoc {
-        item: itemdoc,
-        bounds_str: None,
-        trait_types: ~[],
-        self_ty: None,
-        methods: do methods.iter().map |method| {
-            doc::MethodDoc {
-                name: to_str(method.ident),
-                brief: None,
-                desc: None,
-                sections: ~[],
-                sig: None,
-                implementation: doc::Provided,
-            }
-        }.collect()
-    }
-}
-
-fn tydoc_from_ty(
-    itemdoc: doc::ItemDoc
-) -> doc::TyDoc {
-    doc::SimpleItemDoc {
-        item: itemdoc,
-        sig: None
-    }
-}
-
-fn structdoc_from_struct(
-    itemdoc: doc::ItemDoc,
-    struct_def: @ast::struct_def
-) -> doc::StructDoc {
-    doc::StructDoc {
-        item: itemdoc,
-        fields: do struct_def.fields.map |field| {
-            match field.node.kind {
-                ast::named_field(ident, _) => to_str(ident),
-                ast::unnamed_field => ~"(unnamed)",
-            }
-        },
-        sig: None
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use astsrv;
-    use doc;
-    use extract::{extract, from_srv};
-    use parse;
-
-    fn mk_doc(source: @str) -> doc::Doc {
-        let ast = parse::from_str(source);
-        debug!("ast=%?", ast);
-        extract(ast, ~"")
-    }
-
-    #[test]
-    fn extract_empty_crate() {
-        let doc = mk_doc(@"");
-        assert!(doc.cratemod().mods().is_empty());
-        assert!(doc.cratemod().fns().is_empty());
-    }
-
-    #[test]
-    fn extract_mods() {
-        let doc = mk_doc(@"mod a { mod b { } mod c { } }");
-        assert!(doc.cratemod().mods()[0].name_() == ~"a");
-        assert!(doc.cratemod().mods()[0].mods()[0].name_() == ~"b");
-        assert!(doc.cratemod().mods()[0].mods()[1].name_() == ~"c");
-    }
-
-    #[test]
-    fn extract_fns_from_foreign_mods() {
-        let doc = mk_doc(@"extern { fn a(); }");
-        assert!(doc.cratemod().nmods()[0].fns[0].name_() == ~"a");
-    }
-
-    #[test]
-    fn extract_mods_deep() {
-        let doc = mk_doc(@"mod a { mod b { mod c { } } }");
-        assert!(doc.cratemod().mods()[0].mods()[0].mods()[0].name_() ==
-            ~"c");
-    }
-
-    #[test]
-    fn extract_should_set_mod_ast_id() {
-        let doc = mk_doc(@"mod a { }");
-        assert!(doc.cratemod().mods()[0].id() != 0);
-    }
-
-    #[test]
-    fn extract_fns() {
-        let doc = mk_doc(
-            @"fn a() { } \
-              mod b { fn c() {
-             } }");
-        assert!(doc.cratemod().fns()[0].name_() == ~"a");
-        assert!(doc.cratemod().mods()[0].fns()[0].name_() == ~"c");
-    }
-
-    #[test]
-    fn extract_should_set_fn_ast_id() {
-        let doc = mk_doc(@"fn a() { }");
-        assert!(doc.cratemod().fns()[0].id() != 0);
-    }
-
-    #[test]
-    fn extract_should_use_default_crate_name() {
-        let source = @"";
-        let ast = parse::from_str(source);
-        let doc = extract(ast, ~"burp");
-        assert!(doc.cratemod().name_() == ~"burp");
-    }
-
-    #[test]
-    fn extract_from_seq_srv() {
-        let source = ~"";
-        do astsrv::from_str(source) |srv| {
-            let doc = from_srv(srv, ~"name");
-            assert!(doc.cratemod().name_() == ~"name");
-        }
-    }
-
-    #[test]
-    fn should_extract_static_name_and_id() {
-        let doc = mk_doc(@"static a: int = 0;");
-        assert!(doc.cratemod().statics()[0].id() != 0);
-        assert!(doc.cratemod().statics()[0].name_() == ~"a");
-    }
-
-    #[test]
-    fn should_extract_enums() {
-        let doc = mk_doc(@"enum e { v }");
-        assert!(doc.cratemod().enums()[0].id() != 0);
-        assert!(doc.cratemod().enums()[0].name_() == ~"e");
-    }
-
-    #[test]
-    fn should_extract_enum_variants() {
-        let doc = mk_doc(@"enum e { v }");
-        assert!(doc.cratemod().enums()[0].variants[0].name == ~"v");
-    }
-
-    #[test]
-    fn should_extract_traits() {
-        let doc = mk_doc(@"trait i { fn f(); }");
-        assert!(doc.cratemod().traits()[0].name_() == ~"i");
-    }
-
-    #[test]
-    fn should_extract_trait_methods() {
-        let doc = mk_doc(@"trait i { fn f(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].name == ~"f");
-    }
-
-    #[test]
-    fn should_extract_impl_methods() {
-        let doc = mk_doc(@"impl int { fn f() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].name == ~"f");
-    }
-
-    #[test]
-    fn should_extract_tys() {
-        let doc = mk_doc(@"type a = int;");
-        assert!(doc.cratemod().types()[0].name_() == ~"a");
-    }
-
-    #[test]
-    fn should_extract_structs() {
-        let doc = mk_doc(@"struct Foo { field: () }");
-        assert!(doc.cratemod().structs()[0].name_() == ~"Foo");
-    }
-
-    #[test]
-    fn should_extract_struct_fields() {
-        let doc = mk_doc(@"struct Foo { field: () }");
-        assert!(doc.cratemod().structs()[0].fields[0] == ~"field");
-    }
-}
index 3e74916228f00f046c034e73b94dbeabbea741cb..ae74f4e37c3c351744386a7ecdc3dd536f98f1f2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-use doc;
-#[cfg(test)] use extract;
-#[cfg(test)] use parse;
-
-pub struct Fold<T> {
-    ctxt: T,
-    fold_doc: FoldDoc<T>,
-    fold_crate: FoldCrate<T>,
-    fold_item: FoldItem<T>,
-    fold_mod: FoldMod<T>,
-    fold_nmod: FoldNmod<T>,
-    fold_fn: FoldFn<T>,
-    fold_static: FoldStatic<T>,
-    fold_enum: FoldEnum<T>,
-    fold_trait: FoldTrait<T>,
-    fold_impl: FoldImpl<T>,
-    fold_type: FoldType<T>,
-    fold_struct: FoldStruct<T>
-}
-
-impl<T:Clone> Clone for Fold<T> {
-    fn clone(&self) -> Fold<T> {
-        Fold {
-            ctxt: self.ctxt.clone(),
-            fold_doc: self.fold_doc,
-            fold_crate: self.fold_crate,
-            fold_item: self.fold_item,
-            fold_mod: self.fold_mod,
-            fold_nmod: self.fold_nmod,
-            fold_fn: self.fold_fn,
-            fold_static: self.fold_static,
-            fold_enum: self.fold_enum,
-            fold_trait: self.fold_trait,
-            fold_impl: self.fold_impl,
-            fold_type: self.fold_type,
-            fold_struct: self.fold_struct
-        }
-    }
-}
-
-type FoldDoc<T> = @fn(fold: &Fold<T>, doc: doc::Doc) -> doc::Doc;
-type FoldCrate<T> = @fn(fold: &Fold<T>, doc: doc::CrateDoc) -> doc::CrateDoc;
-type FoldItem<T> = @fn(fold: &Fold<T>, doc: doc::ItemDoc) -> doc::ItemDoc;
-type FoldMod<T> = @fn(fold: &Fold<T>, doc: doc::ModDoc) -> doc::ModDoc;
-type FoldNmod<T> = @fn(fold: &Fold<T>, doc: doc::NmodDoc) -> doc::NmodDoc;
-type FoldFn<T> = @fn(fold: &Fold<T>, doc: doc::FnDoc) -> doc::FnDoc;
-type FoldStatic<T> = @fn(fold: &Fold<T>, doc: doc::StaticDoc) -> doc::StaticDoc;
-type FoldEnum<T> = @fn(fold: &Fold<T>, doc: doc::EnumDoc) -> doc::EnumDoc;
-type FoldTrait<T> = @fn(fold: &Fold<T>, doc: doc::TraitDoc) -> doc::TraitDoc;
-type FoldImpl<T> = @fn(fold: &Fold<T>, doc: doc::ImplDoc) -> doc::ImplDoc;
-type FoldType<T> = @fn(fold: &Fold<T>, doc: doc::TyDoc) -> doc::TyDoc;
-type FoldStruct<T> = @fn(fold: &Fold<T>,
-                         doc: doc::StructDoc) -> doc::StructDoc;
-
-// This exists because fn types don't infer correctly as record
-// initializers, but they do as function arguments
-fn mk_fold<T>(
-    ctxt: T,
-    fold_doc: FoldDoc<T>,
-    fold_crate: FoldCrate<T>,
-    fold_item: FoldItem<T>,
-    fold_mod: FoldMod<T>,
-    fold_nmod: FoldNmod<T>,
-    fold_fn: FoldFn<T>,
-    fold_static: FoldStatic<T>,
-    fold_enum: FoldEnum<T>,
-    fold_trait: FoldTrait<T>,
-    fold_impl: FoldImpl<T>,
-    fold_type: FoldType<T>,
-    fold_struct: FoldStruct<T>
-) -> Fold<T> {
-    Fold {
-        ctxt: ctxt,
-        fold_doc: fold_doc,
-        fold_crate: fold_crate,
-        fold_item: fold_item,
-        fold_mod: fold_mod,
-        fold_nmod: fold_nmod,
-        fold_fn: fold_fn,
-        fold_static: fold_static,
-        fold_enum: fold_enum,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        fold_type: fold_type,
-        fold_struct: fold_struct
-    }
-}
-
-pub fn default_any_fold<T:Clone>(ctxt: T) -> Fold<T> {
-    mk_fold(
-        ctxt,
-        |f, d| default_seq_fold_doc(f, d),
-        |f, d| default_seq_fold_crate(f, d),
-        |f, d| default_seq_fold_item(f, d),
-        |f, d| default_any_fold_mod(f, d),
-        |f, d| default_any_fold_nmod(f, d),
-        |f, d| default_seq_fold_fn(f, d),
-        |f, d| default_seq_fold_static(f, d),
-        |f, d| default_seq_fold_enum(f, d),
-        |f, d| default_seq_fold_trait(f, d),
-        |f, d| default_seq_fold_impl(f, d),
-        |f, d| default_seq_fold_type(f, d),
-        |f, d| default_seq_fold_struct(f, d)
-    )
-}
-
-pub fn default_seq_fold<T:Clone>(ctxt: T) -> Fold<T> {
-    mk_fold(
-        ctxt,
-        |f, d| default_seq_fold_doc(f, d),
-        |f, d| default_seq_fold_crate(f, d),
-        |f, d| default_seq_fold_item(f, d),
-        |f, d| default_seq_fold_mod(f, d),
-        |f, d| default_seq_fold_nmod(f, d),
-        |f, d| default_seq_fold_fn(f, d),
-        |f, d| default_seq_fold_static(f, d),
-        |f, d| default_seq_fold_enum(f, d),
-        |f, d| default_seq_fold_trait(f, d),
-        |f, d| default_seq_fold_impl(f, d),
-        |f, d| default_seq_fold_type(f, d),
-        |f, d| default_seq_fold_struct(f, d)
-    )
-}
-
-pub fn default_par_fold<T:Clone>(ctxt: T) -> Fold<T> {
-    mk_fold(
-        ctxt,
-        |f, d| default_seq_fold_doc(f, d),
-        |f, d| default_seq_fold_crate(f, d),
-        |f, d| default_seq_fold_item(f, d),
-        |f, d| default_par_fold_mod(f, d),
-        |f, d| default_par_fold_nmod(f, d),
-        |f, d| default_seq_fold_fn(f, d),
-        |f, d| default_seq_fold_static(f, d),
-        |f, d| default_seq_fold_enum(f, d),
-        |f, d| default_seq_fold_trait(f, d),
-        |f, d| default_seq_fold_impl(f, d),
-        |f, d| default_seq_fold_type(f, d),
-        |f, d| default_seq_fold_struct(f, d)
-    )
-}
-
-pub fn default_seq_fold_doc<T>(fold: &Fold<T>, doc: doc::Doc) -> doc::Doc {
-    doc::Doc {
-        pages: do doc.pages.iter().map |page| {
-            match (*page).clone() {
-              doc::CratePage(doc) => {
-                doc::CratePage((fold.fold_crate)(fold, doc))
-              }
-              doc::ItemPage(doc) => {
-                doc::ItemPage(fold_ItemTag(fold, doc))
-              }
-            }
-        }.collect(),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_crate<T>(
-    fold: &Fold<T>,
-    doc: doc::CrateDoc
-) -> doc::CrateDoc {
-    doc::CrateDoc {
-        topmod: (fold.fold_mod)(fold, doc.topmod.clone())
-    }
-}
-
-pub fn default_seq_fold_item<T>(
-    _fold: &Fold<T>,
-    doc: doc::ItemDoc
-) -> doc::ItemDoc {
-    doc
-}
-
-pub fn default_any_fold_mod<T:Clone>(
-    fold: &Fold<T>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    doc::ModDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        items: doc.items.iter().map(|ItemTag| {
-            fold_ItemTag(fold, (*ItemTag).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_mod<T>(
-    fold: &Fold<T>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    doc::ModDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        items: doc.items.iter().map(|ItemTag| {
-            fold_ItemTag(fold, (*ItemTag).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn default_par_fold_mod<T:Clone>(
-    fold: &Fold<T>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    doc::ModDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        items: doc.items.iter().map(|ItemTag| {
-            fold_ItemTag(fold, (*ItemTag).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn default_any_fold_nmod<T:Clone>(
-    fold: &Fold<T>,
-    doc: doc::NmodDoc
-) -> doc::NmodDoc {
-    doc::NmodDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        fns: doc.fns.iter().map(|FnDoc| {
-            (fold.fold_fn)(fold, (*FnDoc).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_nmod<T>(
-    fold: &Fold<T>,
-    doc: doc::NmodDoc
-) -> doc::NmodDoc {
-    doc::NmodDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        fns: doc.fns.iter().map(|FnDoc| {
-            (fold.fold_fn)(fold, (*FnDoc).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn default_par_fold_nmod<T:Clone>(
-    fold: &Fold<T>,
-    doc: doc::NmodDoc
-) -> doc::NmodDoc {
-    doc::NmodDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        fns: doc.fns.iter().map(|FnDoc| {
-            (fold.fold_fn)(fold, (*FnDoc).clone())
-        }).collect(),
-        .. doc
-    }
-}
-
-pub fn fold_ItemTag<T>(fold: &Fold<T>, doc: doc::ItemTag) -> doc::ItemTag {
-    match doc {
-      doc::ModTag(ModDoc) => {
-        doc::ModTag((fold.fold_mod)(fold, ModDoc))
-      }
-      doc::NmodTag(nModDoc) => {
-        doc::NmodTag((fold.fold_nmod)(fold, nModDoc))
-      }
-      doc::FnTag(FnDoc) => {
-        doc::FnTag((fold.fold_fn)(fold, FnDoc))
-      }
-      doc::StaticTag(StaticDoc) => {
-        doc::StaticTag((fold.fold_static)(fold, StaticDoc))
-      }
-      doc::EnumTag(EnumDoc) => {
-        doc::EnumTag((fold.fold_enum)(fold, EnumDoc))
-      }
-      doc::TraitTag(TraitDoc) => {
-        doc::TraitTag((fold.fold_trait)(fold, TraitDoc))
-      }
-      doc::ImplTag(ImplDoc) => {
-        doc::ImplTag((fold.fold_impl)(fold, ImplDoc))
-      }
-      doc::TyTag(TyDoc) => {
-        doc::TyTag((fold.fold_type)(fold, TyDoc))
-      }
-      doc::StructTag(StructDoc) => {
-        doc::StructTag((fold.fold_struct)(fold, StructDoc))
-      }
-    }
-}
-
-pub fn default_seq_fold_fn<T>(
-    fold: &Fold<T>,
-    doc: doc::FnDoc
-) -> doc::FnDoc {
-    doc::SimpleItemDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_static<T>(
-    fold: &Fold<T>,
-    doc: doc::StaticDoc
-) -> doc::StaticDoc {
-    doc::SimpleItemDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_enum<T>(
-    fold: &Fold<T>,
-    doc: doc::EnumDoc
-) -> doc::EnumDoc {
-    doc::EnumDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_trait<T>(
-    fold: &Fold<T>,
-    doc: doc::TraitDoc
-) -> doc::TraitDoc {
-    doc::TraitDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_impl<T>(
-    fold: &Fold<T>,
-    doc: doc::ImplDoc
-) -> doc::ImplDoc {
-    doc::ImplDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_type<T>(
-    fold: &Fold<T>,
-    doc: doc::TyDoc
-) -> doc::TyDoc {
-    doc::SimpleItemDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-pub fn default_seq_fold_struct<T>(
-    fold: &Fold<T>,
-    doc: doc::StructDoc
-) -> doc::StructDoc {
-    doc::StructDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
+use std;
+use clean::*;
+use std::iter::Extendable;
+
+pub trait DocFolder {
+    fn fold_item(&mut self, item: Item) -> Option<Item> {
+        self.fold_item_recur(item)
+    }
+
+    /// don't override!
+    fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
+        use std::util::swap;
+        let Item { attrs, name, source, visibility, id, inner } = item;
+        let inner = inner;
+        let c = |x| self.fold_item(x);
+        let inner = match inner {
+            StructItem(i) => {
+                let mut i = i;
+                let mut foo = ~[]; swap(&mut foo, &mut i.fields);
+                i.fields.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
+                StructItem(i)
+            },
+            ModuleItem(i) => {
+                ModuleItem(self.fold_mod(i))
+            },
+            EnumItem(i) => {
+                let mut i = i;
+                let mut foo = ~[]; swap(&mut foo, &mut i.variants);
+                i.variants.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
+                EnumItem(i)
+            },
+            TraitItem(i) => {
+                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod) -> Option<TraitMethod> {
+                    match trm {
+                        Required(it) => {
+                            match this.fold_item(it) {
+                                Some(x) => return Some(Required(x)),
+                                None => return None,
+                            }
+                        },
+                        Provided(it) => {
+                            match this.fold_item(it) {
+                                Some(x) => return Some(Provided(x)),
+                                None => return None,
+                            }
+                        },
+                    }
+                }
+                let mut i = i;
+                let mut foo = ~[]; swap(&mut foo, &mut i.methods);
+                i.methods.extend(&mut foo.move_iter().filter_map(|x| vtrm(self, x)));
+                TraitItem(i)
+            },
+            ImplItem(i) => {
+                let mut i = i;
+                let mut foo = ~[]; swap(&mut foo, &mut i.methods);
+                i.methods.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
+                ImplItem(i)
+            },
+            VariantItem(i) => {
+                let i2 = i.clone(); // this clone is small
+                match i.kind {
+                    StructVariant(j) => {
+                        let mut j = j;
+                        let mut foo = ~[]; swap(&mut foo, &mut j.fields);
+                        j.fields.extend(&mut foo.move_iter().filter_map(c));
+                        VariantItem(Variant {kind: StructVariant(j), ..i2})
+                    },
+                    _ => VariantItem(i2)
+                }
+            },
+            x => x
+        };
+
+        Some(Item { attrs: attrs, name: name, source: source, inner: inner,
+                    visibility: visibility, id: id })
+    }
+
+    fn fold_mod(&mut self, m: Module) -> Module {
+        Module { items: m.items.move_iter().filter_map(|i| self.fold_item(i)).collect() }
+    }
+
+    fn fold_crate(&mut self, mut c: Crate) -> Crate {
+        c.module = match std::util::replace(&mut c.module, None) {
+            Some(module) => self.fold_item(module), None => None
+        };
+        return c;
     }
 }
-
-#[test]
-fn default_fold_should_produce_same_doc() {
-    let source = @"mod a { fn b() { } mod c { fn d() { } } }";
-    let ast = parse::from_str(source);
-    let doc = extract::extract(ast, ~"");
-    let fld = default_seq_fold(());
-    let folded = (fld.fold_doc)(&fld, doc.clone());
-    assert_eq!(doc, folded);
-}
-
-#[test]
-fn default_fold_should_produce_same_statics() {
-    let source = @"static a: int = 0;";
-    let ast = parse::from_str(source);
-    let doc = extract::extract(ast, ~"");
-    let fld = default_seq_fold(());
-    let folded = (fld.fold_doc)(&fld, doc.clone());
-    assert_eq!(doc, folded);
-}
-
-#[test]
-fn default_fold_should_produce_same_enums() {
-    let source = @"enum a { b }";
-    let ast = parse::from_str(source);
-    let doc = extract::extract(ast, ~"");
-    let fld = default_seq_fold(());
-    let folded = (fld.fold_doc)(&fld, doc.clone());
-    assert_eq!(doc, folded);
-}
-
-#[test]
-fn default_parallel_fold_should_produce_same_doc() {
-    let source = @"mod a { fn b() { } mod c { fn d() { } } }";
-    let ast = parse::from_str(source);
-    let doc = extract::extract(ast, ~"");
-    let fld = default_par_fold(());
-    let folded = (fld.fold_doc)(&fld, doc.clone());
-    assert_eq!(doc, folded);
-}
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
new file mode 100644 (file)
index 0000000..4d0f692
--- /dev/null
@@ -0,0 +1,364 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+use std::local_data;
+use std::rt::io;
+
+use syntax::ast;
+
+use clean;
+use html::render::{cache_key, current_location_key};
+
+pub struct VisSpace(Option<ast::visibility>);
+pub struct Method<'self>(&'self clean::SelfTy, &'self clean::FnDecl);
+
+impl fmt::Default for clean::Generics {
+    fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) {
+        if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return }
+        f.buf.write("&lt;".as_bytes());
+
+        for (i, life) in g.lifetimes.iter().enumerate() {
+            if i > 0 { f.buf.write(", ".as_bytes()); }
+            write!(f.buf, "{}", *life);
+        }
+
+        if g.type_params.len() > 0 {
+            if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); }
+
+            for (i, tp) in g.type_params.iter().enumerate() {
+                if i > 0 { f.buf.write(", ".as_bytes()) }
+                f.buf.write(tp.name.as_bytes());
+
+                if tp.bounds.len() > 0 {
+                    f.buf.write(": ".as_bytes());
+                    for (i, bound) in tp.bounds.iter().enumerate() {
+                        if i > 0 { f.buf.write(" + ".as_bytes()); }
+                        write!(f.buf, "{}", *bound);
+                    }
+                }
+            }
+        }
+        f.buf.write("&gt;".as_bytes());
+    }
+}
+
+impl fmt::Default for clean::Lifetime {
+    fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) {
+        f.buf.write("'".as_bytes());
+        f.buf.write(l.as_bytes());
+    }
+}
+
+impl fmt::Default for clean::TyParamBound {
+    fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) {
+        match *bound {
+            clean::RegionBound => {
+                f.buf.write("'static".as_bytes())
+            }
+            clean::TraitBound(ref ty) => {
+                write!(f.buf, "{}", *ty);
+            }
+        }
+    }
+}
+
+impl fmt::Default for clean::Path {
+    fn fmt(path: &clean::Path, f: &mut fmt::Formatter) {
+        if path.global { f.buf.write("::".as_bytes()) }
+        for (i, seg) in path.segments.iter().enumerate() {
+            if i > 0 { f.buf.write("::".as_bytes()) }
+            f.buf.write(seg.name.as_bytes());
+
+            if seg.lifetime.is_some() || seg.types.len() > 0 {
+                f.buf.write("&lt;".as_bytes());
+                match seg.lifetime {
+                    Some(ref lifetime) => write!(f.buf, "{}", *lifetime),
+                    None => {}
+                }
+                for (i, ty) in seg.types.iter().enumerate() {
+                    if i > 0 || seg.lifetime.is_some() {
+                        f.buf.write(", ".as_bytes());
+                    }
+                    write!(f.buf, "{}", *ty);
+                }
+                f.buf.write("&gt;".as_bytes());
+            }
+        }
+    }
+}
+
+fn resolved_path(w: &mut io::Writer, id: ast::NodeId, path: &clean::Path) {
+    // The generics will get written to both the title and link
+    let mut generics = ~"";
+    let last = path.segments.last();
+    if last.lifetime.is_some() || last.types.len() > 0 {
+        generics.push_str("&lt;");
+        match last.lifetime {
+            Some(ref lifetime) => generics.push_str(format!("{}", *lifetime)),
+            None => {}
+        }
+        for (i, ty) in last.types.iter().enumerate() {
+            if i > 0 || last.lifetime.is_some() {
+                generics.push_str(", ");
+            }
+            generics.push_str(format!("{}", *ty));
+        }
+        generics.push_str("&gt;");
+    }
+
+    // Did someone say rightward-drift?
+    do local_data::get(current_location_key) |loc| {
+        let loc = loc.unwrap();
+        do local_data::get(cache_key) |cache| {
+            do cache.unwrap().read |cache| {
+                match cache.paths.find(&id) {
+                    // This is a documented path, link to it!
+                    Some(&(ref fqp, shortty)) => {
+                        let fqn = fqp.connect("::");
+                        let mut same = 0;
+                        for (a, b) in loc.iter().zip(fqp.iter()) {
+                            if *a == *b {
+                                same += 1;
+                            } else {
+                                break;
+                            }
+                        }
+
+                        let mut url = ~"";
+                        for _ in range(same, loc.len()) {
+                            url.push_str("../");
+                        }
+                        if same == fqp.len() {
+                            url.push_str(shortty);
+                            url.push_str(".");
+                            url.push_str(*fqp.last());
+                            url.push_str(".html");
+                        } else {
+                            let remaining = fqp.slice_from(same);
+                            let to_link = remaining.slice_to(remaining.len() - 1);
+                            for component in to_link.iter() {
+                                url.push_str(*component);
+                                url.push_str("/");
+                            }
+                            url.push_str(shortty);
+                            url.push_str(".");
+                            url.push_str(*remaining.last());
+                            url.push_str(".html");
+                        }
+
+                        write!(w, "<a class='{}' href='{}' title='{}'>{}</a>{}",
+                               shortty, url, fqn, last.name, generics);
+                    }
+                    None => {
+                        write!(w, "{}{}", last.name, generics);
+                    }
+                };
+            }
+        }
+    }
+}
+
+impl fmt::Default for clean::Type {
+    fn fmt(g: &clean::Type, f: &mut fmt::Formatter) {
+        match *g {
+            clean::TyParamBinder(id) | clean::Generic(id) => {
+                do local_data::get(cache_key) |cache| {
+                    do cache.unwrap().read |m| {
+                        f.buf.write(m.typarams.get(&id).as_bytes());
+                    }
+                }
+            }
+            clean::Unresolved(*) => unreachable!(),
+            clean::ResolvedPath{id, typarams: ref typarams, path: ref path} => {
+                resolved_path(f.buf, id, path);
+                match *typarams {
+                    Some(ref params) => {
+                        f.buf.write("&lt;".as_bytes());
+                        for (i, param) in params.iter().enumerate() {
+                            if i > 0 { f.buf.write(", ".as_bytes()) }
+                            write!(f.buf, "{}", *param);
+                        }
+                        f.buf.write("&gt;".as_bytes());
+                    }
+                    None => {}
+                }
+            }
+            // XXX: this should be a link
+            clean::External(ref a, _) => {
+                write!(f.buf, "{}", *a);
+            }
+            clean::Self(*) => f.buf.write("Self".as_bytes()),
+            clean::Primitive(prim) => {
+                let s = match prim {
+                    ast::ty_int(ast::ty_i) => "int",
+                    ast::ty_int(ast::ty_i8) => "i8",
+                    ast::ty_int(ast::ty_i16) => "i16",
+                    ast::ty_int(ast::ty_i32) => "i32",
+                    ast::ty_int(ast::ty_i64) => "i64",
+                    ast::ty_uint(ast::ty_u) => "uint",
+                    ast::ty_uint(ast::ty_u8) => "u8",
+                    ast::ty_uint(ast::ty_u16) => "u16",
+                    ast::ty_uint(ast::ty_u32) => "u32",
+                    ast::ty_uint(ast::ty_u64) => "u64",
+                    ast::ty_float(ast::ty_f) => "float",
+                    ast::ty_float(ast::ty_f32) => "f32",
+                    ast::ty_float(ast::ty_f64) => "f64",
+                    ast::ty_str => "str",
+                    ast::ty_bool => "bool",
+                    ast::ty_char => "char",
+                };
+                f.buf.write(s.as_bytes());
+            }
+            clean::Closure(ref decl) => {
+                f.buf.write(match decl.sigil {
+                    ast::BorrowedSigil => "&amp;",
+                    ast::ManagedSigil => "@",
+                    ast::OwnedSigil => "~",
+                }.as_bytes());
+                match decl.region {
+                    Some(ref region) => write!(f.buf, "{} ", *region),
+                    None => {}
+                }
+                write!(f.buf, "{}{}fn{}",
+                       match decl.purity {
+                           ast::unsafe_fn => "unsafe ",
+                           ast::extern_fn => "extern ",
+                           ast::impure_fn => ""
+                       },
+                       match decl.onceness {
+                           ast::Once => "once ",
+                           ast::Many => "",
+                       },
+                       decl.decl);
+                // XXX: where are bounds and lifetimes printed?!
+            }
+            clean::BareFunction(ref decl) => {
+                write!(f.buf, "{}{}fn{}{}",
+                       match decl.purity {
+                           ast::unsafe_fn => "unsafe ",
+                           ast::extern_fn => "extern ",
+                           ast::impure_fn => ""
+                       },
+                       match decl.abi {
+                           ~"" | ~"\"Rust\"" => ~"",
+                           ref s => " " + *s + " ",
+                       },
+                       decl.generics,
+                       decl.decl);
+            }
+            clean::Tuple(ref typs) => {
+                f.buf.write("(".as_bytes());
+                for (i, typ) in typs.iter().enumerate() {
+                    if i > 0 { f.buf.write(", ".as_bytes()) }
+                    write!(f.buf, "{}", *typ);
+                }
+                f.buf.write(")".as_bytes());
+            }
+            clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
+            clean::FixedVector(ref t, ref s) => {
+                write!(f.buf, "[{}, ..{}]", **t, *s);
+            }
+            clean::String => f.buf.write("str".as_bytes()),
+            clean::Bool => f.buf.write("bool".as_bytes()),
+            clean::Unit => f.buf.write("()".as_bytes()),
+            clean::Bottom => f.buf.write("!".as_bytes()),
+            clean::Unique(ref t) => write!(f.buf, "~{}", **t),
+            clean::Managed(m, ref t) => {
+                write!(f.buf, "@{}{}",
+                       match m {
+                           clean::Mutable => "mut ",
+                           clean::Immutable => "",
+                       }, **t)
+            }
+            clean::RawPointer(m, ref t) => {
+                write!(f.buf, "*{}{}",
+                       match m {
+                           clean::Mutable => "mut ",
+                           clean::Immutable => "",
+                       }, **t)
+            }
+            clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
+                let lt = match *l { Some(ref l) => format!("{} ", *l), _ => ~"" };
+                write!(f.buf, "&amp;{}{}{}",
+                       lt,
+                       match mutability {
+                           clean::Mutable => "mut ",
+                           clean::Immutable => "",
+                       },
+                       **ty);
+            }
+        }
+    }
+}
+
+impl fmt::Default for clean::FnDecl {
+    fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) {
+        let mut args = ~"";
+        for (i, input) in d.inputs.iter().enumerate() {
+            if i > 0 { args.push_str(", "); }
+            if input.name.len() > 0 {
+                args.push_str(format!("{}: ", input.name));
+            }
+            args.push_str(format!("{}", input.type_));
+        }
+        write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
+               args = args,
+               arrow = match d.output { clean::Unit => "no", _ => "yes" },
+               ret = d.output);
+    }
+}
+
+impl<'self> fmt::Default for Method<'self> {
+    fn fmt(m: &Method<'self>, f: &mut fmt::Formatter) {
+        let Method(selfty, d) = *m;
+        let mut args = ~"";
+        match *selfty {
+            clean::SelfStatic => {},
+            clean::SelfValue => args.push_str("self"),
+            clean::SelfOwned => args.push_str("~self"),
+            clean::SelfManaged(clean::Mutable) => args.push_str("@mut self"),
+            clean::SelfManaged(clean::Immutable) => args.push_str("@self"),
+            clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
+                args.push_str(format!("&amp;{} self", *lt));
+            }
+            clean::SelfBorrowed(Some(ref lt), clean::Mutable) => {
+                args.push_str(format!("&amp;{} mut self", *lt));
+            }
+            clean::SelfBorrowed(None, clean::Mutable) => {
+                args.push_str("&amp;mut self");
+            }
+            clean::SelfBorrowed(None, clean::Immutable) => {
+                args.push_str("&amp;self");
+            }
+        }
+        for (i, input) in d.inputs.iter().enumerate() {
+            if i > 0 || args.len() > 0 { args.push_str(", "); }
+            if input.name.len() > 0 {
+                args.push_str(format!("{}: ", input.name));
+            }
+            args.push_str(format!("{}", input.type_));
+        }
+        write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
+               args = args,
+               arrow = match d.output { clean::Unit => "no", _ => "yes" },
+               ret = d.output);
+    }
+}
+
+impl fmt::Default for VisSpace {
+    fn fmt(v: &VisSpace, f: &mut fmt::Formatter) {
+        match **v {
+            Some(ast::public) => { write!(f.buf, "pub "); }
+            Some(ast::private) => { write!(f.buf, "priv "); }
+            Some(ast::inherited) | None => {}
+        }
+    }
+}
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
new file mode 100644 (file)
index 0000000..fcf1377
--- /dev/null
@@ -0,0 +1,130 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+use std::rt::io;
+
+#[deriving(Clone)]
+pub struct Layout {
+    logo: ~str,
+    favicon: ~str,
+    crate: ~str,
+}
+
+pub struct Page<'self> {
+    title: &'self str,
+    ty: &'self str,
+    root_path: &'self str,
+}
+
+pub fn render<T: fmt::Default, S: fmt::Default>(
+    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
+{
+    write!(dst, "
+<!DOCTYPE html>
+<html lang=\"en\">
+<head>
+    <meta charset=\"utf-8\" />
+    <title>{title}</title>
+
+    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400'
+          rel='stylesheet' type='text/css'>
+    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}main.css\">
+
+    {favicon, select, none{} other{
+        <link rel=\"icon\" href=\"#\" sizes=\"16x16\"
+              type=\"image/vnd.microsoft.icon\" />}}
+</head>
+<body>
+    <!--[if lte IE 8]>
+    <div class=\"warning\">
+        This old browser is unsupported and will most likely display funky
+        things
+    </div>
+    <![endif]-->
+
+    <section class=\"sidebar\">
+        {logo, select, none{} other{
+            <a href='{root_path}index.html'><img src='#' alt=''/></a>
+        }}
+
+        {sidebar}
+    </section>
+
+    <nav class=\"sub\">
+        <form class=\"search-form js-only\">
+            <input class=\"search-input\" name=\"search\"
+                   autocomplete=\"off\" />
+            <button class=\"do-search\">Search</button>
+        </form>
+    </nav>
+
+    <section class=\"content {ty}\">{content}</section>
+
+    <section class=\"footer\"></section>
+
+    <script>
+        var rootPath = \"{root_path}\";
+    </script>
+    <script src=\"{root_path}jquery.js\"></script>
+    <script src=\"{root_path}{crate}/search-index.js\"></script>
+    <script src=\"{root_path}main.js\"></script>
+
+    <div id=\"help\" class=\"hidden\">
+        <div class=\"shortcuts\">
+            <h1>Keyboard shortcuts</h1>
+            <dl>
+                <dt>?</dt>
+                <dd>Show this help dialog</dd>
+                <dt>S</dt>
+                <dd>Focus the search field</dd>
+                <dt>&uarr;</dt>
+                <dd>Move up in search results</dd>
+                <dt>&darr;</dt>
+                <dd>Move down in search results</dd>
+                <dt>&\\#9166;</dt>
+                <dd>Go to active search result</dd>
+            </dl>
+        </div>
+        <div class=\"infos\">
+            <h1>Search tricks</h1>
+            <p>
+                Prefix searches with a type followed by a colon (e.g.
+                <code>fn:</code>) to restrict the search to a given type.
+            </p>
+            <p>
+                Accepted types are: <code>fn</code>, <code>mod</code>,
+                <code>struct</code> (or <code>str</code>), <code>enum</code>,
+                <code>trait</code>, <code>typedef</code> (or
+                <code>tdef</code>).
+            </p>
+        </div>
+    </div>
+</body>
+</html>
+",
+    content   = *t,
+    root_path = page.root_path,
+    ty        = page.ty,
+    logo      = nonestr(layout.logo),
+    title     = page.title,
+    favicon   = nonestr(layout.favicon),
+    sidebar   = *sidebar,
+    crate     = layout.crate,
+    );
+}
+
+fn boolstr(b: bool) -> &'static str {
+    if b { "true" } else { "false" }
+}
+
+fn nonestr<'a>(s: &'a str) -> &'a str {
+    if s == "" { "none" } else { s }
+}
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
new file mode 100644 (file)
index 0000000..14e2327
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::fmt;
+use std::rt::io::Reader;
+use std::rt::io::pipe::PipeStream;
+use std::rt::io::process::{ProcessConfig, Process, CreatePipe};
+use std::rt::io;
+
+pub struct Markdown<'self>(&'self str);
+
+impl<'self> fmt::Default for Markdown<'self> {
+    fn fmt(md: &Markdown<'self>, fmt: &mut fmt::Formatter) {
+        if md.len() == 0 { return; }
+
+        // Create the pandoc process
+        do io::io_error::cond.trap(|err| {
+            fail2!("Error executing `pandoc`: {}", err.desc);
+        }).inside {
+            let io = ~[CreatePipe(PipeStream::new().unwrap(), true, false),
+                       CreatePipe(PipeStream::new().unwrap(), false, true)];
+            let args = ProcessConfig {
+                program: "pandoc",
+                args: [],
+                env: None,
+                cwd: None,
+                io: io,
+            };
+            let mut p = Process::new(args).expect("couldn't fork for pandoc");
+
+            // Write the markdown to stdin and close it.
+            p.io[0].get_mut_ref().write(md.as_bytes());
+            p.io[0] = None;
+
+            // Ferry the output from pandoc over to the destination buffer.
+            let mut buf = [0, ..1024];
+            loop {
+                match p.io[1].get_mut_ref().read(buf) {
+                    None | Some(0) => { break }
+                    Some(n) => {
+                        fmt.buf.write(buf.slice_to(n));
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
new file mode 100644 (file)
index 0000000..b004061
--- /dev/null
@@ -0,0 +1,1108 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::Cell;
+use std::comm::{SharedPort, SharedChan};
+use std::comm;
+use std::fmt;
+use std::hashmap::HashMap;
+use std::local_data;
+use std::rt::io::buffered::BufferedWriter;
+use std::rt::io::file::{FileInfo, DirectoryInfo};
+use std::rt::io::file;
+use std::rt::io;
+use std::task;
+use std::unstable::finally::Finally;
+use std::util;
+use std::vec;
+
+use extra::arc::RWArc;
+use extra::json::ToJson;
+use extra::sort;
+
+use syntax::ast;
+
+use clean;
+use doctree;
+use fold::DocFolder;
+use html::format::{VisSpace, Method};
+use html::layout;
+use html::markdown::Markdown;
+
+#[deriving(Clone)]
+pub struct Context {
+    current: ~[~str],
+    root_path: ~str,
+    dst: Path,
+    layout: layout::Layout,
+    sidebar: HashMap<~str, ~[~str]>,
+}
+
+enum Implementor {
+    PathType(clean::Type),
+    OtherType(clean::Generics, /* trait */ clean::Type, /* for */ clean::Type),
+}
+
+struct Cache {
+    // typaram id => name of that typaram
+    typarams: HashMap<ast::NodeId, ~str>,
+    // type id => all implementations for that type
+    impls: HashMap<ast::NodeId, ~[clean::Impl]>,
+    // path id => (full qualified path, shortty) -- used to generate urls
+    paths: HashMap<ast::NodeId, (~[~str], &'static str)>,
+    // trait id => method name => dox
+    traits: HashMap<ast::NodeId, HashMap<~str, ~str>>,
+    // trait id => implementors of the trait
+    implementors: HashMap<ast::NodeId, ~[Implementor]>,
+
+    priv stack: ~[~str],
+    priv parent_stack: ~[ast::NodeId],
+    priv search_index: ~[IndexItem],
+}
+
+struct Item<'self> { cx: &'self Context, item: &'self clean::Item, }
+struct Sidebar<'self> { cx: &'self Context, item: &'self clean::Item, }
+
+struct IndexItem {
+    ty: &'static str,
+    name: ~str,
+    path: ~str,
+    desc: ~str,
+    parent: Option<ast::NodeId>,
+}
+
+local_data_key!(pub cache_key: RWArc<Cache>)
+local_data_key!(pub current_location_key: ~[~str])
+
+/// Generates the documentation for `crate` into the directory `dst`
+pub fn run(mut crate: clean::Crate, dst: Path) {
+    let mut cx = Context {
+        dst: dst,
+        current: ~[],
+        root_path: ~"",
+        sidebar: HashMap::new(),
+        layout: layout::Layout {
+            logo: ~"",
+            favicon: ~"",
+            crate: crate.name.clone(),
+        },
+    };
+    mkdir(&cx.dst);
+
+    match crate.module.get_ref().doc_list() {
+        Some(attrs) => {
+            for attr in attrs.iter() {
+                match *attr {
+                    clean::NameValue(~"html_favicon_url", ref s) => {
+                        cx.layout.favicon = s.to_owned();
+                    }
+                    clean::NameValue(~"html_logo_url", ref s) => {
+                        cx.layout.logo = s.to_owned();
+                    }
+                    _ => {}
+                }
+            }
+        }
+        None => {}
+    }
+
+    // Crawl the crate to build various caches used for the output
+    let mut cache = Cache {
+        impls: HashMap::new(),
+        typarams: HashMap::new(),
+        paths: HashMap::new(),
+        traits: HashMap::new(),
+        implementors: HashMap::new(),
+        stack: ~[],
+        parent_stack: ~[],
+        search_index: ~[],
+    };
+    cache.stack.push(crate.name.clone());
+    crate = cache.fold_crate(crate);
+
+    // Add all the static files
+    write(cx.dst.push("jquery.js"), include_str!("static/jquery-2.0.3.min.js"));
+    write(cx.dst.push("main.js"), include_str!("static/main.js"));
+    write(cx.dst.push("main.css"), include_str!("static/main.css"));
+    write(cx.dst.push("normalize.css"), include_str!("static/normalize.css"));
+    write(cx.dst.push("index.html"), format!("
+        <DOCTYPE html><html><head>
+            <meta http-equiv='refresh'
+                  content=\"0; url={}/index.html\">
+        </head><body></body></html>
+    ", crate.name));
+
+    {
+        mkdir(&cx.dst.push(crate.name));
+        let dst = cx.dst.push(crate.name).push("search-index.js");
+        let mut w = BufferedWriter::new(dst.open_writer(io::CreateOrTruncate));
+        let w = &mut w as &mut io::Writer;
+        write!(w, "var searchIndex = [");
+        for (i, item) in cache.search_index.iter().enumerate() {
+            if i > 0 { write!(w, ","); }
+            write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
+                   item.ty, item.name, item.path,
+                   item.desc.to_json().to_str())
+            match item.parent {
+                Some(id) => { write!(w, ",parent:'{}'", id); }
+                None => {}
+            }
+            write!(w, "\\}");
+        }
+        write!(w, "];");
+        write!(w, "var allPaths = \\{");
+        for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() {
+            if i > 0 { write!(w, ","); }
+            write!(w, "'{}':\\{type:'{}',name:'{}'\\}", id, short, *fqp.last());
+        }
+        write!(w, "\\};");
+        w.flush();
+    }
+
+    // Now render the whole crate.
+    cx.crate(crate, cache);
+}
+
+fn write(dst: Path, contents: &str) {
+    let mut w = dst.open_writer(io::CreateOrTruncate);
+    w.write(contents.as_bytes());
+}
+
+fn mkdir(path: &Path) {
+    do io::io_error::cond.trap(|err| {
+        error2!("Couldn't create directory `{}`: {}",
+                path.to_str(), err.desc);
+        fail!()
+    }).inside {
+        if !path.is_dir() {
+            file::mkdir(path);
+        }
+    }
+}
+
+impl<'self> DocFolder for Cache {
+    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
+        // Register any generics to their corresponding string. This is used
+        // when pretty-printing types
+        match item.inner {
+            clean::StructItem(ref s)   => self.generics(&s.generics),
+            clean::EnumItem(ref e)     => self.generics(&e.generics),
+            clean::FunctionItem(ref f) => self.generics(&f.generics),
+            clean::TypedefItem(ref t)  => self.generics(&t.generics),
+            clean::TraitItem(ref t)    => self.generics(&t.generics),
+            clean::ImplItem(ref i)     => self.generics(&i.generics),
+            clean::TyMethodItem(ref i) => self.generics(&i.generics),
+            clean::MethodItem(ref i)   => self.generics(&i.generics),
+            _ => {}
+        }
+
+        // Propagate a trait methods' documentation to all implementors of the
+        // trait
+        match item.inner {
+            clean::TraitItem(ref t) => {
+                let mut dox = HashMap::new();
+                for meth in t.methods.iter() {
+                    let it = meth.item();
+                    match it.doc_value() {
+                        None => {}
+                        Some(s) => {
+                            dox.insert(it.name.get_ref().to_owned(),
+                                       s.to_owned());
+                        }
+                    }
+                }
+                self.traits.insert(item.id, dox);
+            }
+            _ => {}
+        }
+
+        // Collect all the implementors of traits.
+        match item.inner {
+            clean::ImplItem(ref i) => {
+                match i.trait_ {
+                    Some(clean::ResolvedPath{ id, _ }) => {
+                        let v = do self.implementors.find_or_insert_with(id) |_|{
+                            ~[]
+                        };
+                        match i.for_ {
+                            clean::ResolvedPath{_} => {
+                                v.unshift(PathType(i.for_.clone()));
+                            }
+                            _ => {
+                                v.push(OtherType(i.generics.clone(),
+                                                 i.trait_.get_ref().clone(),
+                                                 i.for_.clone()));
+                            }
+                        }
+                    }
+                    Some(*) | None => {}
+                }
+            }
+            _ => {}
+        }
+
+        // Index this method for searching later on
+        match item.name {
+            Some(ref s) => {
+                let parent = match item.inner {
+                    clean::TyMethodItem(*) | clean::VariantItem(*) => {
+                        Some((Some(*self.parent_stack.last()),
+                              self.stack.slice_to(self.stack.len() - 1)))
+
+                    }
+                    clean::MethodItem(*) => {
+                        if self.parent_stack.len() == 0 {
+                            None
+                        } else {
+                            Some((Some(*self.parent_stack.last()),
+                                  self.stack.as_slice()))
+                        }
+                    }
+                    _ => Some((None, self.stack.as_slice()))
+                };
+                match parent {
+                    Some((parent, path)) => {
+                        self.search_index.push(IndexItem {
+                            ty: shortty(&item),
+                            name: s.to_owned(),
+                            path: path.connect("::"),
+                            desc: shorter(item.doc_value()).to_owned(),
+                            parent: parent,
+                        });
+                    }
+                    None => {}
+                }
+            }
+            None => {}
+        }
+
+        // Keep track of the fully qualified path for this item.
+        let pushed = if item.name.is_some() {
+            let n = item.name.get_ref();
+            if n.len() > 0 {
+                self.stack.push(n.to_owned());
+                true
+            } else { false }
+        } else { false };
+        match item.inner {
+            clean::StructItem(*) | clean::EnumItem(*) |
+            clean::TypedefItem(*) | clean::TraitItem(*) => {
+                self.paths.insert(item.id, (self.stack.clone(), shortty(&item)));
+            }
+            _ => {}
+        }
+
+        // Maintain the parent stack
+        let parent_pushed = match item.inner {
+            clean::TraitItem(*) | clean::EnumItem(*) => {
+                self.parent_stack.push(item.id); true
+            }
+            clean::ImplItem(ref i) => {
+                match i.for_ {
+                    clean::ResolvedPath{ id, _ } => {
+                        self.parent_stack.push(id); true
+                    }
+                    _ => false
+                }
+            }
+            _ => false
+        };
+
+        // Once we've recursively found all the generics, then hoard off all the
+        // implementations elsewhere
+        let ret = match self.fold_item_recur(item) {
+            Some(item) => {
+                match item.inner {
+                    clean::ImplItem(i) => {
+                        match i.for_ {
+                            clean::ResolvedPath { id, _ } => {
+                                let v = do self.impls.find_or_insert_with(id) |_| {
+                                    ~[]
+                                };
+                                v.push(i);
+                            }
+                            _ => {}
+                        }
+                        None
+                    }
+                    _ => Some(item),
+                }
+            }
+            i => i,
+        };
+
+        if pushed { self.stack.pop(); }
+        if parent_pushed { self.parent_stack.pop(); }
+        return ret;
+    }
+}
+
+impl<'self> Cache {
+    fn generics(&mut self, generics: &clean::Generics) {
+        for typ in generics.type_params.iter() {
+            self.typarams.insert(typ.id, typ.name.clone());
+        }
+    }
+}
+
+impl Context {
+    fn recurse<T>(&mut self, s: ~str, f: &fn(&mut Context) -> T) -> T {
+        // Recurse in the directory structure and change the "root path" to make
+        // sure it always points to the top (relatively)
+        if s.len() == 0 {
+            fail2!("what {:?}", self);
+        }
+        let next = self.dst.push(s);
+        let prev = util::replace(&mut self.dst, next);
+        self.root_path.push_str("../");
+        self.current.push(s);
+
+        mkdir(&self.dst);
+        let ret = f(self);
+
+        // Go back to where we were at
+        self.dst = prev;
+        let len = self.root_path.len();
+        self.root_path.truncate(len - 3);
+        self.current.pop();
+
+        return ret;
+    }
+
+    /// Processes
+    fn crate(self, mut crate: clean::Crate, cache: Cache) {
+        enum Work {
+            Die,
+            Process(Context, clean::Item),
+        }
+        enum Progress { JobNew, JobDone }
+        static WORKERS: int = 10;
+
+        let mut item = match crate.module.take() {
+            Some(i) => i,
+            None => return
+        };
+        item.name = Some(crate.name);
+
+        let (port, chan) = comm::stream::<Work>();
+        let port = SharedPort::new(port);
+        let chan = SharedChan::new(chan);
+        let (prog_port, prog_chan) = comm::stream();
+        let prog_chan = SharedChan::new(prog_chan);
+        let cache = RWArc::new(cache);
+
+        for i in range(0, WORKERS) {
+            let port = port.clone();
+            let chan = chan.clone();
+            let prog_chan = prog_chan.clone();
+
+            let mut task = task::task();
+            task.unlinked(); // we kill things manually
+            task.name(format!("worker{}", i));
+            do task.spawn_with(cache.clone()) |cache| {
+                local_data::set(cache_key, cache);
+                loop {
+                    match port.recv() {
+                        Process(cx, item) => {
+                            let mut cx = cx;
+                            let item = Cell::new(item);
+                            do (|| {
+                                do cx.item(item.take()) |cx, item| {
+                                    prog_chan.send(JobNew);
+                                    chan.send(Process(cx.clone(), item));
+                                }
+                            }).finally {
+                                // If we fail, everything else should still get
+                                // completed
+                                prog_chan.send(JobDone);
+                            }
+                        }
+                        Die => break,
+                    }
+                }
+            }
+        }
+
+        let watcher_chan = chan.clone();
+        let (done_port, done_chan) = comm::stream();
+        do task::spawn {
+            let mut jobs = 0;
+            loop {
+                match prog_port.recv() {
+                    JobNew => jobs += 1,
+                    JobDone => jobs -= 1,
+                }
+
+                if jobs == 0 { break }
+            }
+
+            for _ in range(0, WORKERS) {
+                watcher_chan.send(Die);
+            }
+            done_chan.send(());
+        }
+
+        prog_chan.send(JobNew);
+        chan.send(Process(self, item));
+        done_port.recv();
+    }
+
+    fn item(&mut self, item: clean::Item, f: &fn(&mut Context, clean::Item)) {
+        fn render(w: io::file::FileWriter, cx: &mut Context, it: &clean::Item,
+                  pushname: bool) {
+            // A little unfortunate that this is done like this, but it sure
+            // does make formatting *a lot* nicer.
+            local_data::set(current_location_key, cx.current.clone());
+
+            let mut title = cx.current.connect("::");
+            if pushname {
+                if title.len() > 0 { title.push_str("::"); }
+                title.push_str(*it.name.get_ref());
+            }
+            title.push_str(" - Rust");
+            let page = layout::Page {
+                ty: shortty(it),
+                root_path: cx.root_path,
+                title: title,
+            };
+
+            // We have a huge number of calls to write, so try to alleviate some
+            // of the pain by using a buffered writer instead of invoking the
+            // write sycall all the time.
+            let mut writer = BufferedWriter::new(w);
+            layout::render(&mut writer as &mut io::Writer, &cx.layout, &page,
+                           &Sidebar{ cx: cx, item: it },
+                           &Item{ cx: cx, item: it });
+            writer.flush();
+        }
+
+        match item.inner {
+            clean::ModuleItem(*) => {
+                let name = item.name.get_ref().to_owned();
+                let item = Cell::new(item);
+                do self.recurse(name) |this| {
+                    let item = item.take();
+                    let dst = this.dst.push("index.html");
+                    let writer = dst.open_writer(io::CreateOrTruncate);
+                    render(writer.unwrap(), this, &item, false);
+
+                    let m = match item.inner {
+                        clean::ModuleItem(m) => m,
+                        _ => unreachable!()
+                    };
+                    this.sidebar = build_sidebar(&m);
+                    for item in m.items.move_iter() {
+                        f(this, item);
+                    }
+                }
+            }
+            _ if item.name.is_some() => {
+                let dst = self.dst.push(item_path(&item));
+                let writer = dst.open_writer(io::CreateOrTruncate);
+                render(writer.unwrap(), self, &item, true);
+            }
+            _ => {}
+        }
+    }
+}
+
+fn shortty(item: &clean::Item) -> &'static str {
+    match item.inner {
+        clean::ModuleItem(*)      => "mod",
+        clean::StructItem(*)      => "struct",
+        clean::EnumItem(*)        => "enum",
+        clean::FunctionItem(*)    => "fn",
+        clean::TypedefItem(*)     => "typedef",
+        clean::StaticItem(*)      => "static",
+        clean::TraitItem(*)       => "trait",
+        clean::ImplItem(*)        => "impl",
+        clean::ViewItemItem(*)    => "viewitem",
+        clean::TyMethodItem(*)    => "tymethod",
+        clean::MethodItem(*)      => "method",
+        clean::StructFieldItem(*) => "structfield",
+        clean::VariantItem(*)     => "variant",
+    }
+}
+
+impl<'self> Item<'self> {
+    fn ismodule(&self) -> bool {
+        match self.item.inner {
+            clean::ModuleItem(*) => true, _ => false
+        }
+    }
+}
+
+impl<'self> fmt::Default for Item<'self> {
+    fn fmt(it: &Item<'self>, fmt: &mut fmt::Formatter) {
+        // Write the breadcrumb trail header for the top
+        write!(fmt.buf, "<h1 class='fqn'>");
+        match it.item.inner {
+            clean::ModuleItem(*) => write!(fmt.buf, "Module "),
+            clean::FunctionItem(*) => write!(fmt.buf, "Function "),
+            clean::TraitItem(*) => write!(fmt.buf, "Trait "),
+            clean::StructItem(*) => write!(fmt.buf, "Struct "),
+            clean::EnumItem(*) => write!(fmt.buf, "Enum "),
+            _ => {}
+        }
+        let cur = it.cx.current.as_slice();
+        let amt = if it.ismodule() { cur.len() - 1 } else { cur.len() };
+        for (i, component) in cur.iter().enumerate().take(amt) {
+            let mut trail = ~"";
+            for _ in range(0, cur.len() - i - 1) {
+                trail.push_str("../");
+            }
+            write!(fmt.buf, "<a href='{}index.html'>{}</a>::",
+                   trail, component.as_slice());
+        }
+        write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>",
+               shortty(it.item), it.item.name.get_ref().as_slice());
+
+        match it.item.inner {
+            clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
+                                                    it.item, m.items),
+            clean::FunctionItem(ref f) => item_function(fmt.buf, it.item, f),
+            clean::TraitItem(ref t) => item_trait(fmt.buf, it.item, t),
+            clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
+            clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
+            clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t),
+            _ => {}
+        }
+    }
+}
+
+fn item_path(item: &clean::Item) -> ~str {
+    match item.inner {
+        clean::ModuleItem(*) => *item.name.get_ref() + "/index.html",
+        _ => shortty(item) + "." + *item.name.get_ref() + ".html"
+    }
+}
+
+fn full_path(cx: &Context, item: &clean::Item) -> ~str {
+    let mut s = cx.current.connect("::");
+    s.push_str("::");
+    s.push_str(item.name.get_ref().as_slice());
+    return s;
+}
+
+fn blank<'a>(s: Option<&'a str>) -> &'a str {
+    match s {
+        Some(s) => s,
+        None => ""
+    }
+}
+
+fn shorter<'a>(s: Option<&'a str>) -> &'a str {
+    match s {
+        Some(s) => match s.find_str("\n\n") {
+            Some(pos) => s.slice_to(pos),
+            None => s,
+        },
+        None => ""
+    }
+}
+
+fn document(w: &mut io::Writer, item: &clean::Item) {
+    match item.doc_value() {
+        Some(s) => {
+            write!(w, "<div class='docblock'>{}</div>", Markdown(s));
+        }
+        None => {}
+    }
+}
+
+fn item_module(w: &mut io::Writer, cx: &Context,
+               item: &clean::Item, items: &[clean::Item]) {
+    document(w, item);
+    let mut indices = vec::from_fn(items.len(), |i| i);
+
+    fn lt(i1: &clean::Item, i2: &clean::Item) -> bool {
+        if shortty(i1) == shortty(i2) {
+            return i1.name < i2.name;
+        }
+        match (&i1.inner, &i2.inner) {
+            (&clean::ViewItemItem(*), _) => true,
+            (_, &clean::ViewItemItem(*)) => false,
+            (&clean::ModuleItem(*), _) => true,
+            (_, &clean::ModuleItem(*)) => false,
+            (&clean::StructItem(*), _) => true,
+            (_, &clean::StructItem(*)) => false,
+            (&clean::EnumItem(*), _) => true,
+            (_, &clean::EnumItem(*)) => false,
+            (&clean::StaticItem(*), _) => true,
+            (_, &clean::StaticItem(*)) => false,
+            (&clean::TraitItem(*), _) => true,
+            (_, &clean::TraitItem(*)) => false,
+            (&clean::FunctionItem(*), _) => true,
+            (_, &clean::FunctionItem(*)) => false,
+            (&clean::TypedefItem(*), _) => true,
+            (_, &clean::TypedefItem(*)) => false,
+            _ => false,
+        }
+    }
+
+    do sort::quick_sort(indices) |&i1, &i2| {
+        lt(&items[i1], &items[i2])
+    }
+
+    let mut curty = "";
+    for &idx in indices.iter() {
+        let myitem = &items[idx];
+        if myitem.name.is_none() { loop }
+
+        let myty = shortty(myitem);
+        if myty != curty {
+            if curty != "" {
+                write!(w, "</table>");
+            }
+            curty = myty;
+            write!(w, "<h2>{}</h2>\n<table>", match myitem.inner {
+                clean::ModuleItem(*)      => "Modules",
+                clean::StructItem(*)      => "Structs",
+                clean::EnumItem(*)        => "Enums",
+                clean::FunctionItem(*)    => "Functions",
+                clean::TypedefItem(*)     => "Type Definitions",
+                clean::StaticItem(*)      => "Statics",
+                clean::TraitItem(*)       => "Traits",
+                clean::ImplItem(*)        => "Implementations",
+                clean::ViewItemItem(*)    => "Reexports",
+                clean::TyMethodItem(*)    => "Type Methods",
+                clean::MethodItem(*)      => "Methods",
+                clean::StructFieldItem(*) => "Struct Fields",
+                clean::VariantItem(*)     => "Variants",
+            });
+        }
+
+        match myitem.inner {
+            clean::StaticItem(ref s) => {
+                struct Initializer<'self>(&'self str);
+                impl<'self> fmt::Default for Initializer<'self> {
+                    fn fmt(s: &Initializer<'self>, f: &mut fmt::Formatter) {
+                        let tag = if s.contains("\n") { "pre" } else { "code" };
+                        write!(f.buf, "<{tag}>{}</{tag}>",
+                               s.as_slice(), tag=tag);
+                    }
+                }
+
+                write!(w, "
+                    <tr>
+                        <td><code>{}: {} = </code>{}</td>
+                        <td class='docblock'>{}&nbsp;</td>
+                    </tr>
+                ",
+                *myitem.name.get_ref(),
+                s.type_,
+                Initializer(s.expr),
+                Markdown(blank(myitem.doc_value())));
+            }
+
+            _ => {
+                write!(w, "
+                    <tr>
+                        <td><a class='{class}' href='{href}'
+                               title='{title}'>{}</a></td>
+                        <td class='docblock short'>{}</td>
+                    </tr>
+                ",
+                *myitem.name.get_ref(),
+                Markdown(shorter(myitem.doc_value())),
+                class = shortty(myitem),
+                href = item_path(myitem),
+                title = full_path(cx, myitem));
+            }
+        }
+    }
+    write!(w, "</table>");
+}
+
+fn item_function(w: &mut io::Writer, it: &clean::Item, f: &clean::Function) {
+    write!(w, "<pre class='fn'>{vis}fn {name}{generics}{decl}</pre>",
+           vis = VisSpace(it.visibility),
+           name = it.name.get_ref().as_slice(),
+           generics = f.generics,
+           decl = f.decl);
+    document(w, it);
+}
+
+fn item_trait(w: &mut io::Writer, it: &clean::Item, t: &clean::Trait) {
+    let mut parents = ~"";
+    if t.parents.len() > 0 {
+        parents.push_str(": ");
+        for (i, p) in t.parents.iter().enumerate() {
+            if i > 0 { parents.push_str(" + "); }
+            parents.push_str(format!("{}", *p));
+        }
+    }
+
+    // Output the trait definition
+    write!(w, "<pre class='trait'>{}trait {}{}{} ",
+           VisSpace(it.visibility),
+           it.name.get_ref().as_slice(),
+           t.generics,
+           parents);
+    let required = t.methods.iter().filter(|m| m.is_req()).to_owned_vec();
+    let provided = t.methods.iter().filter(|m| !m.is_req()).to_owned_vec();
+
+    if t.methods.len() == 0 {
+        write!(w, "\\{ \\}");
+    } else {
+        write!(w, "\\{\n");
+        for m in required.iter() {
+            write!(w, "    ");
+            render_method(w, m.item(), true);
+            write!(w, ";\n");
+        }
+        if required.len() > 0 && provided.len() > 0 {
+            w.write("\n".as_bytes());
+        }
+        for m in provided.iter() {
+            write!(w, "    ");
+            render_method(w, m.item(), true);
+            write!(w, " \\{ ... \\}\n");
+        }
+        write!(w, "\\}");
+    }
+    write!(w, "</pre>");
+
+    // Trait documentation
+    document(w, it);
+
+    fn meth(w: &mut io::Writer, m: &clean::TraitMethod) {
+        write!(w, "<h3 id='fn.{}' class='method'><code>",
+               *m.item().name.get_ref());
+        render_method(w, m.item(), false);
+        write!(w, "</code></h3>");
+        document(w, m.item());
+    }
+
+    // Output the documentation for each function individually
+    if required.len() > 0 {
+        write!(w, "
+            <h2 id='required-methods'>Required Methods</h2>
+            <div class='methods'>
+        ");
+        for m in required.iter() {
+            meth(w, *m);
+        }
+        write!(w, "</div>");
+    }
+    if provided.len() > 0 {
+        write!(w, "
+            <h2 id='provided-methods'>Provided Methods</h2>
+            <div class='methods'>
+        ");
+        for m in provided.iter() {
+            meth(w, *m);
+        }
+        write!(w, "</div>");
+    }
+
+    do local_data::get(cache_key) |cache| {
+        do cache.unwrap().read |cache| {
+            match cache.implementors.find(&it.id) {
+                Some(implementors) => {
+                    write!(w, "
+                        <h2 id='implementors'>Implementors</h2>
+                        <ul class='item-list'>
+                    ");
+                    for i in implementors.iter() {
+                        match *i {
+                            PathType(ref ty) => {
+                                write!(w, "<li><code>{}</code></li>", *ty);
+                            }
+                            OtherType(ref generics, ref trait_, ref for_) => {
+                                write!(w, "<li><code>impl{} {} for {}</code></li>",
+                                       *generics, *trait_, *for_);
+                            }
+                        }
+                    }
+                    write!(w, "</ul>");
+                }
+                None => {}
+            }
+        }
+    }
+}
+
+fn render_method(w: &mut io::Writer, meth: &clean::Item, withlink: bool) {
+    fn fun(w: &mut io::Writer, it: &clean::Item, purity: ast::purity,
+           g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
+           withlink: bool) {
+        write!(w, "{}fn {withlink, select,
+                            true{<a href='\\#fn.{name}'>{name}</a>}
+                            other{{name}}
+                        }{generics}{decl}",
+               match purity {
+                   ast::unsafe_fn => "unsafe ",
+                   _ => "",
+               },
+               name = it.name.get_ref().as_slice(),
+               generics = *g,
+               decl = Method(selfty, d),
+               withlink = if withlink {"true"} else {"false"});
+    }
+    match meth.inner {
+        clean::TyMethodItem(ref m) => {
+            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+        }
+        clean::MethodItem(ref m) => {
+            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+        }
+        _ => unreachable!()
+    }
+}
+
+fn item_struct(w: &mut io::Writer, it: &clean::Item, s: &clean::Struct) {
+    write!(w, "<pre class='struct'>");
+    render_struct(w, it, Some(&s.generics), s.struct_type, s.fields, "");
+    write!(w, "</pre>");
+
+    document(w, it);
+    render_methods(w, it);
+}
+
+fn item_enum(w: &mut io::Writer, it: &clean::Item, e: &clean::Enum) {
+    write!(w, "<pre class='enum'>{}enum {}{}",
+           VisSpace(it.visibility),
+           it.name.get_ref().as_slice(),
+           e.generics);
+    if e.variants.len() == 0 {
+        write!(w, " \\{\\}");
+    } else {
+        write!(w, " \\{\n");
+        for v in e.variants.iter() {
+            let name = v.name.get_ref().as_slice();
+            match v.inner {
+                clean::VariantItem(ref var) => {
+                    match var.kind {
+                        clean::CLikeVariant => write!(w, "    {},\n", name),
+                        clean::TupleVariant(ref tys) => {
+                            write!(w, "    {}(", name);
+                            for (i, ty) in tys.iter().enumerate() {
+                                if i > 0 { write!(w, ", ") }
+                                write!(w, "{}", *ty);
+                            }
+                            write!(w, "),\n");
+                        }
+                        clean::StructVariant(ref s) => {
+                            render_struct(w, v, None, s.struct_type, s.fields,
+                                          "    ");
+                        }
+                    }
+                }
+                _ => unreachable!()
+            }
+        }
+        write!(w, "\\}");
+    }
+    write!(w, "</pre>");
+
+    document(w, it);
+    render_methods(w, it);
+}
+
+fn render_struct(w: &mut io::Writer, it: &clean::Item,
+                 g: Option<&clean::Generics>,
+                 ty: doctree::StructType,
+                 fields: &[clean::Item],
+                 tab: &str) {
+    write!(w, "{}struct {}",
+           VisSpace(it.visibility),
+           it.name.get_ref().as_slice());
+    match g {
+        Some(g) => write!(w, "{}", *g),
+        None => {}
+    }
+    match ty {
+        doctree::Plain => {
+            write!(w, " \\{\n");
+            for field in fields.iter() {
+                match field.inner {
+                    clean::StructFieldItem(ref ty) => {
+                        write!(w, "    {}{}: {},\n{}",
+                               VisSpace(field.visibility),
+                               field.name.get_ref().as_slice(),
+                               ty.type_,
+                               tab);
+                    }
+                    _ => unreachable!()
+                }
+            }
+            write!(w, "\\}");
+        }
+        doctree::Tuple | doctree::Newtype => {
+            write!(w, "(");
+            for (i, field) in fields.iter().enumerate() {
+                if i > 0 { write!(w, ", ") }
+                match field.inner {
+                    clean::StructFieldItem(ref field) => {
+                        write!(w, "{}", field.type_);
+                    }
+                    _ => unreachable!()
+                }
+            }
+            write!(w, ");");
+        }
+        doctree::Unit => { write!(w, ";"); }
+    }
+}
+
+fn render_methods(w: &mut io::Writer, it: &clean::Item) {
+    do local_data::get(cache_key) |cache| {
+        let cache = cache.unwrap();
+        do cache.read |c| {
+            match c.impls.find(&it.id) {
+                Some(v) => {
+                    let mut non_trait = v.iter().filter(|i| i.trait_.is_none());
+                    let non_trait = non_trait.to_owned_vec();
+                    let mut traits = v.iter().filter(|i| i.trait_.is_some());
+                    let traits = traits.to_owned_vec();
+
+                    if non_trait.len() > 0 {
+                        write!(w, "<h2 id='methods'>Methods</h2>");
+                        for &i in non_trait.iter() {
+                            render_impl(w, i);
+                        }
+                    }
+                    if traits.len() > 0 {
+                        write!(w, "<h2 id='implementations'>Trait \
+                                   Implementations</h2>");
+                        for &i in traits.iter() {
+                            render_impl(w, i);
+                        }
+                    }
+                }
+                None => {}
+            }
+        }
+    }
+}
+
+fn render_impl(w: &mut io::Writer, i: &clean::Impl) {
+    write!(w, "<h3 class='impl'><code>impl{} ", i.generics);
+    let trait_id = match i.trait_ {
+        Some(ref ty) => {
+            write!(w, "{} for ", *ty);
+            match *ty {
+                clean::ResolvedPath { id, _ } => Some(id),
+                _ => None,
+            }
+        }
+        None => None
+    };
+    write!(w, "{}</code></h3>", i.for_);
+    write!(w, "<div class='methods'>");
+    for meth in i.methods.iter() {
+        write!(w, "<h4 id='fn.{}' class='method'><code>",
+               *meth.name.get_ref());
+        render_method(w, meth, false);
+        write!(w, "</code></h4>\n");
+        match meth.doc_value() {
+            Some(s) => {
+                write!(w, "<div class='docblock'>{}</div>", Markdown(s));
+                loop
+            }
+            None => {}
+        }
+
+        // No documentation? Attempt to slurp in the trait's documentation
+        let trait_id = match trait_id { Some(id) => id, None => loop };
+        do local_data::get(cache_key) |cache| {
+            do cache.unwrap().read |cache| {
+                let name = meth.name.get_ref().as_slice();
+                match cache.traits.find(&trait_id) {
+                    Some(m) => {
+                        match m.find_equiv(&name) {
+                            Some(s) => {
+                                write!(w, "<div class='docblock'>{}</div>",
+                                       Markdown(s.as_slice()));
+                            }
+                            None => {}
+                        }
+                    }
+                    None => {}
+                }
+            }
+        }
+    }
+    write!(w, "</div>");
+}
+
+fn item_typedef(w: &mut io::Writer, it: &clean::Item, t: &clean::Typedef) {
+    write!(w, "<pre class='typedef'>type {}{} = {};</pre>",
+           it.name.get_ref().as_slice(),
+           t.generics,
+           t.type_);
+
+    document(w, it);
+}
+
+impl<'self> fmt::Default for Sidebar<'self> {
+    fn fmt(s: &Sidebar<'self>, fmt: &mut fmt::Formatter) {
+        let cx = s.cx;
+        let it = s.item;
+        write!(fmt.buf, "<p class='location'>");
+        let len = cx.current.len() - if it.is_mod() {1} else {0};
+        for (i, name) in cx.current.iter().take(len).enumerate() {
+            if i > 0 { write!(fmt.buf, "&\\#8203;::") }
+            write!(fmt.buf, "<a href='{}index.html'>{}</a>",
+                   cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name);
+        }
+        write!(fmt.buf, "</p>");
+
+        fn block(w: &mut io::Writer, short: &str, longty: &str,
+                 cur: &clean::Item, cx: &Context) {
+            let items = match cx.sidebar.find_equiv(&short) {
+                Some(items) => items.as_slice(),
+                None => return
+            };
+            write!(w, "<div class='block {}'><h2>{}</h2>", short, longty);
+            for item in items.iter() {
+                let class = if cur.name.get_ref() == item &&
+                               short == shortty(cur) { "current" } else { "" };
+                write!(w, "<a class='{ty} {class}' href='{curty, select,
+                                mod{../}
+                                other{}
+                           }{ty, select,
+                                mod{{name}/index.html}
+                                other{#.{name}.html}
+                           }'>{name}</a><br/>",
+                       ty = short,
+                       class = class,
+                       curty = shortty(cur),
+                       name = item.as_slice());
+            }
+            write!(w, "</div>");
+        }
+
+        block(fmt.buf, "mod", "Modules", it, cx);
+        block(fmt.buf, "struct", "Structs", it, cx);
+        block(fmt.buf, "enum", "Enums", it, cx);
+        block(fmt.buf, "trait", "Traits", it, cx);
+        block(fmt.buf, "fn", "Functions", it, cx);
+    }
+}
+
+fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> {
+    let mut map = HashMap::new();
+    for item in m.items.iter() {
+        let short = shortty(item);
+        let myname = match item.name {
+            None => loop,
+            Some(ref s) => s.to_owned(),
+        };
+        let v = map.find_or_insert_with(short.to_owned(), |_| ~[]);
+        v.push(myname);
+    }
+
+    for (_, items) in map.mut_iter() {
+        sort::quick_sort(*items, |i1, i2| i1 < i2);
+    }
+    return map;
+}
diff --git a/src/librustdoc/html/static/jquery-2.0.3.min.js b/src/librustdoc/html/static/jquery-2.0.3.min.js
new file mode 100644 (file)
index 0000000..2be209d
--- /dev/null
@@ -0,0 +1,6 @@
+/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery-2.0.3.min.map
+*/
+(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p="2.0.3",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v="sizzle"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",$=W.replace("w","w#"),B="\\["+M+"*("+W+")"+M+"*(?:([*^$|!~]?=)"+M+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+$+")|)|)"+M+"*\\]",I=":("+W+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+B.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=RegExp("^"+M+"*,"+M+"*"),X=RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=RegExp(M+"*[+~]"),Y=RegExp("="+M+"*([^\\]'\"]*)"+M+"*\\]","g"),V=RegExp(I),G=RegExp("^"+$+"$"),J={ID:RegExp("^#("+W+")"),CLASS:RegExp("^\\.("+W+")"),TAG:RegExp("^("+W.replace("w","w*")+")"),ATTR:RegExp("^"+B),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:RegExp("^(?:"+R+")$","i"),needsContext:RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Q=/^[^{]+\{\s*\[native \w/,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\d$/i,tt=/'|\\/g,nt=RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||"string"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute("id"))?m=g.replace(tt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent("onbeforeunload",function(){c()}),n.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||d.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll(":checked").length||d.push(":checked")}),ut(function(e){var n=t.createElement("input");n.setAttribute("type","hidden"),e.appendChild(n).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&d.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||d.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),d.push(",.*:")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",I)}),d=d.length&&RegExp(d.join("|")),g=g.length&&RegExp(g.join("|")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,"='$1']"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||"").replace(nt,rt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);return r[v]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,"$1"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||"")||ot.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z," ")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x="0",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&"ID"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split("").sort(S).join("")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||lt("type|href|height|width",function(e,t,n){return n?undefined:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||lt("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&"string"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)
+};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n\f]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,"string"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return Z(e,"nextSibling")},prev:function(e){return Z(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,nt=/<([\w:]+)/,rt=/<|&#?\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\s*(?:[^=]|=\s*.checked.)/i,at=/^$|\/(?:java|ecma)script/i,ut=/^true\/(.*)/,lt=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ct={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(tt,"<$1></$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,"script"),s.length>0&&dt(s,!u&&mt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement("div")),s=(nt.exec(i)||["",""])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,"<$1></$2>")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=""}else h.push(t.createTextNode(i));f.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),"script"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||"")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}});function pt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ot.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp("^("+b+")(.*)$","i"),Ct=RegExp("^("+b+")(?!px)[a-z%]+$","i"),kt=RegExp("^([+-])=("+b+")","i"),Nt={BODY:"block"},Et={position:"absolute",visibility:"hidden",display:"block"},St={letterSpacing:0,fontWeight:400},jt=["Top","Right","Bottom","Left"],Dt=["Webkit","O","Moz","ms"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Lt(r)&&(o[s]=q.access(r,"olddisplay",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),"normal"===i&&t in St&&(i=St[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ft(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+jt[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+jt[o]+"Width",!0,i))):(s+=x.css(e,"padding"+jt[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+jt[o]+"Width",!0,i)));return s}function Pt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?"border":"content"),r,o)+"px"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),"none"!==n&&n||(xt=(xt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(xt[0].contentWindow||xt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=Mt(e,t),xt.detach()),Nt[e]=n),n}function Mt(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,t){x.cssHooks[t]={get:function(e,n,r){return n?0===e.offsetWidth&&bt.test(x.css(e,"display"))?x.swap(e,Et,function(){return Pt(e,t,r)}):Pt(e,t,r):undefined},set:function(e,n,r){var i=r&&qt(e);return Ot(e,n,r?Ft(e,t,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,t){return t?x.swap(e,{display:"inline-block"},vt,[e,"marginRight"]):undefined}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,t){x.cssHooks[t]={get:function(e,n){return n?(n=vt(e,t),Ct.test(n)?x(e).position()[t]+"px":n):undefined}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+jt[r]+t]=o[r]||o[r-2]||o[0];return i}},wt.test(e)||(x.cssHooks[e+t].set=Ot)});var Wt=/%20/g,$t=/\[\]$/,Bt=/\r?\n/g,It=/^(?:submit|button|image|reset|file)$/i,zt=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&zt.test(this.nodeName)&&!It.test(e)&&(this.checked||!ot.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(Bt,"\r\n")}}):{name:t.name,value:n.replace(Bt,"\r\n")}}).get()}}),x.param=function(e,t){var n,r=[],i=function(e,t){t=x.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){i(this.name,this.value)});else for(n in e)_t(n,e[n],t,i);return r.join("&").replace(Wt,"+")};function _t(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||$t.test(e)?r(e,i):_t(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)_t(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)
+},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Xt,Ut,Yt=x.now(),Vt=/\?/,Gt=/#.*$/,Jt=/([?&])_=[^&]*/,Qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Kt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Zt=/^(?:GET|HEAD)$/,en=/^\/\//,tn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,nn=x.fn.load,rn={},on={},sn="*/".concat("*");try{Ut=i.href}catch(an){Ut=o.createElement("a"),Ut.href="",Ut=Ut.href}Xt=tn.exec(Ut.toLowerCase())||[];function un(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function ln(e,t,n,r){var i={},o=e===on;function s(a){var u;return i[a]=!0,x.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):undefined:(t.dataTypes.unshift(l),s(l),!1)}),u}return s(t.dataTypes[0])||!i["*"]&&s("*")}function cn(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)t[n]!==undefined&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,t,n){if("string"!=typeof e&&nn)return nn.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=e.slice(a),e=e.slice(0,a)),x.isFunction(t)?(n=t,t=undefined):t&&"object"==typeof t&&(i="POST"),s.length>0&&x.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?x("<div>").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ut,type:"GET",isLocal:Kt.test(Xt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":sn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?cn(cn(e,x.ajaxSettings),t):cn(x.ajaxSettings,e)},ajaxPrefilter:un(rn),ajaxTransport:un(on),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),p=c.context||c,f=c.context&&(p.nodeType||p.jquery)?x(p):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Qt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Ut)+"").replace(Gt,"").replace(en,Xt[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=tn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===Xt[1]&&a[2]===Xt[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(Xt[3]||("http:"===Xt[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),ln(rn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Zt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Vt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Jt.test(r)?r.replace(Jt,"$1_="+Yt++):r+(Vt.test(r)?"&":"?")+"_="+Yt++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+sn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(p,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=ln(on,c,t,T)){T.readyState=1,u&&f.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=pn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e||"HEAD"===c.type?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(p,[m,C,T]):h.rejectWith(p,[T,C,y]),T.statusCode(g),g=undefined,u&&f.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(p,[T,C]),u&&(f.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function pn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(p){return{state:"parsererror",error:s?p:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),o.head.appendChild(t[0])},abort:function(){n&&n()}}}});var hn=[],dn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=hn.pop()||x.expando+"_"+Yt++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");return a||"jsonp"===t.dataTypes[0]?(i=t.jsonpCallback=x.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(Vt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||x.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,hn.push(i)),s&&x.isFunction(o)&&o(s[0]),s=o=undefined}),"script"):undefined}),x.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var gn=x.ajaxSettings.xhr(),mn={0:200,1223:204},yn=0,vn={};e.ActiveXObject&&x(e).on("unload",function(){for(var e in vn)vn[e]();vn=undefined}),x.support.cors=!!gn&&"withCredentials"in gn,x.support.ajax=gn=!!gn,x.ajaxTransport(function(e){var t;return x.support.cors||gn&&!e.crossDomain?{send:function(n,r){var i,o,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete vn[o],t=s.onload=s.onerror=null,"abort"===e?s.abort():"error"===e?r(s.status||404,s.statusText):r(mn[s.status]||s.status,s.statusText,"string"==typeof s.responseText?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=vn[o=yn++]=t("abort"),s.send(e.hasContent&&e.data||null)},abort:function(){t&&t()}}:undefined});var xn,bn,wn=/^(?:toggle|show|hide)$/,Tn=RegExp("^(?:([+-])=|)("+b+")([a-z%]*)$","i"),Cn=/queueHooks$/,kn=[An],Nn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Tn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),s=(x.cssNumber[e]||"px"!==o&&+r)&&Tn.exec(x.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do a=a||".5",s/=a,x.style(n.elem,e,s+o);while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};function En(){return setTimeout(function(){xn=undefined}),xn=x.now()}function Sn(e,t,n){var r,i=(Nn[t]||[]).concat(Nn["*"]),o=0,s=i.length;for(;s>o;o++)if(r=i[o].call(n,t,e))return r}function jn(e,t,n){var r,i,o=0,s=kn.length,a=x.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=xn||En(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;for(;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:xn||En(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(Dn(c,l.opts.specialEasing);s>o;o++)if(r=kn[o].call(l,e,c,l.opts))return r;return x.map(c,Sn,l),x.isFunction(l.opts.start)&&l.opts.start.call(e,l),x.fx.timer(x.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function Dn(e,t){var n,r,i,o,s;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=x.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(jn,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Nn[n]=Nn[n]||[],Nn[n].unshift(t)},prefilter:function(e,t){t?kn.unshift(e):kn.push(e)}});function An(e,t,n){var r,i,o,s,a,u,l=this,c={},p=e.style,f=e.nodeType&&Lt(e),h=q.get(e,"fxshow");n.queue||(a=x._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,l.always(function(){l.always(function(){a.unqueued--,x.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(p.display="inline-block")),n.overflow&&(p.overflow="hidden",l.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],wn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show")){if("show"!==i||!h||h[r]===undefined)continue;f=!0}c[r]=h&&h[r]||x.style(e,r)}if(!x.isEmptyObject(c)){h?"hidden"in h&&(f=h.hidden):h=q.access(e,"fxshow",{}),o&&(h.hidden=!f),f?x(e).show():l.done(function(){x(e).hide()}),l.done(function(){var t;q.remove(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)s=Sn(f?h[r]:0,r,l),r in h||(h[r]=s.start,f&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}function Ln(e,t,n,r,i){return new Ln.prototype.init(e,t,n,r,i)}x.Tween=Ln,Ln.prototype={constructor:Ln,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=Ln.propHooks[this.prop];return e&&e.get?e.get(this):Ln.propHooks._default.get(this)},run:function(e){var t,n=Ln.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ln.propHooks._default.set(this),this}},Ln.prototype.init.prototype=Ln.prototype,Ln.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Ln.propHooks.scrollTop=Ln.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(qn(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Lt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),s=function(){var t=jn(this,x.extend({},e),o);(i||q.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=undefined),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=x.timers,s=q.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Cn.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=q.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,s=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function qn(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=jt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:qn("show"),slideUp:qn("hide"),slideToggle:qn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=Ln.prototype.init,x.fx.tick=function(){var e,t=x.timers,n=0;for(xn=x.now();t.length>n;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||x.fx.stop(),xn=undefined},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){bn||(bn=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(bn),bn=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===undefined?this:this.each(function(t){x.offset.setOffset(this,e,t)});var t,n,i=this[0],o={top:0,left:0},s=i&&i.ownerDocument;if(s)return t=s.documentElement,x.contains(t,i)?(typeof i.getBoundingClientRect!==r&&(o=i.getBoundingClientRect()),n=Hn(s),{top:o.top+n.pageYOffset-t.clientTop,left:o.left+n.pageXOffset-t.clientLeft}):o},x.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l,c=x.css(e,"position"),p=x(e),f={};"static"===c&&(e.style.position="relative"),a=p.offset(),o=x.css(e,"top"),u=x.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=p.position(),s=r.top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),x.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+i),"using"in t?t.using.call(e,f):p.css(f)}},x.fn.extend({position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===x.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(r=e.offset()),r.top+=x.css(e[0],"borderTopWidth",!0),r.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-x.css(n,"marginTop",!0),left:t.left-r.left-x.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;x.fn[t]=function(i){return x.access(this,function(t,i,o){var s=Hn(t);return o===undefined?s?s[n]:t[i]:(s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o,undefined)},t,i,arguments.length,null)}});function Hn(e){return x.isWindow(e)?e:9===e.nodeType&&e.defaultView}x.each({Height:"height",Width:"width"},function(e,t){x.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){x.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(r===!0||i===!0?"margin":"border");return x.access(this,function(t,n,r){var i;return x.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):r===undefined?x.css(t,n,s):x.style(t,n,r,s)},t,o?r:undefined,o,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}),"object"==typeof e&&"object"==typeof e.document&&(e.jQuery=e.$=x)})(window);
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
new file mode 100644 (file)
index 0000000..2b96516
--- /dev/null
@@ -0,0 +1,270 @@
+/**
+ * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+ * file at the top-level directory of this distribution and at
+ * http://rust-lang.org/COPYRIGHT.
+ *
+ * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+ * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+ * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+ * option. This file may not be copied, modified, or distributed
+ * except according to those terms.
+ */
+
+@import "normalize.css";
+
+* {
+  -webkit-box-sizing: border-box;
+     -moz-box-sizing: border-box;
+          box-sizing: border-box;
+}
+
+/* Fonts */
+
+body {
+    font: 13px Arial, sans-serif;
+    line-height: 165%;
+}
+
+h1, .sidebar .location {
+    font: 700 22px "Oswald", Arial, sans-serif;
+}
+
+h2, h3, h4 {
+    font: 700 16px "Oswald", Arial, sans-serif;
+    text-transform: uppercase;
+}
+
+h2 code, h3 code, h4 code {
+    text-transform: none;
+    font-size: 1.2em;
+}
+
+code, pre, h1.fqn {
+    font: 15px "Inconsolata", "Consolas", "Courier New", monospace;
+}
+h1.fqn {
+    font-size: 26px;
+    font-weight: normal;
+}
+
+nav {
+    font: 700 26px "Oswald", Arial, sans-serif;
+    text-transform: uppercase;
+}
+
+nav.sub {
+    padding-top: 20px;
+    font: 700 16px "Oswald", Arial, sans-serif;
+    text-transform: uppercase;
+    text-align: right;
+}
+
+/* General structure */
+
+html, body {
+    min-height: 100%;
+    height: 100%;
+}
+
+body {
+    position: relative;
+    height: auto;
+    padding-bottom: 20px;
+}
+
+.sidebar {
+    width: 200px;
+    position: absolute;
+    left: 0;
+    top: 0;
+    min-height: 100%;
+}
+
+.content, nav { max-width: 960px; }
+
+/* Everything else */
+
+.js-only, .hidden { display: none; }
+
+.sidebar {
+    background: #e9e9e9;
+    padding: 10px;
+}
+
+.sidebar img {
+    margin: 20px auto;
+    display: block;
+}
+
+.sidebar .location { margin-bottom: 10px; }
+.sidebar .block, pre { background: #fff; }
+.sidebar .block, pre, .content { border-bottom: 2px solid black; }
+.trait { border-color: #fcae2b !important; }
+.mod { border-color: #809fc7 !important; }
+.enum { border-color: #93bc99 !important; }
+.struct { border-color: #e53700 !important; }
+.fn { border-color: #a2777f !important; }
+
+.block {
+    padding: 10px;
+    margin-bottom: 10px;
+}
+.block h2 { margin-top: 0; }
+
+.content {
+    background: #f3f3f3;
+    padding: 20px 20px 20px 40px;
+}
+.content h1 { margin-top: 0; }
+.content h1, .content h2 { margin-left: -20px; }
+.content pre { padding: 20px; }
+
+.content .highlighted {
+    cursor: pointer;
+    color: #000 !important;
+    background-color: #ccc;
+}
+.content .highlighted a { color: #000 !important; }
+.content .highlighted.trait { background-color: #fece7e; }
+.content .highlighted.mod { background-color: #afc6e4; }
+.content .highlighted.enum { background-color: #b4d1b9; }
+.content .highlighted.struct { background-color: #e7b1a0; }
+.content .highlighted.fn { background-color: #c6afb3; }
+
+.docblock.short.nowrap {
+    display: block;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+.docblock.short p {
+    overflow: hidden;
+    text-overflow: ellipsis;
+    margin: 0;
+}
+
+.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
+    margin-left: 0;
+}
+
+.docblock h1 { font-size: 1.1em; }
+.docblock h2 { font-size: 1.05em; }
+.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
+
+.content .source { float: right; }
+.content table {
+    border-spacing: 0 5px;
+    border-collapse: separate;
+}
+.content td { vertical-align: top; }
+.content td:first-child { padding-right: 20px; }
+.content td p:first-child { margin-top: 0; }
+.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
+
+.content .item-list {
+    list-style-type: none;
+    padding: 0;
+}
+
+.content .item-list li { margin-bottom: 3px; }
+
+.content .multi-column {
+    -moz-column-count: 5;
+    -moz-column-gap: 2.5em;
+    -webkit-column-count: 5;
+    -webkit-column-gap: 2.5em;
+    column-count: 5;
+    column-gap: 2.5em;
+}
+.content .multi-column li { width: 100%; display: inline-block; }
+
+.content .method { font-size: 1em; }
+.content .methods { margin-left: 20px; }
+.content .methods .docblock { margin-left: 20px; }
+
+nav {
+    border-bottom: 1px solid #e0e0e0;
+    padding-bottom: 10px;
+    margin-bottom: 10px;
+}
+nav.main {
+    padding: 20px 0;
+    text-align: center;
+}
+nav.main .current {
+    border-top: 1px solid #000;
+    border-bottom: 1px solid #000;
+}
+nav.main .separator {
+    border: 1px solid #000;
+    display: inline-block;
+    height: 23px;
+    margin: 0 20px;
+}
+nav.sum { text-align: right; }
+nav.sub form { display: inline; }
+
+nav, .content {
+    margin-left: 220px;
+    margin-right: 20px;
+}
+
+a {
+    text-decoration: none;
+    color: #000;
+}
+
+.content a, .block a.current { font-weight: bold; }
+
+.content a.trait, .block a.current.trait { color: #ed9603; }
+.content a.mod, .block a.current.mod { color: #4d76ae; }
+.content a.enum, .block a.current.enum { color: #5e9766; }
+.content a.struct, .block a.current.struct { color: #e53700; }
+.content a.fn, .block a.current.fn { color: #8c6067; }
+
+.search-input {
+    border: 2px solid #f2f2f2;
+    border-radius: 2px;
+    width: 350px;
+}
+.search-results .desc {
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    display: block;
+}
+
+#help {
+    background: #e9e9e9;
+    border-radius: 4px;
+    box-shadow: 0 0 6px rgba(0,0,0,.2);
+
+    position: absolute;
+    top: 300px;
+    left: 50%;
+    margin-top: -125px;
+    margin-left: -275px;
+    width: 550px;
+    height: 250px;
+    border: 1px solid #bfbfbf;
+}
+
+#help dt {
+    float: left;
+    border-radius: 3px;
+    border: 1px solid #bfbfbf;
+    background: #fff;
+    width: 23px;
+    text-align: center;
+    clear: left;
+    display: block;
+    margin-top: -1px;
+}
+#help dd { margin: 5px 33px; }
+#help .infos { padding-left: 0; }
+#help h1 { margin-top: 0; }
+#help div {
+    width: 50%;
+    float: left;
+    padding: 20px;
+}
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
new file mode 100644 (file)
index 0000000..b5ae3da
--- /dev/null
@@ -0,0 +1,420 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*jslint browser: true, es5: true */
+/*globals $: true, searchIndex: true, rootPath: true, allPaths: true */
+
+(function () {
+    "use strict";
+    var resizeTimeout, interval;
+
+    $('.js-only').removeClass('js-only');
+
+    function resizeShortBlocks() {
+        if (resizeTimeout) {
+            clearTimeout(resizeTimeout);
+        }
+        resizeTimeout = setTimeout(function () {
+            var contentWidth = $('.content').width();
+            $('.docblock.short').width(function () {
+                return contentWidth - 40 - $(this).prev().width();
+            }).addClass('nowrap');
+        }, 150);
+    }
+    resizeShortBlocks();
+    $(window).on('resize', resizeShortBlocks);
+
+    $(document).on('keyup', function (e) {
+        if (document.activeElement.tagName === 'INPUT') {
+            return;
+        }
+
+        if (e.keyCode === 188 && $('#help').hasClass('hidden')) { // question mark
+            e.preventDefault();
+            $('#help').removeClass('hidden');
+        } else if (e.keyCode === 27 && !$('#help').hasClass('hidden')) { // esc
+            e.preventDefault();
+            $('#help').addClass('hidden');
+        } else if (e.keyCode === 83) { // S
+            e.preventDefault();
+            $('.search-input').focus();
+        }
+    }).on('click', function (e) {
+        if (!$(e.target).closest('#help').length) {
+            $('#help').addClass('hidden');
+        }
+    });
+
+    $('.version-selector').on('change', function () {
+        var i, match,
+            url = document.location.href,
+            stripped = '',
+            len = rootPath.match(/\.\.\//g).length + 1;
+
+        for (i = 0; i < len; i += 1) {
+            match = url.match(/\/[^\/]*$/);
+            if (i < len - 1) {
+                stripped = match[0] + stripped;
+            }
+            url = url.substring(0, url.length - match[0].length);
+        }
+
+        url += '/' + $('.version-selector').val() + stripped;
+
+        document.location.href = url;
+    });
+
+    function initSearch(searchIndex) {
+        var currentResults, index;
+
+        // clear cached values from the search bar
+        $(".search-input")[0].value = '';
+
+        function execQuery(query, max, searchWords) {
+            var valLower = query.query.toLowerCase(),
+                val = valLower,
+                typeFilter = query.type,
+                results = [],
+                aa = 0,
+                bb = 0;
+
+            // quoted values mean literal search
+            bb = searchWords.length;
+            if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && val.charAt(val.length - 1) === val.charAt(0)) {
+                val = val.substr(1, val.length - 2);
+                for (aa = 0; aa < bb; aa += 1) {
+                    if (searchWords[aa] === val) {
+                        // filter type: ... queries
+                        if (!typeFilter || typeFilter === searchIndex[aa].ty) {
+                            results.push([aa, -1]);
+                        }
+                    }
+                    if (results.length === max) {
+                        break;
+                    }
+                }
+            } else {
+                // gather matching search results up to a certain maximum
+                val = val.replace(/\_/g, "");
+                for (aa = 0; aa < bb; aa += 1) {
+                    if (searchWords[aa].indexOf(val) > -1 || searchWords[aa].replace(/_/g, "").indexOf(val) > -1) {
+                        // filter type: ... queries
+                        if (!typeFilter || typeFilter === searchIndex[aa].ty) {
+                            results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
+                        }
+                    }
+                    if (results.length === max) {
+                        break;
+                    }
+                }
+            }
+            bb = results.length;
+            for (aa = 0; aa < bb; aa += 1) {
+                results[aa].push(searchIndex[results[aa][0]].ty);
+            }
+            for (aa = 0; aa < bb; aa += 1) {
+                results[aa].push(searchIndex[results[aa][0]].path);
+            }
+
+            // if there are no results then return to default and fail
+            if (results.length === 0) {
+                return [];
+            }
+
+            // sort by exact match
+            results.sort(function search_complete_sort0(aaa, bbb) {
+                if (searchWords[aaa[0]] === valLower && searchWords[bbb[0]] !== valLower) {
+                    return 1;
+                }
+            });
+            // first sorting attempt
+            // sort by item name length
+            results.sort(function search_complete_sort1(aaa, bbb) {
+                if (searchWords[aaa[0]].length > searchWords[bbb[0]].length) {
+                    return 1;
+                }
+            });
+            // second sorting attempt
+            // sort by item name
+            results.sort(function search_complete_sort1(aaa, bbb) {
+                if (searchWords[aaa[0]].length === searchWords[bbb[0]].length && searchWords[aaa[0]] > searchWords[bbb[0]]) {
+                    return 1;
+                }
+            });
+            // third sorting attempt
+            // sort by index of keyword in item name
+            if (results[0][1] !== -1) {
+                results.sort(function search_complete_sort1(aaa, bbb) {
+                    if (aaa[1] > bbb[1] && bbb[1] === 0) {
+                        return 1;
+                    }
+                });
+            }
+            // fourth sorting attempt
+            // sort by type
+            results.sort(function search_complete_sort3(aaa, bbb) {
+                if (searchWords[aaa[0]] === searchWords[bbb[0]] && aaa[2] > bbb[2]) {
+                    return 1;
+                }
+            });
+            // fifth sorting attempt
+            // sort by path
+            results.sort(function search_complete_sort4(aaa, bbb) {
+                if (searchWords[aaa[0]] === searchWords[bbb[0]] && aaa[2] === bbb[2] && aaa[3] > bbb[3]) {
+                    return 1;
+                }
+            });
+            // sixth sorting attempt
+            // remove duplicates, according to the data provided
+            for (aa = results.length - 1; aa > 0; aa -= 1) {
+                if (searchWords[results[aa][0]] === searchWords[results[aa - 1][0]] && results[aa][2] === results[aa - 1][2] && results[aa][3] === results[aa - 1][3]) {
+                    results[aa][0] = -1;
+                }
+            }
+
+            return results;
+        }
+
+        function getQuery() {
+            var matches, type, query = $('.search-input').val();
+
+            matches = query.match(/^(fn|mod|str(uct)?|enum|trait|t(ype)?d(ef)?)\s*:\s*/i);
+            if (matches) {
+                type = matches[1].replace(/^td$/, 'typedef').replace(/^str$/, 'struct').replace(/^tdef$/, 'typedef').replace(/^typed$/, 'typedef');
+                query = query.substring(matches[0].length);
+            }
+
+            return {
+                query: query,
+                type: type,
+                id: query + type,
+            };
+        }
+
+        function initSearchNav() {
+            var hoverTimeout, $results = $('.search-results .result');
+
+            $results.on('click', function () {
+                document.location.href = $(this).find('a').prop('href');
+            }).on('mouseover', function () {
+                var $el = $(this);
+                clearTimeout(hoverTimeout);
+                hoverTimeout = setTimeout(function () {
+                    $results.removeClass('highlighted');
+                    $el.addClass('highlighted');
+                }, 20);
+            });
+
+            $(document).off('keyup.searchnav');
+            $(document).on('keyup.searchnav', function (e) {
+                var $active = $results.filter('.highlighted');
+
+                if (e.keyCode === 38) { // up
+                    e.preventDefault();
+                    if (!$active.length || !$active.prev()) {
+                        return;
+                    }
+
+                    $active.prev().addClass('highlighted');
+                    $active.removeClass('highlighted');
+                } else if (e.keyCode === 40) { // down
+                    e.preventDefault();
+                    if (!$active.length) {
+                        $results.first().addClass('highlighted');
+                    } else if ($active.next().length) {
+                        $active.next().addClass('highlighted');
+                        $active.removeClass('highlighted');
+                    }
+                } else if (e.keyCode === 13) { // return
+                    e.preventDefault();
+                    if ($active.length) {
+                        document.location.href = $active.find('a').prop('href');
+                    }
+                }
+            });
+        }
+
+        function showResults(results) {
+            var output, shown, query = getQuery();
+
+            currentResults = query.id;
+            output = '<h1>Results for ' + query.query + (query.type ? ' (type: ' + query.type + ')' : '') + '</h1>';
+            output += '<table class="search-results">';
+
+            if (results.length > 0) {
+                shown = [];
+
+                results.forEach(function (item) {
+                    var name, type;
+
+                    if (shown.indexOf(item) !== -1) {
+                        return;
+                    }
+
+                    shown.push(item);
+                    name = item.name;
+                    type = item.ty;
+
+                    output += '<tr class="' + type + ' result"><td>';
+
+                    if (type === 'mod') {
+                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + name + '/index.html" class="' + type + '">' + name + '</a>';
+                    } else if (type === 'static' || type === 'reexport') {
+                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/index.html" class="' + type + '">' + name + '</a>';
+                    } else if (item.parent !== undefined) {
+                        var myparent = allPaths[item.parent];
+                        output += item.path + '::' + myparent.name + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + myparent.type + '.' + myparent.name + '.html" class="' + type + '">' + name + '</a>';
+                    } else {
+                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + type + '.' + name + '.html" class="' + type + '">' + name + '</a>';
+                    }
+
+                    output += '</td><td><span class="desc">' + item.desc + '</span></td></tr>';
+                });
+            } else {
+                output += 'No results :( <a href="https://duckduckgo.com/?q=' + encodeURIComponent('rust ' + query.query) + '">Try on DuckDuckGo?</a>';
+            }
+
+            output += "</p>";
+            $('.content').html(output);
+            $('.search-results .desc').width($('.content').width() - 40 - $('.content td:first-child').first().width());
+            initSearchNav();
+        }
+
+        function search(e) {
+            var query, filterdata = [], obj, i, len,
+                results = [],
+                maxResults = 200,
+                resultIndex;
+
+            query = getQuery();
+            if (e) {
+                e.preventDefault();
+            }
+
+            if (!query.query || query.id === currentResults) {
+                return;
+            }
+
+            resultIndex = execQuery(query, 20000, index);
+            len = resultIndex.length;
+            for (i = 0; i < len; i += 1) {
+                if (resultIndex[i][0] > -1) {
+                    obj = searchIndex[resultIndex[i][0]];
+                    filterdata.push([obj.name, obj.ty, obj.path, obj.desc]);
+                    results.push(obj);
+                }
+                if (results.length >= maxResults) {
+                    break;
+                }
+            }
+
+            // TODO add sorting capability through this function?
+            //
+            //            // the handler for the table heading filtering
+            //            filterdraw = function search_complete_filterdraw(node) {
+            //                var name = "",
+            //                    arrow = "",
+            //                    op = 0,
+            //                    tbody = node.parentNode.parentNode.nextSibling,
+            //                    anchora = {},
+            //                    tra = {},
+            //                    tha = {},
+            //                    td1a = {},
+            //                    td2a = {},
+            //                    td3a = {},
+            //                    aaa = 0,
+            //                    bbb = 0;
+            //
+            //                // the 4 following conditions set the rules for each
+            //                // table heading
+            //                if (node === ths[0]) {
+            //                    op = 0;
+            //                    name = "name";
+            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
+            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
+            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
+            //                }
+            //                if (node === ths[1]) {
+            //                    op = 1;
+            //                    name = "type";
+            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
+            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
+            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
+            //                }
+            //                if (node === ths[2]) {
+            //                    op = 2;
+            //                    name = "path";
+            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
+            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
+            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
+            //                }
+            //                if (node === ths[3]) {
+            //                    op = 3;
+            //                    name = "description";
+            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
+            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
+            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
+            //                }
+            //
+            //                // ascending or descending search
+            //                arrow = node.innerHTML.split(" ")[1];
+            //                if (arrow === undefined || arrow === "\u25b2") {
+            //                    arrow = "\u25bc";
+            //                } else {
+            //                    arrow = "\u25b2";
+            //                }
+            //
+            //                // filter the data
+            //                filterdata.sort(function search_complete_filterDraw_sort(xx, yy) {
+            //                    if ((arrow === "\u25b2" && xx[op].toLowerCase() < yy[op].toLowerCase()) || (arrow === "\u25bc" && xx[op].toLowerCase() > yy[op].toLowerCase())) {
+            //                        return 1;
+            //                    }
+            //                });
+            //            };
+
+            showResults(results);
+        }
+
+        function buildIndex(searchIndex) {
+            var len = searchIndex.length,
+                i = 0,
+                searchWords = [];
+
+            // before any analysis is performed lets gather the search terms to
+            // search against apart from the rest of the data.  This is a quick
+            // operation that is cached for the life of the page state so that
+            // all other search operations have access to this cached data for
+            // faster analysis operations
+            for (i = 0; i < len; i += 1) {
+                if (typeof searchIndex[i].name === "string") {
+                    searchWords.push(searchIndex[i].name.toLowerCase());
+                } else {
+                    searchWords.push("");
+                }
+            }
+
+            return searchWords;
+        }
+
+        function startSearch() {
+            var keyUpTimeout;
+            $('.do-search').on('click', search);
+            $('.search-input').on('keyup', function () {
+                clearTimeout(keyUpTimeout);
+                keyUpTimeout = setTimeout(search, 100);
+            });
+        }
+
+        index = buildIndex(searchIndex);
+        startSearch();
+    }
+
+    initSearch(searchIndex);
+}());
diff --git a/src/librustdoc/html/static/normalize.css b/src/librustdoc/html/static/normalize.css
new file mode 100644 (file)
index 0000000..6adf56e
--- /dev/null
@@ -0,0 +1,396 @@
+/*! normalize.css v2.1.2 | 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 styling not present in IE 8/9.
+ */
+
+[hidden] {
+    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
+   ========================================================================== */
+
+/**
+ * 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.
+ * 2. Remove excess padding in IE 8/9.
+ */
+
+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/src/librustdoc/markdown_index_pass.rs b/src/librustdoc/markdown_index_pass.rs
deleted file mode 100644 (file)
index 9063477..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Build indexes as appropriate for the markdown pass
-
-
-use astsrv;
-use config;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use markdown_pass;
-use markdown_writer;
-use pass::Pass;
-
-pub fn mk_pass(config: config::Config) -> Pass {
-    Pass {
-        name: ~"markdown_index",
-        f: |srv, doc| run(srv, doc, config.clone())
-    }
-}
-
-pub fn run(
-    _srv: astsrv::Srv,
-    doc: doc::Doc,
-    config: config::Config
-) -> doc::Doc {
-    let fold = Fold {
-        fold_mod: fold_mod,
-        fold_nmod: fold_nmod,
-        .. fold::default_any_fold(config)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_mod(
-    fold: &fold::Fold<config::Config>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-
-    let doc = fold::default_any_fold_mod(fold, doc);
-
-    doc::ModDoc {
-        index: Some(build_mod_index(doc.clone(), fold.ctxt.clone())),
-        .. doc
-    }
-}
-
-fn fold_nmod(
-    fold: &fold::Fold<config::Config>,
-    doc: doc::NmodDoc
-) -> doc::NmodDoc {
-
-    let doc = fold::default_any_fold_nmod(fold, doc);
-
-    doc::NmodDoc {
-        index: Some(build_nmod_index(doc.clone(), fold.ctxt.clone())),
-        .. doc
-    }
-}
-
-fn build_mod_index(
-    doc: doc::ModDoc,
-    config: config::Config
-) -> doc::Index {
-    doc::Index {
-        entries: doc.items.map(|doc| {
-            item_to_entry((*doc).clone(), &config)
-        })
-    }
-}
-
-fn build_nmod_index(
-    doc: doc::NmodDoc,
-    config: config::Config
-) -> doc::Index {
-    doc::Index {
-        entries: doc.fns.map(|doc| {
-            item_to_entry(doc::FnTag((*doc).clone()), &config)
-        })
-    }
-}
-
-fn item_to_entry(
-    doc: doc::ItemTag,
-    config: &config::Config
-) -> doc::IndexEntry {
-    let link = match doc {
-      doc::ModTag(_) | doc::NmodTag(_)
-      if config.output_style == config::DocPerMod => {
-        markdown_writer::make_filename(config,
-                                       doc::ItemPage(doc.clone())).to_str()
-      }
-      _ => {
-        ~"#" + pandoc_header_id(markdown_pass::header_text(doc.clone()))
-      }
-    };
-
-    doc::IndexEntry {
-        kind: markdown_pass::header_kind(doc.clone()),
-        name: markdown_pass::header_name(doc.clone()),
-        brief: doc.brief(),
-        link: link
-    }
-}
-
-pub fn pandoc_header_id(header: &str) -> ~str {
-
-    // http://johnmacfarlane.net/pandoc/README.html#headers
-
-    let header = remove_formatting(header);
-    let header = remove_punctuation(header);
-    let header = replace_with_hyphens(header);
-    let header = convert_to_lowercase(header);
-    let header = remove_up_to_first_letter(header);
-    let header = maybe_use_section_id(header);
-    return header;
-
-    fn remove_formatting(s: &str) -> ~str {
-        s.replace("`", "")
-    }
-    fn remove_punctuation(s: &str) -> ~str {
-        let s = s.replace("<", "");
-        let s = s.replace(">", "");
-        let s = s.replace("[", "");
-        let s = s.replace("]", "");
-        let s = s.replace("(", "");
-        let s = s.replace(")", "");
-        let s = s.replace("@~", "");
-        let s = s.replace("~", "");
-        let s = s.replace("/", "");
-        let s = s.replace(":", "");
-        let s = s.replace("&", "");
-        let s = s.replace("^", "");
-        let s = s.replace(",", "");
-        let s = s.replace("'", "");
-        let s = s.replace("+", "");
-        return s;
-    }
-    fn replace_with_hyphens(s: &str) -> ~str {
-        // Collapse sequences of whitespace to a single dash
-        // XXX: Hacky implementation here that only covers
-        // one or two spaces.
-        let s = s.trim();
-        let s = s.replace("  ", "-");
-        let s = s.replace(" ", "-");
-        return s;
-    }
-    // FIXME: #4318 Instead of to_ascii and to_str_ascii, could use
-    // to_ascii_consume and to_str_consume to not do a unnecessary copy.
-    fn convert_to_lowercase(s: &str) -> ~str { s.to_ascii().to_lower().to_str_ascii() }
-    fn remove_up_to_first_letter(s: &str) -> ~str { s.to_str() }
-    fn maybe_use_section_id(s: &str) -> ~str { s.to_str() }
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass;
-    use config;
-    use desc_to_brief_pass;
-    use doc;
-    use extract;
-    use markdown_index_pass::run;
-    use path_pass;
-    use prune_hidden_pass;
-    use super::pandoc_header_id;
-
-    fn mk_doc(output_style: config::OutputStyle, source: ~str)
-               -> doc::Doc {
-        do astsrv::from_str(source) |srv| {
-            let config = config::Config {
-                output_style: output_style,
-                .. config::default_config(&Path("whatever"))
-            };
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (prune_hidden_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (path_pass::mk_pass().f)(srv.clone(), doc);
-
-            run(srv.clone(), doc, config)
-        }
-    }
-
-    #[test]
-    fn should_remove_punctuation_from_headers() {
-        assert!(pandoc_header_id("impl foo of bar<A>") ==
-                ~"impl-foo-of-bara");
-        assert!(pandoc_header_id("impl of num::num for int")
-                == ~"impl-of-numnum-for-int");
-        assert!(pandoc_header_id("impl of num::num for int/&")
-                == ~"impl-of-numnum-for-int");
-        assert!(pandoc_header_id("impl of num::num for ^int")
-                == ~"impl-of-numnum-for-int");
-        assert!(pandoc_header_id("impl for & condvar")
-                == ~"impl-for-condvar");
-        assert!(pandoc_header_id("impl of Select<T, U> for (Left, Right)")
-                == ~"impl-of-selectt-u-for-left-right");
-        assert!(pandoc_header_id("impl of Condition<'self, T, U>")
-                == ~"impl-of-conditionself-t-u");
-        assert!(pandoc_header_id("impl of Condition<T: Clone>")
-                == ~"impl-of-conditiont-clone");
-    }
-
-    #[test]
-    fn should_trim_whitespace_after_removing_punctuation() {
-        assert_eq!(pandoc_header_id("impl foo for ()"), ~"impl-foo-for");
-    }
-
-    #[test]
-    fn should_index_mod_contents() {
-        let doc = mk_doc(
-            config::DocPerCrate,
-            ~"mod a { } fn b() { }"
-        );
-        assert!(doc.cratemod().index.unwrap().entries[0] == doc::IndexEntry {
-            kind: ~"Module",
-            name: ~"a",
-            brief: None,
-            link: ~"#module-a"
-        });
-        assert!(doc.cratemod().index.unwrap().entries[1] == doc::IndexEntry {
-            kind: ~"Function",
-            name: ~"b",
-            brief: None,
-            link: ~"#function-b"
-        });
-    }
-
-    #[test]
-    fn should_index_mod_contents_multi_page() {
-        let doc = mk_doc(
-            config::DocPerMod,
-            ~"mod a { } fn b() { }"
-        );
-        assert_eq!(doc.cratemod().index.unwrap().entries[0], doc::IndexEntry {
-            kind: ~"Module",
-            name: ~"a",
-            brief: None,
-            link: ~"a.html"
-        });
-        assert_eq!(doc.cratemod().index.unwrap().entries[1], doc::IndexEntry {
-            kind: ~"Function",
-            name: ~"b",
-            brief: None,
-            link: ~"#function-b"
-        });
-    }
-
-    #[test]
-    fn should_add_brief_desc_to_index() {
-        let doc = mk_doc(
-            config::DocPerMod,
-            ~"#[doc = \"test\"] mod a { }"
-        );
-        assert_eq!(doc.cratemod().index.unwrap().entries[0].brief, Some(~"test"));
-    }
-
-    #[test]
-    fn should_index_foreign_mod_contents() {
-        let doc = mk_doc(
-            config::DocPerCrate,
-            ~"extern { fn b(); }"
-        );
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().nmods()[0].index.unwrap().entries[0],
-                   doc::IndexEntry {
-                       kind: ~"Function",
-                       name: ~"b",
-                       brief: None,
-                       link: ~"#function-b"
-                   });
-    }
-}
diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs
deleted file mode 100644 (file)
index 7d07b48..0000000
+++ /dev/null
@@ -1,941 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Generate markdown from a document tree
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use markdown_pass;
-use markdown_writer::Writer;
-use markdown_writer::WriterUtils;
-use markdown_writer::WriterFactory;
-use pass::Pass;
-use sort_pass;
-
-use std::cell::Cell;
-use std::str;
-use std::vec;
-use syntax;
-
-pub fn mk_pass(writer_factory: WriterFactory) -> Pass {
-    let writer_factory = Cell::new(writer_factory);
-    Pass {
-        name: ~"markdown",
-        f: |srv, doc| run(srv, doc, writer_factory.take())
-    }
-}
-
-fn run(
-    srv: astsrv::Srv,
-    doc: doc::Doc,
-    writer_factory: WriterFactory
-) -> doc::Doc {
-
-    fn mods_last(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
-        fn is_mod(item: &doc::ItemTag) -> bool {
-            match *item {
-                doc::ModTag(_) => true,
-                _ => false
-            }
-        }
-
-        let lteq = !is_mod(item1) || is_mod(item2);
-        lteq
-    }
-
-    // Sort the items so mods come last. All mods will be
-    // output at the same header level so sorting mods last
-    // makes the headers come out nested correctly.
-    let sorted_doc = (sort_pass::mk_pass(
-        ~"mods last", mods_last
-    ).f)(srv, doc.clone());
-
-    write_markdown(sorted_doc, writer_factory);
-
-    return doc;
-}
-
-struct Ctxt {
-    w: Writer
-}
-
-pub fn write_markdown(
-    doc: doc::Doc,
-    writer_factory: WriterFactory
-) {
-    // There is easy parallelism to be had here, but
-    // we don't want to spawn too many pandoc processes.
-    // (See #2484, which is closed.)
-    do doc.pages.map |page| {
-        let ctxt = Ctxt {
-            w: writer_factory((*page).clone())
-        };
-        write_page(&ctxt, page)
-    };
-}
-
-fn write_page(ctxt: &Ctxt, page: &doc::Page) {
-    write_title(ctxt, (*page).clone());
-    match (*page).clone() {
-        doc::CratePage(doc) => {
-            write_crate(ctxt, doc);
-        }
-        doc::ItemPage(doc) => {
-            // We don't write a header for item's pages because their
-            // header in the html output is created by the page title
-            write_item_no_header(ctxt, doc);
-        }
-    }
-    ctxt.w.put_done();
-}
-
-fn write_title(ctxt: &Ctxt, page: doc::Page) {
-    ctxt.w.put_line(fmt!("%% %s", make_title(page)));
-    ctxt.w.put_line(~"");
-}
-
-fn make_title(page: doc::Page) -> ~str {
-    let item = match page {
-        doc::CratePage(CrateDoc) => {
-            doc::ModTag(CrateDoc.topmod.clone())
-        }
-        doc::ItemPage(ItemTag) => {
-            ItemTag
-        }
-    };
-    let title = markdown_pass::header_text(item);
-    let title = title.replace("`", "");
-    return title;
-}
-
-enum Hlvl {
-    H1 = 1,
-    H2 = 2,
-    H3 = 3,
-    H4 = 4
-}
-
-fn write_header(ctxt: &Ctxt, lvl: Hlvl, doc: doc::ItemTag) {
-    let text = header_text(doc);
-    write_header_(ctxt, lvl, text);
-}
-
-fn write_header_(ctxt: &Ctxt, lvl: Hlvl, title: ~str) {
-    let hashes = str::from_chars(vec::from_elem(lvl as uint, '#'));
-    ctxt.w.put_line(fmt!("%s %s", hashes, title));
-    ctxt.w.put_line(~"");
-}
-
-pub fn header_kind(doc: doc::ItemTag) -> ~str {
-    match doc {
-        doc::ModTag(_) => {
-            if doc.id() == syntax::ast::CRATE_NODE_ID {
-                ~"Crate"
-            } else {
-                ~"Module"
-            }
-        }
-        doc::NmodTag(_) => {
-            ~"Foreign module"
-        }
-        doc::FnTag(_) => {
-            ~"Function"
-        }
-        doc::StaticTag(_) => {
-            ~"Static"
-        }
-        doc::EnumTag(_) => {
-            ~"Enum"
-        }
-        doc::TraitTag(_) => {
-            ~"Trait"
-        }
-        doc::ImplTag(_) => {
-            ~"Implementation"
-        }
-        doc::TyTag(_) => {
-            ~"Type"
-        }
-        doc::StructTag(_) => {
-            ~"Struct"
-        }
-    }
-}
-
-pub fn header_name(doc: doc::ItemTag) -> ~str {
-    let fullpath = (doc.path() + &[doc.name_()]).connect("::");
-    match &doc {
-        &doc::ModTag(_) if doc.id() != syntax::ast::CRATE_NODE_ID => {
-            fullpath
-        }
-        &doc::NmodTag(_) => {
-            fullpath
-        }
-        &doc::ImplTag(ref doc) => {
-            assert!(doc.self_ty.is_some());
-            let bounds = if doc.bounds_str.is_some() {
-                fmt!(" where %s", *doc.bounds_str.get_ref())
-            } else {
-                ~""
-            };
-            let self_ty = doc.self_ty.get_ref();
-            let mut trait_part = ~"";
-            for (i, trait_type) in doc.trait_types.iter().enumerate() {
-                if i == 0 {
-                    trait_part.push_str(" of ");
-                } else {
-                    trait_part.push_str(", ");
-                }
-                trait_part.push_str(*trait_type);
-            }
-            fmt!("%s for %s%s", trait_part, *self_ty, bounds)
-        }
-        _ => {
-            doc.name_()
-        }
-    }
-}
-
-pub fn header_text(doc: doc::ItemTag) -> ~str {
-    match &doc {
-        &doc::ImplTag(ref ImplDoc) => {
-            let header_kind = header_kind(doc.clone());
-            let bounds = if ImplDoc.bounds_str.is_some() {
-                fmt!(" where `%s`", *ImplDoc.bounds_str.get_ref())
-            } else {
-                ~""
-            };
-            let desc = if ImplDoc.trait_types.is_empty() {
-                fmt!("for `%s`%s", *ImplDoc.self_ty.get_ref(), bounds)
-            } else {
-                fmt!("of `%s` for `%s`%s",
-                     ImplDoc.trait_types[0],
-                     *ImplDoc.self_ty.get_ref(),
-                     bounds)
-            };
-            return fmt!("%s %s", header_kind, desc);
-        }
-        _ => {}
-    }
-
-    header_text_(header_kind(doc.clone()),
-                 header_name(doc))
-}
-
-fn header_text_(kind: &str, name: &str) -> ~str {
-    fmt!("%s `%s`", kind, name)
-}
-
-fn write_crate(
-    ctxt: &Ctxt,
-    doc: doc::CrateDoc
-) {
-    write_top_module(ctxt, doc.topmod.clone());
-}
-
-fn write_top_module(
-    ctxt: &Ctxt,
-    ModDoc: doc::ModDoc
-) {
-    write_mod_contents(ctxt, ModDoc);
-}
-
-fn write_mod(
-    ctxt: &Ctxt,
-    ModDoc: doc::ModDoc
-) {
-    write_mod_contents(ctxt, ModDoc);
-}
-
-fn write_common(
-    ctxt: &Ctxt,
-    desc: Option<~str>,
-    sections: &[doc::Section]
-) {
-    write_desc(ctxt, desc);
-    write_sections(ctxt, sections);
-}
-
-fn write_desc(
-    ctxt: &Ctxt,
-    desc: Option<~str>
-) {
-    match desc {
-        Some(desc) => {
-            ctxt.w.put_line(desc);
-            ctxt.w.put_line(~"");
-        }
-        None => ()
-    }
-}
-
-fn write_sections(ctxt: &Ctxt, sections: &[doc::Section]) {
-    for section in sections.iter() {
-        write_section(ctxt, (*section).clone());
-    }
-}
-
-fn write_section(ctxt: &Ctxt, section: doc::Section) {
-    write_header_(ctxt, H4, section.header.clone());
-    ctxt.w.put_line(section.body.clone());
-    ctxt.w.put_line(~"");
-}
-
-fn write_mod_contents(
-    ctxt: &Ctxt,
-    doc: doc::ModDoc
-) {
-    write_common(ctxt, doc.desc(), doc.sections());
-    if doc.index.is_some() {
-        write_index(ctxt, doc.index.get_ref());
-    }
-
-    for itemTag in doc.items.iter() {
-        write_item(ctxt, (*itemTag).clone());
-    }
-}
-
-fn write_item(ctxt: &Ctxt, doc: doc::ItemTag) {
-    write_item_(ctxt, doc, true);
-}
-
-fn write_item_no_header(ctxt: &Ctxt, doc: doc::ItemTag) {
-    write_item_(ctxt, doc, false);
-}
-
-fn write_item_(ctxt: &Ctxt, doc: doc::ItemTag, write_header: bool) {
-    if write_header {
-        write_item_header(ctxt, doc.clone());
-    }
-
-    match doc {
-        doc::ModTag(ModDoc) => write_mod(ctxt, ModDoc),
-        doc::NmodTag(nModDoc) => write_nmod(ctxt, nModDoc),
-        doc::FnTag(FnDoc) => write_fn(ctxt, FnDoc),
-        doc::StaticTag(StaticDoc) => write_static(ctxt, StaticDoc),
-        doc::EnumTag(EnumDoc) => write_enum(ctxt, EnumDoc),
-        doc::TraitTag(TraitDoc) => write_trait(ctxt, TraitDoc),
-        doc::ImplTag(ImplDoc) => write_impl(ctxt, ImplDoc),
-        doc::TyTag(TyDoc) => write_type(ctxt, TyDoc),
-        doc::StructTag(StructDoc) => put_struct(ctxt, StructDoc),
-    }
-}
-
-fn write_item_header(ctxt: &Ctxt, doc: doc::ItemTag) {
-    write_header(ctxt, item_header_lvl(&doc), doc);
-}
-
-fn item_header_lvl(doc: &doc::ItemTag) -> Hlvl {
-    match doc {
-        &doc::ModTag(_) | &doc::NmodTag(_) => H1,
-        _ => H2
-    }
-}
-
-fn write_index(ctxt: &Ctxt, index: &doc::Index) {
-    if index.entries.is_empty() {
-        return;
-    }
-
-    ctxt.w.put_line(~"<div class='index'>");
-    ctxt.w.put_line(~"");
-
-    for entry in index.entries.iter() {
-        let header = header_text_(entry.kind, entry.name);
-        let id = entry.link.clone();
-        if entry.brief.is_some() {
-            ctxt.w.put_line(fmt!("* [%s](%s) - %s",
-                                 header, id, *entry.brief.get_ref()));
-        } else {
-            ctxt.w.put_line(fmt!("* [%s](%s)", header, id));
-        }
-    }
-    ctxt.w.put_line(~"");
-    ctxt.w.put_line(~"</div>");
-    ctxt.w.put_line(~"");
-}
-
-fn write_nmod(ctxt: &Ctxt, doc: doc::NmodDoc) {
-    write_common(ctxt, doc.desc(), doc.sections());
-    if doc.index.is_some() {
-        write_index(ctxt, doc.index.get_ref());
-    }
-
-    for FnDoc in doc.fns.iter() {
-        write_item_header(ctxt, doc::FnTag((*FnDoc).clone()));
-        write_fn(ctxt, (*FnDoc).clone());
-    }
-}
-
-fn write_fn(
-    ctxt: &Ctxt,
-    doc: doc::FnDoc
-) {
-    write_fnlike(ctxt, doc.sig.clone(), doc.desc(), doc.sections());
-}
-
-fn write_fnlike(
-    ctxt: &Ctxt,
-    sig: Option<~str>,
-    desc: Option<~str>,
-    sections: &[doc::Section]
-) {
-    write_sig(ctxt, sig);
-    write_common(ctxt, desc, sections);
-}
-
-fn write_sig(ctxt: &Ctxt, sig: Option<~str>) {
-    match sig {
-        Some(sig) => {
-            ctxt.w.put_line(code_block(sig));
-            ctxt.w.put_line(~"");
-        }
-        None => fail!("unimplemented")
-    }
-}
-
-fn code_block(s: ~str) -> ~str {
-    fmt!("~~~ {.rust}
-%s
-~~~", s)
-}
-
-fn write_static(
-    ctxt: &Ctxt,
-    doc: doc::StaticDoc
-) {
-    write_sig(ctxt, doc.sig.clone());
-    write_common(ctxt, doc.desc(), doc.sections());
-}
-
-fn write_enum(
-    ctxt: &Ctxt,
-    doc: doc::EnumDoc
-) {
-    write_common(ctxt, doc.desc(), doc.sections());
-    write_variants(ctxt, doc.variants);
-}
-
-fn write_variants(
-    ctxt: &Ctxt,
-    docs: &[doc::VariantDoc]
-) {
-    if docs.is_empty() {
-        return;
-    }
-
-    write_header_(ctxt, H4, ~"Variants");
-
-    for variant in docs.iter() {
-        write_variant(ctxt, (*variant).clone());
-    }
-
-    ctxt.w.put_line(~"");
-}
-
-fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) {
-    assert!(doc.sig.is_some());
-    let sig = doc.sig.get_ref();
-
-    // space out list items so they all end up within paragraph elements
-    ctxt.w.put_line(~"");
-
-    match doc.desc.clone() {
-        Some(desc) => {
-            ctxt.w.put_line(list_item_indent(fmt!("* `%s` - %s", *sig, desc)));
-        }
-        None => {
-            ctxt.w.put_line(fmt!("* `%s`", *sig));
-        }
-    }
-}
-
-fn list_item_indent(item: &str) -> ~str {
-    let indented = item.any_line_iter().collect::<~[&str]>();
-
-    // separate markdown elements within `*` lists must be indented by four
-    // spaces, or they will escape the list context. indenting everything
-    // seems fine though.
-    indented.connect("\n    ")
-}
-
-fn write_trait(ctxt: &Ctxt, doc: doc::TraitDoc) {
-    write_common(ctxt, doc.desc(), doc.sections());
-    write_methods(ctxt, doc.methods);
-}
-
-fn write_methods(ctxt: &Ctxt, docs: &[doc::MethodDoc]) {
-    for doc in docs.iter() {
-        write_method(ctxt, (*doc).clone());
-    }
-}
-
-fn write_method(ctxt: &Ctxt, doc: doc::MethodDoc) {
-    write_header_(ctxt, H3, header_text_("Method", doc.name));
-    write_fnlike(ctxt, doc.sig.clone(), doc.desc.clone(), doc.sections);
-}
-
-fn write_impl(ctxt: &Ctxt, doc: doc::ImplDoc) {
-    write_common(ctxt, doc.desc(), doc.sections());
-    write_methods(ctxt, doc.methods);
-}
-
-fn write_type(
-    ctxt: &Ctxt,
-    doc: doc::TyDoc
-) {
-    write_sig(ctxt, doc.sig.clone());
-    write_common(ctxt, doc.desc(), doc.sections());
-}
-
-fn put_struct(
-    ctxt: &Ctxt,
-    doc: doc::StructDoc
-) {
-    write_sig(ctxt, doc.sig.clone());
-    write_common(ctxt, doc.desc(), doc.sections());
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass;
-    use config;
-    use desc_to_brief_pass;
-    use doc;
-    use extract;
-    use markdown_index_pass;
-    use markdown_pass::{mk_pass, write_markdown};
-    use markdown_writer;
-    use path_pass;
-    use page_pass;
-    use prune_hidden_pass;
-    use sectionalize_pass;
-    use trim_pass;
-    use tystr_pass;
-    use unindent_pass;
-
-    fn render(source: ~str) -> ~str {
-        let (srv, doc) = create_doc_srv(source);
-        let markdown = write_markdown_str_srv(srv, doc);
-        debug!("markdown: %s", markdown);
-        markdown
-    }
-
-    fn create_doc_srv(source: ~str) -> (astsrv::Srv, doc::Doc) {
-        do astsrv::from_str(source) |srv| {
-
-            let config = config::Config {
-                output_style: config::DocPerCrate,
-                .. config::default_config(&Path("whatever"))
-            };
-
-            let doc = extract::from_srv(srv.clone(), ~"");
-            debug!("doc (extract): %?", doc);
-            let doc = (tystr_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (tystr): %?", doc);
-            let doc = (path_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (path): %?", doc);
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (attr): %?", doc);
-            let doc = (prune_hidden_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (prune_hidden): %?", doc);
-            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (desc_to_brief): %?", doc);
-            let doc = (unindent_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (unindent): %?", doc);
-            let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (trim): %?", doc);
-            let doc = (trim_pass::mk_pass().f)(srv.clone(), doc);
-            debug!("doc (sectionalize): %?", doc);
-            let doc = (markdown_index_pass::mk_pass(config).f)(
-                srv.clone(), doc);
-            debug!("doc (index): %?", doc);
-            (srv.clone(), doc)
-        }
-    }
-
-    fn create_doc(source: ~str) -> doc::Doc {
-        let (_, doc) = create_doc_srv(source);
-        doc
-    }
-
-    fn write_markdown_str(
-        doc: doc::Doc
-    ) -> ~str {
-        let (writer_factory, po) = markdown_writer::future_writer_factory();
-        write_markdown(doc, writer_factory);
-        return po.recv().second();
-    }
-
-    fn write_markdown_str_srv(
-        srv: astsrv::Srv,
-        doc: doc::Doc
-    ) -> ~str {
-        let (writer_factory, po) = markdown_writer::future_writer_factory();
-        let pass = mk_pass(writer_factory);
-        (pass.f)(srv, doc);
-        return po.recv().second();
-    }
-
-    #[test]
-    fn write_markdown_should_write_mod_headers() {
-        let markdown = render(~"mod moo { }");
-        assert!(markdown.contains("# Module `moo`"));
-    }
-
-    #[test]
-    fn should_leave_blank_line_after_header() {
-        let markdown = render(~"mod morp { }");
-        assert!(markdown.contains("Module `morp`\n\n"));
-    }
-
-    #[test]
-    fn should_write_modules_last() {
-        /*
-        Because the markdown pass writes all modules at the same level of
-        indentation (it doesn't 'nest' them), we need to make sure that we
-        write all of the modules contained in each module after all other
-        types of items, or else the header nesting will end up wrong, with
-        modules appearing to contain items that they do not.
-        */
-        let markdown = render(
-            ~"mod a { }\
-              fn b() { }\
-              mod c {
-}\
-              fn d() { }"
-        );
-
-        let idx_a = markdown.find_str("# Module `a`").unwrap();
-        let idx_b = markdown.find_str("## Function `b`").unwrap();
-        let idx_c = markdown.find_str("# Module `c`").unwrap();
-        let idx_d = markdown.find_str("## Function `d`").unwrap();
-
-        assert!(idx_b < idx_d);
-        assert!(idx_d < idx_a);
-        assert!(idx_a < idx_c);
-    }
-
-    #[test]
-    fn should_request_new_writer_for_each_page() {
-        // This port will send us a (page, str) pair for every writer
-        // that was created
-        let (writer_factory, po) = markdown_writer::future_writer_factory();
-        let (srv, doc) = create_doc_srv(~"mod a { }");
-        // Split the document up into pages
-        let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
-        write_markdown(doc, writer_factory);
-        // We expect two pages to have been written
-        for _ in range(0, 2u) {
-            po.recv();
-        }
-    }
-
-    #[test]
-    fn should_write_title_for_each_page() {
-        let (writer_factory, po) = markdown_writer::future_writer_factory();
-        let (srv, doc) = create_doc_srv(
-            ~"#[link(name = \"core\")]; mod a { }");
-        let doc = (page_pass::mk_pass(config::DocPerMod).f)(srv, doc);
-        write_markdown(doc, writer_factory);
-        for _ in range(0, 2u) {
-            let (page, markdown) = po.recv();
-            match page {
-                doc::CratePage(_) => {
-                    assert!(markdown.contains("% Crate core"));
-                }
-                doc::ItemPage(_) => {
-                    assert!(markdown.contains("% Module a"));
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn should_write_full_path_to_mod() {
-        let markdown = render(~"mod a { mod b { mod c { } } }");
-        assert!(markdown.contains("# Module `a::b::c`"));
-    }
-
-    #[test]
-    fn should_write_sections() {
-        let markdown = render(
-            ~"#[doc = \"\
-              # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert!(markdown.contains("#### Header\n\nBody\n\n"));
-    }
-
-    #[test]
-    fn should_write_crate_description() {
-        let markdown = render(~"#[doc = \"this is the crate\"];");
-        assert!(markdown.contains("this is the crate"));
-    }
-
-
-    #[test]
-    fn should_write_index() {
-        let markdown = render(~"mod a { } mod b { }");
-        assert!(markdown.contains(
-            "\n\n* [Module `a`](#module-a)\n\
-             * [Module `b`](#module-b)\n\n"
-        ));
-    }
-
-    #[test]
-    fn should_write_index_brief() {
-        let markdown = render(~"#[doc = \"test\"] mod a { }");
-        assert!(markdown.contains("(#module-a) - test\n"));
-    }
-
-    #[test]
-    fn should_not_write_index_if_no_entries() {
-        let markdown = render(~"");
-        assert!(!markdown.contains("\n\n\n"));
-    }
-
-    #[test]
-    fn should_write_index_for_foreign_mods() {
-        let markdown = render(~"extern { fn a(); }");
-        assert!(markdown.contains(
-            "\n\n* [Function `a`](#function-a)\n\n"
-        ));
-    }
-
-    #[test]
-    fn should_write_foreign_fns() {
-        let markdown = render(
-            ~"extern { #[doc = \"test\"] fn a(); }");
-        assert!(markdown.contains("test"));
-    }
-
-    #[test]
-    fn should_write_foreign_fn_headers() {
-        let markdown = render(
-            ~"extern { #[doc = \"test\"] fn a(); }");
-        assert!(markdown.contains("## Function `a`"));
-    }
-
-    #[test]
-    fn write_markdown_should_write_function_header() {
-        let markdown = render(~"fn func() { }");
-        assert!(markdown.contains("## Function `func`"));
-    }
-
-    #[test]
-    fn should_write_the_function_signature() {
-        let markdown = render(~"#[doc = \"f\"] fn a() { }");
-        assert!(markdown.contains("\n~~~ {.rust}\nfn a()\n"));
-    }
-
-    #[test]
-    fn should_insert_blank_line_after_fn_signature() {
-        let markdown = render(~"#[doc = \"f\"] fn a() { }");
-        assert!(markdown.contains("fn a()\n~~~\n\n"));
-    }
-
-    #[test]
-    fn should_correctly_bracket_fn_signature() {
-        let doc = create_doc(~"fn a() { }");
-        let doc = doc::Doc{
-            pages: ~[
-                doc::CratePage(doc::CrateDoc{
-                    topmod: doc::ModDoc{
-                        items: ~[doc::FnTag(doc::SimpleItemDoc{
-                            sig: Some(~"line 1\nline 2"),
-                            .. (doc.cratemod().fns()[0]).clone()
-                        })],
-                        .. doc.cratemod()
-                    },
-                    .. doc.CrateDoc()
-                })
-            ]
-        };
-        let markdown = write_markdown_str(doc);
-        assert!(markdown.contains("~~~ {.rust}\nline 1\nline 2\n~~~"));
-    }
-
-    #[test]
-    fn should_leave_blank_line_between_fn_header_and_sig() {
-        let markdown = render(~"fn a() { }");
-        assert!(markdown.contains("Function `a`\n\n~~~ {.rust}\nfn a()"));
-    }
-
-    #[test]
-    fn should_write_static_header() {
-        let markdown = render(~"static a: bool = true;");
-        assert!(markdown.contains("## Static `a`\n\n"));
-    }
-
-    #[test]
-    fn should_write_static_description() {
-        let markdown = render(
-            ~"#[doc = \"b\"]\
-              static a: bool = true;");
-        assert!(markdown.contains("\n\nb\n\n"));
-    }
-
-    #[test]
-    fn should_write_enum_header() {
-        let markdown = render(~"enum a { b }");
-        assert!(markdown.contains("## Enum `a`\n\n"));
-    }
-
-    #[test]
-    fn should_write_enum_description() {
-        let markdown = render(~"#[doc = \"b\"] enum a { b }");
-        assert!(markdown.contains("\n\nb\n\n"));
-    }
-
-    #[test]
-    fn should_write_variant_list() {
-        let markdown = render(
-            ~"enum a { \
-              #[doc = \"test\"] b, \
-              #[doc = \"test\"] c }");
-        assert!(markdown.contains(
-            "\n\n#### Variants\n\
-             \n\
-             \n* `b` - test\
-             \n\
-             \n* `c` - test\n\n"));
-    }
-
-    #[test]
-    fn should_write_variant_list_without_descs() {
-        let markdown = render(~"enum a { b, c }");
-        assert!(markdown.contains(
-            "\n\n#### Variants\n\
-             \n\
-             \n* `b`\
-             \n\
-             \n* `c`\n\n"));
-    }
-
-    #[test]
-    fn should_write_variant_list_with_indent() {
-        let markdown = render(
-            ~"enum a { #[doc = \"line 1\\n\\nline 2\"] b, c }");
-        assert!(markdown.contains(
-            "\n\n#### Variants\n\
-             \n\
-             \n* `b` - line 1\
-             \n    \
-             \n    line 2\
-             \n\
-             \n* `c`\n\n"));
-    }
-
-    #[test]
-    fn should_write_variant_list_with_signatures() {
-        let markdown = render(~"enum a { b(int), #[doc = \"a\"] c(int) }");
-        assert!(markdown.contains(
-            "\n\n#### Variants\n\
-             \n\
-             \n* `b(int)`\
-             \n\
-             \n* `c(int)` - a\n\n"));
-    }
-
-    #[test]
-    fn should_write_trait_header() {
-        let markdown = render(~"trait i { fn a(); }");
-        assert!(markdown.contains("## Trait `i`"));
-    }
-
-    #[test]
-    fn should_write_trait_desc() {
-        let markdown = render(~"#[doc = \"desc\"] trait i { fn a(); }");
-        assert!(markdown.contains("desc"));
-    }
-
-    #[test]
-    fn should_write_trait_method_header() {
-        let markdown = render(~"trait i { fn a(); }");
-        assert!(markdown.contains("### Method `a`"));
-    }
-
-    #[test]
-    fn should_write_trait_method_signature() {
-        let markdown = render(~"trait i { fn a(&self); }");
-        assert!(markdown.contains("\n~~~ {.rust}\nfn a(&self)"));
-    }
-
-    #[test]
-    fn should_write_impl_header() {
-        let markdown = render(~"impl int { fn a() { } }");
-        assert!(markdown.contains("## Implementation for `int`"));
-    }
-
-    #[test]
-    fn should_write_impl_header_with_bounds() {
-        let markdown = render(~"impl <T> int<T> { }");
-        assert!(markdown.contains("## Implementation for `int<T>` where `<T>`"));
-    }
-
-    #[test]
-    fn should_write_impl_header_with_trait() {
-        let markdown = render(~"impl j for int { fn a() { } }");
-        assert!(markdown.contains(
-                              "## Implementation of `j` for `int`"));
-    }
-
-    #[test]
-    fn should_write_impl_desc() {
-        let markdown = render(
-            ~"#[doc = \"desc\"] impl int { fn a() { } }");
-        assert!(markdown.contains("desc"));
-    }
-
-    #[test]
-    fn should_write_impl_method_header() {
-        let markdown = render(
-            ~"impl int { fn a() { } }");
-        assert!(markdown.contains("### Method `a`"));
-    }
-
-    #[test]
-    fn should_write_impl_method_signature() {
-        let markdown = render(
-            ~"impl int { fn a(&mut self) { } }");
-        assert!(markdown.contains("~~~ {.rust}\nfn a(&mut self)"));
-    }
-
-    #[test]
-    fn should_write_type_header() {
-        let markdown = render(~"type t = int;");
-        assert!(markdown.contains("## Type `t`"));
-    }
-
-    #[test]
-    fn should_write_type_desc() {
-        let markdown = render(
-            ~"#[doc = \"desc\"] type t = int;");
-        assert!(markdown.contains("\n\ndesc\n\n"));
-    }
-
-    #[test]
-    fn should_write_type_signature() {
-        let markdown = render(~"type t = int;");
-        assert!(markdown.contains("\n\n~~~ {.rust}\ntype t = int\n~~~\n"));
-    }
-
-    #[test]
-    fn should_put_struct_header() {
-        let markdown = render(~"struct S { field: () }");
-        assert!(markdown.contains("## Struct `S`\n\n"));
-    }
-}
diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs
deleted file mode 100644 (file)
index fb58e5c..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use config;
-use doc::ItemUtils;
-use doc;
-
-use std::comm::*;
-use std::comm;
-use std::io;
-use std::result;
-use std::run;
-use std::str;
-use std::task;
-use extra::future::Future;
-
-#[deriving(Clone)]
-pub enum WriteInstr {
-    Write(~str),
-    Done
-}
-
-pub type Writer = ~fn(v: WriteInstr);
-pub type WriterFactory = ~fn(page: doc::Page) -> Writer;
-
-pub trait WriterUtils {
-    fn put_str(&self, str: ~str);
-    fn put_line(&self, str: ~str);
-    fn put_done(&self);
-}
-
-impl WriterUtils for Writer {
-    fn put_str(&self, str: ~str) {
-        (*self)(Write(str));
-    }
-
-    fn put_line(&self, str: ~str) {
-        self.put_str(str + "\n");
-    }
-
-    fn put_done(&self) {
-        (*self)(Done)
-    }
-}
-
-pub fn make_writer_factory(config: config::Config) -> WriterFactory {
-    match config.output_format {
-      config::Markdown => {
-        markdown_writer_factory(config)
-      }
-      config::PandocHtml => {
-        pandoc_writer_factory(config)
-      }
-    }
-}
-
-fn markdown_writer_factory(config: config::Config) -> WriterFactory {
-    let result: ~fn(page: doc::Page) -> Writer = |page| {
-        markdown_writer(&config, page)
-    };
-    result
-}
-
-fn pandoc_writer_factory(config: config::Config) -> WriterFactory {
-    let result: ~fn(doc::Page) -> Writer = |page| {
-        pandoc_writer(&config, page)
-    };
-    result
-}
-
-fn markdown_writer(
-    config: &config::Config,
-    page: doc::Page
-) -> Writer {
-    let filename = make_local_filename(config, page);
-    do generic_writer |markdown| {
-        write_file(&filename, markdown);
-    }
-}
-
-fn pandoc_writer(
-    config: &config::Config,
-    page: doc::Page
-) -> Writer {
-    assert!(config.pandoc_cmd.is_some());
-    let pandoc_cmd = (*config.pandoc_cmd.get_ref()).clone();
-    let filename = make_local_filename(config, page);
-
-    let pandoc_args = ~[
-        ~"--standalone",
-        ~"--section-divs",
-        ~"--from=markdown",
-        ~"--to=html",
-        ~"--css=rust.css",
-        ~"--output=" + filename.to_str()
-    ];
-
-    do generic_writer |markdown| {
-        use std::io::WriterUtil;
-
-        debug!("pandoc cmd: %s", pandoc_cmd);
-        debug!("pandoc args: %s", pandoc_args.connect(" "));
-
-        let mut proc = run::Process::new(pandoc_cmd, pandoc_args, run::ProcessOptions::new());
-
-        proc.input().write_str(markdown);
-        let output = proc.finish_with_output();
-
-        debug!("pandoc result: %i", output.status);
-        if output.status != 0 {
-            error!("pandoc-out: %s", str::from_utf8(output.output));
-            error!("pandoc-err: %s", str::from_utf8(output.error));
-            fail!("pandoc failed");
-        }
-    }
-}
-
-fn generic_writer(process: ~fn(markdown: ~str)) -> Writer {
-    let (po, ch) = stream::<WriteInstr>();
-    do task::spawn || {
-        let mut markdown = ~"";
-        let mut keep_going = true;
-        while keep_going {
-            match po.recv() {
-              Write(s) => markdown.push_str(s),
-              Done => keep_going = false
-            }
-        }
-        process(markdown);
-    };
-    let result: ~fn(instr: WriteInstr) = |instr| ch.send(instr);
-    result
-}
-
-pub fn make_local_filename(
-    config: &config::Config,
-    page: doc::Page
-) -> Path {
-    let filename = make_filename(config, page);
-    config.output_dir.push_rel(&filename)
-}
-
-pub fn make_filename(
-    config: &config::Config,
-    page: doc::Page
-) -> Path {
-    let filename = {
-        match page {
-          doc::CratePage(doc) => {
-            if config.output_format == config::PandocHtml &&
-                config.output_style == config::DocPerMod {
-                ~"index"
-            } else {
-                assert!(doc.topmod.name_() != ~"");
-                doc.topmod.name_()
-            }
-          }
-          doc::ItemPage(doc) => {
-            (doc.path() + &[doc.name_()]).connect("_")
-          }
-        }
-    };
-    let ext = match config.output_format {
-      config::Markdown => ~"md",
-      config::PandocHtml => ~"html"
-    };
-
-    Path(filename).with_filetype(ext)
-}
-
-fn write_file(path: &Path, s: ~str) {
-    use std::io::WriterUtil;
-
-    match io::file_writer(path, [io::Create, io::Truncate]) {
-      result::Ok(writer) => {
-        writer.write_str(s);
-      }
-      result::Err(e) => fail!(e)
-    }
-}
-
-pub fn future_writer_factory(
-) -> (WriterFactory, Port<(doc::Page, ~str)>) {
-    let (markdown_po, markdown_ch) = stream();
-    let markdown_ch = SharedChan::new(markdown_ch);
-    let writer_factory: WriterFactory = |page| {
-        let (writer_po, writer_ch) = comm::stream();
-        let markdown_ch = markdown_ch.clone();
-        do task::spawn || {
-            let (writer, future) = future_writer();
-            let mut future = future;
-            writer_ch.send(writer);
-            let s = future.get();
-            markdown_ch.send((page.clone(), s));
-        }
-        writer_po.recv()
-    };
-
-    (writer_factory, markdown_po)
-}
-
-fn future_writer() -> (Writer, Future<~str>) {
-    let (port, chan) = comm::stream();
-    let writer: ~fn(instr: WriteInstr) = |instr| chan.send(instr.clone());
-    let future = do Future::from_fn || {
-        let mut res = ~"";
-        loop {
-            match port.recv() {
-              Write(s) => res.push_str(s),
-              Done => break
-            }
-        }
-        res
-    };
-    (writer, future)
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use doc;
-    use extract;
-    use path_pass;
-    use config;
-    use super::make_local_filename;
-
-    fn mk_doc(name: ~str, source: ~str) -> doc::Doc {
-        do astsrv::from_str(source) |srv| {
-            let doc = extract::from_srv(srv.clone(), name.clone());
-            let doc = (path_pass::mk_pass().f)(srv.clone(), doc);
-            doc
-        }
-    }
-
-    #[test]
-    fn should_use_markdown_file_name_based_off_crate() {
-        let config = config::Config {
-            output_dir: Path("output/dir"),
-            output_format: config::Markdown,
-            output_style: config::DocPerCrate,
-            .. config::default_config(&Path("input/test.rc"))
-        };
-        let doc = mk_doc(~"test", ~"");
-        let page = doc::CratePage(doc.CrateDoc());
-        let filename = make_local_filename(&config, page);
-        assert_eq!(filename.to_str(), ~"output/dir/test.md");
-    }
-
-    #[test]
-    fn should_name_html_crate_file_name_index_html_when_doc_per_mod() {
-        let config = config::Config {
-            output_dir: Path("output/dir"),
-            output_format: config::PandocHtml,
-            output_style: config::DocPerMod,
-            .. config::default_config(&Path("input/test.rc"))
-        };
-        let doc = mk_doc(~"", ~"");
-        let page = doc::CratePage(doc.CrateDoc());
-        let filename = make_local_filename(&config, page);
-        assert_eq!(filename.to_str(), ~"output/dir/index.html");
-    }
-
-    #[test]
-    fn should_name_mod_file_names_by_path() {
-        let config = config::Config {
-            output_dir: Path("output/dir"),
-            output_format: config::PandocHtml,
-            output_style: config::DocPerMod,
-            .. config::default_config(&Path("input/test.rc"))
-        };
-        let doc = mk_doc(~"", ~"mod a { mod b { } }");
-        // hidden __std_macros module at the start.
-        let modb = doc.cratemod().mods()[1].mods()[0].clone();
-        let page = doc::ItemPage(doc::ModTag(modb));
-        let filename = make_local_filename(&config, page);
-        assert_eq!(filename, Path("output/dir/a_b.html"));
-    }
-}
diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs
deleted file mode 100644 (file)
index 342c949..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Divides the document tree into pages.
-
-Each page corresponds is a logical section. There may be pages for
-individual modules, pages for the crate, indexes, etc.
-*/
-
-
-use astsrv;
-use config;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-use std::comm::*;
-use std::task;
-use syntax::ast;
-
-#[cfg(test)] use doc::PageUtils;
-
-pub fn mk_pass(output_style: config::OutputStyle) -> Pass {
-    Pass {
-        name: ~"page",
-        f: |srv, doc| run(srv, doc, output_style)
-    }
-}
-
-pub fn run(
-    _srv: astsrv::Srv,
-    doc: doc::Doc,
-    output_style: config::OutputStyle
-) -> doc::Doc {
-
-    if output_style == config::DocPerCrate {
-        return doc;
-    }
-
-    let (result_port, result_chan) = stream();
-    let (page_port, page_chan) = stream();
-    let page_chan = SharedChan::new(page_chan);
-    do task::spawn {
-        result_chan.send(make_doc_from_pages(&page_port));
-    };
-
-    find_pages(doc, page_chan);
-    result_port.recv()
-}
-
-type PagePort = Port<Option<doc::Page>>;
-type PageChan = SharedChan<Option<doc::Page>>;
-
-fn make_doc_from_pages(page_port: &PagePort) -> doc::Doc {
-    let mut pages = ~[];
-    loop {
-        let val = page_port.recv();
-        if val.is_some() {
-            pages.push(val.unwrap());
-        } else {
-            break;
-        }
-    }
-    doc::Doc {
-        pages: pages
-    }
-}
-
-fn find_pages(doc: doc::Doc, page_chan: PageChan) {
-    let fold = Fold {
-        ctxt: page_chan.clone(),
-        fold_crate: fold_crate,
-        fold_mod: fold_mod,
-        fold_nmod: fold_nmod,
-        .. fold::default_any_fold(page_chan.clone())
-    };
-    (fold.fold_doc)(&fold, doc.clone());
-
-    page_chan.send(None);
-}
-
-fn fold_crate(fold: &fold::Fold<PageChan>, doc: doc::CrateDoc)
-              -> doc::CrateDoc {
-    let doc = fold::default_seq_fold_crate(fold, doc);
-
-    let page = doc::CratePage(doc::CrateDoc {
-        topmod: strip_mod(doc.topmod.clone()),
-        .. doc.clone()
-    });
-
-    fold.ctxt.send(Some(page));
-
-    doc
-}
-
-fn fold_mod(fold: &fold::Fold<PageChan>, doc: doc::ModDoc) -> doc::ModDoc {
-    let doc = fold::default_any_fold_mod(fold, doc);
-
-    if doc.id() != ast::CRATE_NODE_ID {
-
-        let doc = strip_mod(doc.clone());
-        let page = doc::ItemPage(doc::ModTag(doc));
-        fold.ctxt.send(Some(page));
-    }
-
-    doc
-}
-
-fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc {
-    doc::ModDoc {
-        items: do doc.items.iter().filter |item| {
-            match **item {
-              doc::ModTag(_) | doc::NmodTag(_) => false,
-              _ => true
-            }
-        }.map(|x| (*x).clone()).collect::<~[doc::ItemTag]>(),
-        .. doc.clone()
-    }
-}
-
-fn fold_nmod(fold: &fold::Fold<PageChan>, doc: doc::NmodDoc) -> doc::NmodDoc {
-    let doc = fold::default_seq_fold_nmod(fold, doc);
-    let page = doc::ItemPage(doc::NmodTag(doc.clone()));
-    fold.ctxt.send(Some(page));
-    return doc;
-}
-
-#[cfg(test)]
-mod test {
-    use astsrv;
-    use config;
-    use attr_pass;
-    use doc;
-    use extract;
-    use prune_hidden_pass;
-    use page_pass::run;
-
-    fn mk_doc_(
-        output_style: config::OutputStyle,
-        source: ~str
-    ) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (prune_hidden_pass::mk_pass().f)(srv.clone(), doc);
-            run(srv.clone(), doc, output_style)
-        }
-    }
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        mk_doc_(config::DocPerMod, source.clone())
-    }
-
-    #[test]
-    fn should_not_split_the_doc_into_pages_for_doc_per_crate() {
-        let doc = mk_doc_(
-            config::DocPerCrate,
-            ~"mod a { } mod b { mod c { } }"
-        );
-        assert_eq!(doc.pages.len(), 1u);
-    }
-
-    #[test]
-    fn should_make_a_page_for_every_mod() {
-        let doc = mk_doc(~"mod a { }");
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.pages.mods()[0].name_(), ~"a");
-    }
-
-    #[test]
-    fn should_remove_mods_from_containing_mods() {
-        let doc = mk_doc(~"mod a { }");
-        assert!(doc.cratemod().mods().is_empty());
-    }
-}
diff --git a/src/librustdoc/parse.rs b/src/librustdoc/parse.rs
deleted file mode 100644 (file)
index a8321dd..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! AST-parsing helpers
-
-use rustc::driver::driver;
-use rustc::driver::session;
-use syntax::ast;
-use syntax::parse;
-
-pub fn from_file(file: &Path) -> @ast::Crate {
-    parse::parse_crate_from_file(
-        file, ~[], parse::new_parse_sess(None))
-}
-
-pub fn from_str(source: @str) -> @ast::Crate {
-    parse::parse_crate_from_source_str(
-        @"-", source, ~[], parse::new_parse_sess(None))
-}
-
-pub fn from_file_sess(sess: session::Session, file: &Path) -> @ast::Crate {
-    parse::parse_crate_from_file(
-        file, cfg(sess), sess.parse_sess)
-}
-
-pub fn from_str_sess(sess: session::Session, source: @str) -> @ast::Crate {
-    parse::parse_crate_from_source_str(
-        @"-", source, cfg(sess), sess.parse_sess)
-}
-
-fn cfg(sess: session::Session) -> ast::CrateConfig {
-    driver::build_configuration(sess)
-}
-
diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs
deleted file mode 100644 (file)
index aadc1b3..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-
-use astsrv;
-use doc;
-use time;
-
-#[cfg(test)] use extract;
-
-/// A single operation on the document model
-pub struct Pass {
-    name: ~str,
-    f: @fn(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc
-}
-
-pub fn run_passes(
-    srv: astsrv::Srv,
-    doc: doc::Doc,
-    passes: ~[Pass]
-) -> doc::Doc {
-    let mut passno = 0;
-    do passes.iter().fold(doc) |doc, pass| {
-        debug!("pass #%d", passno);
-        passno += 1;
-        do time(pass.name.clone()) {
-            (pass.f)(srv.clone(), doc.clone())
-        }
-    }
-}
-
-#[test]
-fn test_run_passes() {
-    fn pass1(
-        _srv: astsrv::Srv,
-        doc: doc::Doc
-    ) -> doc::Doc {
-        doc::Doc{
-            pages: ~[
-                doc::CratePage(doc::CrateDoc{
-                    topmod: doc::ModDoc{
-                        item: doc::ItemDoc {
-                            name: doc.cratemod().name_() + "two",
-                            .. doc.cratemod().item.clone()
-                        },
-                        items: ~[],
-                        index: None
-                    }
-                })
-            ]
-        }
-    }
-    fn pass2(
-        _srv: astsrv::Srv,
-        doc: doc::Doc
-    ) -> doc::Doc {
-        doc::Doc{
-            pages: ~[
-                doc::CratePage(doc::CrateDoc{
-                    topmod: doc::ModDoc{
-                        item: doc::ItemDoc {
-                            name: doc.cratemod().name_() + "three",
-                            .. doc.cratemod().item.clone()
-                        },
-                        items: ~[],
-                        index: None
-                    }
-                })
-            ]
-        }
-    }
-    let source = ~"";
-    do astsrv::from_str(source) |srv| {
-        let passes = ~[
-            Pass {
-                name: ~"",
-                f: pass1
-            },
-            Pass {
-                name: ~"",
-                f: pass2
-            }
-        ];
-        let doc = extract::from_srv(srv.clone(), ~"one");
-        let doc = run_passes(srv, doc, passes);
-        assert_eq!(doc.cratemod().name_(), ~"onetwothree");
-    }
-}
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
new file mode 100644 (file)
index 0000000..e580ab0
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::num;
+use std::uint;
+
+use clean;
+use syntax::ast;
+use clean::Item;
+use plugins;
+use fold;
+use fold::DocFolder;
+
+/// Strip items marked `#[doc(hidden)]`
+pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult {
+    struct Stripper;
+    impl fold::DocFolder for Stripper {
+        fn fold_item(&mut self, i: Item) -> Option<Item> {
+            for attr in i.attrs.iter() {
+                match attr {
+                    &clean::List(~"doc", ref l) => {
+                        for innerattr in l.iter() {
+                            match innerattr {
+                                &clean::Word(ref s) if "hidden" == *s => {
+                                    debug!("found one in strip_hidden; removing");
+                                    return None;
+                                },
+                                _ => (),
+                            }
+                        }
+                    },
+                    _ => ()
+                }
+            }
+            self.fold_item_recur(i)
+        }
+    }
+    let mut stripper = Stripper;
+    let crate = stripper.fold_crate(crate);
+    (crate, None)
+}
+
+pub fn unindent_comments(crate: clean::Crate) -> plugins::PluginResult {
+    struct CommentCleaner;
+    impl fold::DocFolder for CommentCleaner {
+        fn fold_item(&mut self, i: Item) -> Option<Item> {
+            let mut i = i;
+            let mut avec: ~[clean::Attribute] = ~[];
+            for attr in i.attrs.iter() {
+                match attr {
+                    &clean::NameValue(~"doc", ref s) => avec.push(
+                        clean::NameValue(~"doc", unindent(*s))),
+                    x => avec.push(x.clone())
+                }
+            }
+            i.attrs = avec;
+            self.fold_item_recur(i)
+        }
+    }
+    let mut cleaner = CommentCleaner;
+    let crate = cleaner.fold_crate(crate);
+    (crate, None)
+}
+
+pub fn collapse_privacy(crate: clean::Crate) -> plugins::PluginResult {
+    struct PrivacyCollapser {
+        stack: ~[clean::Visibility]
+    }
+    impl fold::DocFolder for PrivacyCollapser {
+        fn fold_item(&mut self, mut i: Item) -> Option<Item> {
+            if i.visibility.is_some() {
+                if i.visibility == Some(ast::inherited) {
+                    i.visibility = Some(self.stack.last().clone());
+                } else {
+                    self.stack.push(i.visibility.clone().unwrap());
+                }
+            }
+            self.fold_item_recur(i)
+        }
+    }
+    let mut privacy = PrivacyCollapser { stack: ~[] };
+    let crate = privacy.fold_crate(crate);
+    (crate, None)
+}
+
+pub fn collapse_docs(crate: clean::Crate) -> plugins::PluginResult {
+    struct Collapser;
+    impl fold::DocFolder for Collapser {
+        fn fold_item(&mut self, i: Item) -> Option<Item> {
+            let mut docstr = ~"";
+            let mut i = i;
+            for attr in i.attrs.iter() {
+                match *attr {
+                    clean::NameValue(~"doc", ref s) => {
+                        docstr.push_str(s.clone());
+                        docstr.push_char('\n');
+                    },
+                    _ => ()
+                }
+            }
+            let mut a: ~[clean::Attribute] = i.attrs.iter().filter(|&a| match a {
+                &clean::NameValue(~"doc", _) => false,
+                _ => true
+            }).map(|x| x.clone()).collect();
+            if "" != docstr {
+                a.push(clean::NameValue(~"doc", docstr.trim().to_owned()));
+            }
+            i.attrs = a;
+            self.fold_item_recur(i)
+        }
+    }
+    let mut collapser = Collapser;
+    let crate = collapser.fold_crate(crate);
+    (crate, None)
+}
+
+// n.b. this is copied from src/librustdoc/unindent_pass.rs
+pub fn unindent(s: &str) -> ~str {
+    let lines = s.any_line_iter().collect::<~[&str]>();
+    let mut saw_first_line = false;
+    let mut saw_second_line = false;
+    let min_indent = do lines.iter().fold(uint::max_value) |min_indent, line| {
+
+        // After we see the first non-whitespace line, look at
+        // the line we have. If it is not whitespace, and therefore
+        // part of the first paragraph, then ignore the indentation
+        // level of the first line
+        let ignore_previous_indents =
+            saw_first_line &&
+            !saw_second_line &&
+            !line.is_whitespace();
+
+        let min_indent = if ignore_previous_indents {
+            uint::max_value
+        } else {
+            min_indent
+        };
+
+        if saw_first_line {
+            saw_second_line = true;
+        }
+
+        if line.is_whitespace() {
+            min_indent
+        } else {
+            saw_first_line = true;
+            let mut spaces = 0;
+            do line.iter().all |char| {
+                // Only comparing against space because I wouldn't
+                // know what to do with mixed whitespace chars
+                if char == ' ' {
+                    spaces += 1;
+                    true
+                } else {
+                    false
+                }
+            };
+            num::min(min_indent, spaces)
+        }
+    };
+
+    match lines {
+        [head, .. tail] => {
+            let mut unindented = ~[ head.trim() ];
+            unindented.push_all(do tail.map |&line| {
+                if line.is_whitespace() {
+                    line
+                } else {
+                    assert!(line.len() >= min_indent);
+                    line.slice_from(min_indent)
+                }
+            });
+            unindented.connect("\n")
+        }
+        [] => s.to_owned()
+    }
+}
+
+#[cfg(test)]
+mod unindent_tests {
+    use super::unindent;
+
+    #[test]
+    fn should_unindent() {
+        let s = ~"    line1\n    line2";
+        let r = unindent(s);
+        assert_eq!(r, ~"line1\nline2");
+    }
+
+    #[test]
+    fn should_unindent_multiple_paragraphs() {
+        let s = ~"    line1\n\n    line2";
+        let r = unindent(s);
+        assert_eq!(r, ~"line1\n\nline2");
+    }
+
+    #[test]
+    fn should_leave_multiple_indent_levels() {
+        // Line 2 is indented another level beyond the
+        // base indentation and should be preserved
+        let s = ~"    line1\n\n        line2";
+        let r = unindent(s);
+        assert_eq!(r, ~"line1\n\n    line2");
+    }
+
+    #[test]
+    fn should_ignore_first_line_indent() {
+        // Thi first line of the first paragraph may not be indented as
+        // far due to the way the doc string was written:
+        //
+        // #[doc = "Start way over here
+        //          and continue here"]
+        let s = ~"line1\n    line2";
+        let r = unindent(s);
+        assert_eq!(r, ~"line1\nline2");
+    }
+
+    #[test]
+    fn should_not_ignore_first_line_indent_in_a_single_line_para() {
+        let s = ~"line1\n\n    line2";
+        let r = unindent(s);
+        assert_eq!(r, ~"line1\n\n    line2");
+    }
+}
diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs
deleted file mode 100644 (file)
index 6e6092a..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Records the full path to items
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-#[cfg(test)] use extract;
-
-use syntax::ast;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"path",
-        f: run
-    }
-}
-
-struct Ctxt {
-    srv: astsrv::Srv,
-    path: @mut ~[~str]
-}
-
-impl Clone for Ctxt {
-    fn clone(&self) -> Ctxt {
-        Ctxt {
-            srv: self.srv.clone(),
-            path: @mut (*self.path).clone()
-        }
-    }
-}
-
-fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
-    let ctxt = Ctxt {
-        srv: srv,
-        path: @mut ~[]
-    };
-    let fold = Fold {
-        ctxt: ctxt.clone(),
-        fold_item: fold_item,
-        fold_mod: fold_mod,
-        fold_nmod: fold_nmod,
-        .. fold::default_any_fold(ctxt)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_item(fold: &fold::Fold<Ctxt>, doc: doc::ItemDoc) -> doc::ItemDoc {
-    doc::ItemDoc {
-        path: (*fold.ctxt.path).clone(),
-        .. doc
-    }
-}
-
-fn fold_mod(fold: &fold::Fold<Ctxt>, doc: doc::ModDoc) -> doc::ModDoc {
-    let is_topmod = doc.id() == ast::CRATE_NODE_ID;
-
-    if !is_topmod { fold.ctxt.path.push(doc.name_()); }
-    let doc = fold::default_any_fold_mod(fold, doc);
-    if !is_topmod { fold.ctxt.path.pop(); }
-
-    doc::ModDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-fn fold_nmod(fold: &fold::Fold<Ctxt>, doc: doc::NmodDoc) -> doc::NmodDoc {
-    fold.ctxt.path.push(doc.name_());
-    let doc = fold::default_seq_fold_nmod(fold, doc);
-    fold.ctxt.path.pop();
-
-    doc::NmodDoc {
-        item: (fold.fold_item)(fold, doc.item.clone()),
-        .. doc
-    }
-}
-
-#[test]
-fn should_record_mod_paths() {
-    let source = ~"mod a { mod b { mod c { } } mod d { mod e { } } }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = run(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().mods()[1].mods()[0].mods()[0].path(),
-                   ~[~"a", ~"b"]);
-        assert_eq!(doc.cratemod().mods()[1].mods()[1].mods()[0].path(),
-                   ~[~"a", ~"d"]);
-    }
-}
-
-#[test]
-fn should_record_fn_paths() {
-    let source = ~"mod a { fn b() { } }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = run(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().mods()[1].fns()[0].path(), ~[~"a"]);
-    }
-}
diff --git a/src/librustdoc/plugins.rs b/src/librustdoc/plugins.rs
new file mode 100644 (file)
index 0000000..4bad870
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use clean;
+
+use extra;
+use dl = std::unstable::dynamic_lib;
+
+pub type PluginJson = Option<(~str, extra::json::Json)>;
+pub type PluginResult = (clean::Crate, PluginJson);
+pub type plugin_callback = extern fn (clean::Crate) -> PluginResult;
+
+/// Manages loading and running of plugins
+pub struct PluginManager {
+    priv dylibs: ~[dl::DynamicLibrary],
+    priv callbacks: ~[plugin_callback],
+    /// The directory plugins will be loaded from
+    prefix: Path,
+}
+
+impl PluginManager {
+    /// Create a new plugin manager
+    pub fn new(prefix: Path) -> PluginManager {
+        PluginManager {
+            dylibs: ~[],
+            callbacks: ~[],
+            prefix: prefix,
+        }
+    }
+
+    /// Load a plugin with the given name.
+    ///
+    /// Turns `name` into the proper dynamic library filename for the given
+    /// platform. On windows, it turns into name.dll, on OS X, name.dylib, and
+    /// elsewhere, libname.so.
+    pub fn load_plugin(&mut self, name: ~str) {
+        let x = self.prefix.push(libname(name));
+        let lib_result = dl::DynamicLibrary::open(Some(&x));
+        let lib = lib_result.unwrap();
+        let plugin = unsafe { lib.symbol("rustdoc_plugin_entrypoint") }.unwrap();
+        self.dylibs.push(lib);
+        self.callbacks.push(plugin);
+    }
+
+    /// Load a normal Rust function as a plugin.
+    ///
+    /// This is to run passes over the cleaned crate. Plugins run this way
+    /// correspond to the A-aux tag on Github.
+    pub fn add_plugin(&mut self, plugin: plugin_callback) {
+        self.callbacks.push(plugin);
+    }
+    /// Run all the loaded plugins over the crate, returning their results
+    pub fn run_plugins(&self, crate: clean::Crate) -> (clean::Crate, ~[PluginJson]) {
+        let mut out_json = ~[];
+        let mut crate = crate;
+        for &callback in self.callbacks.iter() {
+            let (c, res) = callback(crate);
+            crate = c;
+            out_json.push(res);
+        }
+        (crate, out_json)
+    }
+}
+
+#[cfg(target_os="win32")]
+fn libname(mut n: ~str) -> ~str {
+    n.push_str(".dll");
+    n
+}
+
+#[cfg(target_os="macos")]
+fn libname(mut n: ~str) -> ~str {
+    n.push_str(".dylib");
+    n
+}
+
+#[cfg(not(target_os="win32"), not(target_os="macos"))]
+fn libname(n: ~str) -> ~str {
+    let mut i = ~"lib";
+    i.push_str(n);
+    i.push_str(".so");
+    i
+}
diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs
deleted file mode 100644 (file)
index 9dc2f43..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Prunes things with the #[doc(hidden)] attribute
-
-use astsrv;
-use attr_parser;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"prune_hidden",
-        f: run
-    }
-}
-
-pub fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
-    let fold = Fold {
-        ctxt: srv.clone(),
-        fold_mod: fold_mod,
-        .. fold::default_any_fold(srv)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_mod(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    let doc = fold::default_any_fold_mod(fold, doc);
-
-    doc::ModDoc {
-        items: do doc.items.iter().filter |item_tag| {
-            !is_hidden(fold.ctxt.clone(), item_tag.item())
-        }.map(|x| (*x).clone()).collect(),
-        .. doc
-    }
-}
-
-fn is_hidden(srv: astsrv::Srv, doc: doc::ItemDoc) -> bool {
-    use syntax::ast_map;
-
-    let id = doc.id;
-    do astsrv::exec(srv) |ctxt| {
-        let attrs = match ctxt.ast_map.get_copy(&id) {
-          ast_map::node_item(item, _) => item.attrs.clone(),
-          _ => ~[]
-        };
-        attr_parser::parse_hidden(attrs)
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use astsrv;
-    use doc;
-    use extract;
-    use prune_hidden_pass::run;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_prune_hidden_items() {
-        let doc = mk_doc(~"#[doc(hidden)] mod a { }");
-        assert!(doc.cratemod().mods().is_empty())
-    }
-}
diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs
deleted file mode 100644 (file)
index 6a2a0ef..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Prune things that are private
-
-
-use extract;
-use syntax::ast;
-use syntax::ast_map;
-use astsrv;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"prune_private",
-        f: run
-    }
-}
-
-pub fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
-    // First strip private methods out of impls
-    let fold = Fold {
-        ctxt: srv.clone(),
-        fold_impl: fold_impl,
-        .. fold::default_any_fold(srv.clone())
-    };
-    let doc = (fold.fold_doc)(&fold, doc);
-
-    // Then strip private items and empty impls
-    let fold = Fold {
-        ctxt: srv.clone(),
-        fold_mod: fold_mod,
-        .. fold::default_any_fold(srv)
-    };
-    let doc = (fold.fold_doc)(&fold, doc);
-
-    return doc;
-}
-
-fn fold_impl(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ImplDoc
-) -> doc::ImplDoc {
-    let doc = fold::default_seq_fold_impl(fold, doc);
-
-    do astsrv::exec(fold.ctxt.clone()) |ctxt| {
-        match ctxt.ast_map.get_copy(&doc.item.id) {
-            ast_map::node_item(item, _) => {
-                match item.node {
-                    ast::item_impl(_, None, _, ref methods) => {
-                        // Associated impls have complex rules for method visibility
-                        strip_priv_methods(doc.clone(), *methods, item.vis)
-                    }
-                    ast::item_impl(_, Some(_), _ ,_) => {
-                        // Trait impls don't
-                        doc.clone()
-                    }
-                    _ => fail!()
-                }
-            }
-            _ => fail!()
-        }
-    }
-}
-
-fn strip_priv_methods(
-    doc: doc::ImplDoc,
-    methods: &[@ast::method],
-    item_vis: ast::visibility
-) -> doc::ImplDoc {
-    let methods = do doc.methods.iter().filter |method| {
-        let ast_method = do methods.iter().find |m| {
-            extract::to_str(m.ident) == method.name
-        };
-        assert!(ast_method.is_some());
-        let ast_method = ast_method.unwrap();
-        match ast_method.vis {
-            ast::public => true,
-            ast::private => false,
-            ast::inherited => item_vis == ast::public
-        }
-    }.map(|x| (*x).clone()).collect();
-
-    doc::ImplDoc {
-        methods: methods,
-        .. doc
-    }
-}
-
-fn fold_mod(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    let doc = fold::default_any_fold_mod(fold, doc);
-
-    doc::ModDoc {
-        items: doc.items.iter().filter(|item_tag| {
-            match item_tag {
-                & &doc::ImplTag(ref doc) => {
-                    if doc.trait_types.is_empty() {
-                        // This is an associated impl. We have already pruned the
-                        // non-visible methods. If there are any left then
-                        // retain the impl, otherwise throw it away
-                        !doc.methods.is_empty()
-                    } else {
-                        // This is a trait implementation, make it visible
-                        // NB: This is not quite right since this could be an impl
-                        // of a private trait. We can't know that without running
-                        // resolve though.
-                        true
-                    }
-                }
-                _ => {
-                    is_visible(fold.ctxt.clone(), item_tag.item())
-                }
-            }
-        }).map(|x| (*x).clone()).collect(),
-        .. doc
-    }
-}
-
-fn is_visible(srv: astsrv::Srv, doc: doc::ItemDoc) -> bool {
-    let id = doc.id;
-
-    do astsrv::exec(srv) |ctxt| {
-        match ctxt.ast_map.get_copy(&id) {
-            ast_map::node_item(item, _) => {
-                match &item.node {
-                    &ast::item_impl(*) => {
-                        // Impls handled elsewhere
-                        fail!()
-                    }
-                    _ => {
-                        // Otherwise just look at the visibility
-                        item.vis == ast::public
-                    }
-                }
-            }
-            _ => unreachable!()
-        }
-    }
-}
-
-
-#[cfg(test)]
-mod test {
-    use astsrv;
-    use doc;
-    use extract;
-    use tystr_pass;
-    use prune_private_pass::run;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = tystr_pass::run(srv.clone(), doc);
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_prune_items_without_pub_modifier() {
-        let doc = mk_doc(~"mod a { }");
-        assert!(doc.cratemod().mods().is_empty());
-    }
-
-    #[test]
-    fn should_not_prune_trait_impls() {
-        // Impls are more complicated
-        let doc = mk_doc(
-            ~" \
-              trait Foo { } \
-              impl Foo for int { } \
-              ");
-        assert!(!doc.cratemod().impls().is_empty());
-    }
-
-    #[test]
-    fn should_prune_associated_methods_without_vis_modifier_on_impls_without_vis_modifier() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              pub fn bar() { }\
-              fn baz() { }\
-              }");
-        assert_eq!(doc.cratemod().impls()[0].methods.len(), 1);
-    }
-
-    #[test]
-    fn should_prune_priv_associated_methods_on_impls_without_vis_modifier() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              pub fn bar() { }\
-              fn baz() { }\
-              }");
-        assert_eq!(doc.cratemod().impls()[0].methods.len(), 1);
-    }
-
-    #[test]
-    fn should_prune_priv_associated_methods_on_pub_impls() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              pub fn bar() { }\
-              fn baz() { }\
-              }");
-        assert_eq!(doc.cratemod().impls()[0].methods.len(), 1);
-    }
-
-    #[test]
-    fn should_prune_associated_methods_without_vis_modifier_on_priv_impls() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              pub fn bar() { }\
-              fn baz() { }\
-              }");
-        assert_eq!(doc.cratemod().impls()[0].methods.len(), 1);
-    }
-
-    #[test]
-    fn should_prune_priv_associated_methods_on_priv_impls() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              pub fn bar() { }\
-              fn baz() { }\
-              }");
-        assert_eq!(doc.cratemod().impls()[0].methods.len(), 1);
-    }
-
-    #[test]
-    fn should_prune_associated_impls_with_no_pub_methods() {
-        let doc = mk_doc(
-            ~"impl Foo {\
-              fn baz() { }\
-              }");
-        assert!(doc.cratemod().impls().is_empty());
-    }
-
-    #[test]
-    fn should_not_prune_associated_impls_with_pub_methods() {
-        let doc = mk_doc(
-            ~" \
-              impl Foo { pub fn bar() { } } \
-              ");
-        assert!(!doc.cratemod().impls().is_empty());
-    }
-}
index a55fa6bc3f7e961b1d28c3c2cb9ced3c702de28e..bc7e6c8926db5c04376406d7ba6aaabefe4ef5b4 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Rustdoc - The Rust documentation generator
-
 #[link(name = "rustdoc",
-       vers = "0.8-pre",
-       uuid = "f8abd014-b281-484d-a0c3-26e3de8e2412",
-       url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")];
+       vers = "0.8",
+       uuid = "8c6e4598-1596-4aa5-a24c-b811914bbbc6",
+       url = "https://github.com/mozilla/rust/tree/master/src/librustdoc")];
 
-#[comment = "The Rust documentation generator"];
+#[desc = "rustdoc, the Rust documentation extractor"];
 #[license = "MIT/ASL2"];
 #[crate_type = "lib"];
 
-extern mod extra;
-extern mod rustc;
 extern mod syntax;
+extern mod rustc;
+extern mod extra;
 
-use std::os;
-
-use config::Config;
-use doc::Item;
-use doc::ItemUtils;
-
-pub mod pass;
-pub mod config;
-pub mod parse;
-pub mod extract;
-pub mod attr_parser;
-pub mod doc;
-pub mod markdown_index_pass;
-pub mod markdown_pass;
-pub mod markdown_writer;
+use extra::serialize::Encodable;
+use extra::time;
+use extra::getopts::groups;
+use std::cell::Cell;
+use std::rt::io;
+use std::rt::io::Writer;
+use std::rt::io::file::FileInfo;
+
+pub mod clean;
+pub mod core;
+pub mod doctree;
 pub mod fold;
-pub mod path_pass;
-pub mod attr_pass;
-pub mod tystr_pass;
-pub mod prune_hidden_pass;
-pub mod desc_to_brief_pass;
-pub mod text_pass;
-pub mod unindent_pass;
-pub mod trim_pass;
-pub mod astsrv;
-pub mod demo;
-pub mod sort_pass;
-pub mod sort_item_name_pass;
-pub mod sort_item_type_pass;
-pub mod page_pass;
-pub mod sectionalize_pass;
-pub mod escape_pass;
-pub mod prune_private_pass;
+pub mod html {
+    pub mod render;
+    pub mod layout;
+    pub mod markdown;
+    pub mod format;
+}
+pub mod passes;
+pub mod plugins;
+pub mod visit_ast;
+
+pub static SCHEMA_VERSION: &'static str = "0.8.0";
+
+local_data_key!(pub ctxtkey: @core::DocContext)
+
+enum OutputFormat {
+    HTML, JSON
+}
 
 pub fn main() {
-    let args = os::args();
-    main_args(args);
+    main_args(std::os::args());
+}
+
+pub fn opts() -> ~[groups::OptGroup] {
+    use extra::getopts::groups::*;
+    ~[
+        optmulti("L", "library-path", "directory to add to crate search path",
+                 "DIR"),
+        optmulti("", "plugin-path", "directory to load plugins from", "DIR"),
+        optmulti("", "passes", "space separated list of passes to also run",
+                 "PASSES"),
+        optmulti("", "plugins", "space separated list of plugins to also load",
+                 "PLUGINS"),
+        optflag("h", "help", "show this help message"),
+        optflag("", "nodefaults", "don't run the default passes"),
+        optopt("o", "output", "where to place the output", "PATH"),
+    ]
+}
+
+pub fn usage(argv0: &str) {
+    println(groups::usage(format!("{} [options] [html|json] <crate>",
+                                  argv0), opts()));
 }
 
 pub fn main_args(args: &[~str]) {
-    if args.iter().any(|x| "-h" == *x) || args.iter().any(|x| "--help" == *x) {
-        config::usage();
+    //use extra::getopts::groups::*;
+
+    let matches = groups::getopts(args.tail(), opts()).unwrap();
+
+    if matches.opt_present("h") || matches.opt_present("help") {
+        usage(args[0]);
         return;
     }
 
-    let config = match config::parse_config(args) {
-      Ok(config) => config,
-      Err(err) => {
-        printfln!("error: %s", err);
-        return;
-      }
+    let (format, cratefile) = match matches.free.clone() {
+        [~"json", crate] => (JSON, crate),
+        [~"html", crate] => (HTML, crate),
+        [s, _] => {
+            println!("Unknown output format: `{}`", s);
+            usage(args[0]);
+            exit(1);
+        }
+        [_, .._] => {
+            println!("Expected exactly one crate to process");
+            usage(args[0]);
+            exit(1);
+        }
+        _ => {
+            println!("Expected an output format and then one crate");
+            usage(args[0]);
+            exit(1);
+        }
     };
 
-    run(config);
-}
+    // First, parse the crate and extract all relevant information.
+    let libs = Cell::new(matches.opt_strs("L").map(|s| Path(*s)));
+    let cr = Cell::new(Path(cratefile));
+    info2!("starting to run rustc");
+    let crate = do std::task::try {
+        let cr = cr.take();
+        core::run_core(libs.take(), &cr)
+    }.unwrap();
+    info2!("finished with rustc");
+
+    // Process all of the crate attributes, extracting plugin metadata along
+    // with the passes which we are supposed to run.
+    let mut default_passes = !matches.opt_present("nodefaults");
+    let mut passes = matches.opt_strs("passes");
+    let mut plugins = matches.opt_strs("plugins");
+    match crate.module.get_ref().doc_list() {
+        Some(nested) => {
+            for inner in nested.iter() {
+                match *inner {
+                    clean::Word(~"no_default_passes") => {
+                        default_passes = false;
+                    }
+                    clean::NameValue(~"passes", ref value) => {
+                        for pass in value.word_iter() {
+                            passes.push(pass.to_owned());
+                        }
+                    }
+                    clean::NameValue(~"plugins", ref value) => {
+                        for p in value.word_iter() {
+                            plugins.push(p.to_owned());
+                        }
+                    }
+                    _ => {}
+                }
+            }
+        }
+        None => {}
+    }
+    if default_passes {
+        passes.unshift(~"collapse-docs");
+        passes.unshift(~"unindent-comments");
+    }
 
-/// Runs rustdoc over the given file
-fn run(config: Config) {
+    // Load all plugins/passes into a PluginManager
+    let mut pm = plugins::PluginManager::new(Path("/tmp/rustdoc_ng/plugins"));
+    for pass in passes.iter() {
+        let plugin = match pass.as_slice() {
+            "strip-hidden" => passes::strip_hidden,
+            "unindent-comments" => passes::unindent_comments,
+            "collapse-docs" => passes::collapse_docs,
+            "collapse-privacy" => passes::collapse_privacy,
+            s => { error!("unknown pass %s, skipping", s); loop },
+        };
+        pm.add_plugin(plugin);
+    }
+    info2!("loading plugins...");
+    for pname in plugins.move_iter() {
+        pm.load_plugin(pname);
+    }
 
-    let source_file = config.input_crate.clone();
+    // Run everything!
+    info2!("Executing passes/plugins");
+    let (crate, res) = pm.run_plugins(crate);
 
-    // Create an AST service from the source code
-    do astsrv::from_file(source_file.to_str()) |srv| {
+    info2!("going to format");
+    let started = time::precise_time_ns();
+    let output = matches.opt_str("o").map(|s| Path(*s));
+    match format {
+        HTML => { html::render::run(crate, output.unwrap_or(Path("doc"))) }
+        JSON => { jsonify(crate, res, output.unwrap_or(Path("doc.json"))) }
+    }
+    let ended = time::precise_time_ns();
+    info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
+}
 
-        // Just time how long it takes for the AST to become available
-        do time(~"wait_ast") {
-            do astsrv::exec(srv.clone()) |_ctxt| { }
-        };
+fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
+    // {
+    //   "schema": version,
+    //   "crate": { parsed crate ... },
+    //   "plugins": { output of plugins ... }
+    // }
+    let mut json = ~extra::treemap::TreeMap::new();
+    json.insert(~"schema", extra::json::String(SCHEMA_VERSION.to_owned()));
+    let plugins_json = ~res.move_iter().filter_map(|opt| opt).collect();
+
+    // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
+    // straight to the Rust JSON representation.
+    let crate_json_str = do std::io::with_str_writer |w| {
+        crate.encode(&mut extra::json::Encoder(w));
+    };
+    let crate_json = match extra::json::from_str(crate_json_str) {
+        Ok(j) => j,
+        Err(_) => fail!("Rust generated JSON is invalid??")
+    };
 
-        // Extract the initial doc tree from the AST. This contains
-        // just names and node ids.
-        let doc = time(~"extract", || {
-            let default_name = source_file.clone();
-            extract::from_srv(srv.clone(), default_name.to_str())
-        });
-
-        // Refine and publish the document
-        pass::run_passes(srv, doc, ~[
-            // Generate type and signature strings
-            tystr_pass::mk_pass(),
-            // Record the full paths to various nodes
-            path_pass::mk_pass(),
-            // Extract the docs attributes and attach them to doc nodes
-            attr_pass::mk_pass(),
-            // Perform various text escaping
-            escape_pass::mk_pass(),
-            // Remove things marked doc(hidden)
-            prune_hidden_pass::mk_pass(),
-            // Remove things that are private
-            prune_private_pass::mk_pass(),
-            // Extract brief documentation from the full descriptions
-            desc_to_brief_pass::mk_pass(),
-            // Massage the text to remove extra indentation
-            unindent_pass::mk_pass(),
-            // Split text into multiple sections according to headers
-            sectionalize_pass::mk_pass(),
-            // Trim extra spaces from text
-            trim_pass::mk_pass(),
-            // Sort items by name
-            sort_item_name_pass::mk_pass(),
-            // Sort items again by kind
-            sort_item_type_pass::mk_pass(),
-            // Create indexes appropriate for markdown
-            markdown_index_pass::mk_pass(config.clone()),
-            // Break the document into pages if required by the
-            // output format
-            page_pass::mk_pass(config.output_style),
-            // Render
-            markdown_pass::mk_pass(
-                markdown_writer::make_writer_factory(config.clone())
-            )
-        ]);
-    }
+    json.insert(~"crate", crate_json);
+    json.insert(~"plugins", extra::json::Object(plugins_json));
+
+    let mut file = dst.open_writer(io::Create).unwrap();
+    let output = extra::json::Object(json).to_str();
+    file.write(output.as_bytes());
 }
 
-pub fn time<T>(what: ~str, f: &fn() -> T) -> T {
-    let start = extra::time::precise_time_s();
-    let rv = f();
-    let end = extra::time::precise_time_s();
-    info!("time: %3.3f s    %s", end - start, what);
-    rv
+fn exit(status: int) -> ! {
+    #[fixed_stack_segment]; #[inline(never)];
+    use std::libc;
+    unsafe { libc::exit(status as libc::c_int) }
 }
diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs
deleted file mode 100644 (file)
index 20f3ff3..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Breaks rustdocs into sections according to their headers
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"sectionalize",
-        f: run
-    }
-}
-
-pub fn run(_srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
-    let fold = Fold {
-        fold_item: fold_item,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        .. fold::default_any_fold(())
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_item(fold: &fold::Fold<()>, doc: doc::ItemDoc) -> doc::ItemDoc {
-    let doc = fold::default_seq_fold_item(fold, doc);
-    let (desc, sections) = sectionalize(doc.desc.clone());
-
-    doc::ItemDoc {
-        desc: desc,
-        sections: sections,
-        .. doc
-    }
-}
-
-fn fold_trait(fold: &fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc {
-    let doc = fold::default_seq_fold_trait(fold, doc);
-
-    doc::TraitDoc {
-        methods: do doc.methods.map |method| {
-            let (desc, sections) = sectionalize(method.desc.clone());
-
-            doc::MethodDoc {
-                desc: desc,
-                sections: sections,
-                .. (*method).clone()
-            }
-        },
-        .. doc
-    }
-}
-
-fn fold_impl(fold: &fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc {
-    let doc = fold::default_seq_fold_impl(fold, doc);
-
-    doc::ImplDoc {
-        methods: do doc.methods.map |method| {
-            let (desc, sections) = sectionalize(method.desc.clone());
-
-            doc::MethodDoc {
-                desc: desc,
-                sections: sections,
-                .. (*method).clone()
-            }
-        },
-        .. doc
-    }
-}
-
-fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
-
-    /*!
-     * Take a description of the form
-     *
-     *     General text
-     *
-     *     # Section header
-     *
-     *     Section text
-     *
-     *     # Section header
-     *
-     *     Section text
-     *
-     * and remove each header and accompanying text into section records.
-     */
-
-    if desc.is_none() {
-        return (None, ~[]);
-    }
-
-    let mut new_desc = None::<~str>;
-    let mut current_section: Option<doc::Section> = None;
-    let mut sections = ~[];
-
-    for line in desc.get_ref().any_line_iter() {
-        match parse_header(line) {
-          Some(header) => {
-            if current_section.is_some() {
-                sections.push((*current_section.get_ref()).clone());
-            }
-            current_section = Some(doc::Section {
-                header: header.to_owned(),
-                body: ~""
-            });
-          }
-          None => {
-            match current_section.clone() {
-              Some(section) => {
-                current_section = Some(doc::Section {
-                    body: fmt!("%s\n%s", section.body, line),
-                    .. section
-                });
-              }
-              None => {
-                new_desc = match new_desc.clone() {
-                  Some(desc) => {
-                    Some(fmt!("%s\n%s", desc, line))
-                  }
-                  None => {
-                    Some(line.to_owned())
-                  }
-                };
-              }
-            }
-          }
-        }
-    }
-
-    if current_section.is_some() {
-        sections.push(current_section.unwrap());
-    }
-
-    (new_desc, sections)
-}
-
-fn parse_header<'a>(line: &'a str) -> Option<&'a str> {
-    if line.starts_with("# ") {
-        Some(line.slice_from(2))
-    } else {
-        None
-    }
-}
-
-
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass;
-    use doc;
-    use extract;
-    use prune_hidden_pass;
-    use sectionalize_pass::run;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (prune_hidden_pass::mk_pass().f)(srv.clone(), doc);
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_create_section_headers() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert!(doc.cratemod().mods()[0].item.sections[0].header.contains("Header"));
-    }
-
-    #[test]
-    fn should_create_section_bodies() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert!(doc.cratemod().mods()[0].item.sections[0].body.contains("Body"));
-    }
-
-    #[test]
-    fn should_not_create_sections_from_indented_headers() {
-        let doc = mk_doc(
-            ~"#[doc = \"\n\
-              Text\n             # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert!(doc.cratemod().mods()[0].item.sections.is_empty());
-    }
-
-    #[test]
-    fn should_remove_section_text_from_main_desc() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              Description\n\n\
-              # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert!(!doc.cratemod().mods()[0].desc().unwrap().contains("Header"));
-        assert!(!doc.cratemod().mods()[0].desc().unwrap().contains("Body"));
-    }
-
-    #[test]
-    fn should_eliminate_desc_if_it_is_just_whitespace() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              # Header\n\
-              Body\"]\
-              mod a {
-}");
-        assert_eq!(doc.cratemod().mods()[0].desc(), None);
-    }
-
-    #[test]
-    fn should_sectionalize_trait_methods() {
-        let doc = mk_doc(
-            ~"trait i {
-#[doc = \"\
-              # Header\n\
-              Body\"]\
-              fn a(); }");
-        assert_eq!(doc.cratemod().traits()[0].methods[0].sections.len(), 1u);
-    }
-
-    #[test]
-    fn should_sectionalize_impl_methods() {
-        let doc = mk_doc(
-            ~"impl bool {
-#[doc = \"\
-              # Header\n\
-              Body\"]\
-              fn a() { } }");
-        assert_eq!(doc.cratemod().impls()[0].methods[0].sections.len(), 1u);
-    }
-}
diff --git a/src/librustdoc/sort_item_name_pass.rs b/src/librustdoc/sort_item_name_pass.rs
deleted file mode 100644 (file)
index 8c7267e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Sorts items by name
-
-use doc::ItemUtils;
-use doc;
-use pass::Pass;
-use sort_pass;
-
-pub fn mk_pass() -> Pass {
-    fn by_item_name(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
-        (*item1).name_() <= (*item2).name_()
-    }
-    sort_pass::mk_pass(~"sort_item_name", by_item_name)
-}
-
-#[test]
-fn test() {
-    use astsrv;
-    use extract;
-
-    let source = ~"mod z { } fn y() { }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = (mk_pass().f)(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().items[1].name_(), ~"y");
-        assert_eq!(doc.cratemod().items[2].name_(), ~"z");
-    }
-}
diff --git a/src/librustdoc/sort_item_type_pass.rs b/src/librustdoc/sort_item_type_pass.rs
deleted file mode 100644 (file)
index ba8f376..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Sorts items by type
-
-use doc;
-use pass::Pass;
-use sort_pass;
-
-pub fn mk_pass() -> Pass {
-    fn by_score(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
-        fn score(item: &doc::ItemTag) -> int {
-            match *item {
-              doc::StaticTag(_) => 0,
-              doc::TyTag(_) => 1,
-              doc::EnumTag(_) => 2,
-              doc::StructTag(_) => 3,
-              doc::TraitTag(_) => 4,
-              doc::ImplTag(_) => 5,
-              doc::FnTag(_) => 6,
-              doc::ModTag(_) => 7,
-              doc::NmodTag(_) => 8
-            }
-        }
-
-        score(item1) <= score(item2)
-    }
-
-    sort_pass::mk_pass(~"sort_item_type", by_score)
-}
-
-#[test]
-fn test() {
-    use astsrv;
-    use extract;
-
-    let source =
-        ~"mod imod { } \
-         static istatic: int = 0; \
-         fn ifn() { } \
-         enum ienum { ivar } \
-         trait itrait { fn a(); } \
-         impl int { fn a() { } } \
-         type itype = int; \
-         struct istruct { f: () }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = (mk_pass().f)(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().items[0].name_(), ~"istatic");
-        assert_eq!(doc.cratemod().items[1].name_(), ~"itype");
-        assert_eq!(doc.cratemod().items[2].name_(), ~"ienum");
-        assert_eq!(doc.cratemod().items[3].name_(), ~"istruct");
-        assert_eq!(doc.cratemod().items[4].name_(), ~"itrait");
-        assert_eq!(doc.cratemod().items[5].name_(), ~"__extensions__");
-        assert_eq!(doc.cratemod().items[6].name_(), ~"ifn");
-        // hidden __std_macros module fits here.
-        assert_eq!(doc.cratemod().items[8].name_(), ~"imod");
-    }
-}
diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs
deleted file mode 100644 (file)
index a6aa948..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A general sorting pass
-
-use astsrv;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-#[cfg(test)] use extract;
-
-use extra::sort;
-use std::clone::Clone;
-
-pub type ItemLtEqOp = @fn(v1: &doc::ItemTag, v2:  &doc::ItemTag) -> bool;
-
-struct ItemLtEq {
-    op: ItemLtEqOp,
-}
-
-impl Clone for ItemLtEq {
-    fn clone(&self) -> ItemLtEq {
-        ItemLtEq {
-            op: self.op,
-        }
-    }
-}
-
-pub fn mk_pass(name: ~str, lteq: ItemLtEqOp) -> Pass {
-    Pass {
-        name: name.clone(),
-        f: |srv, doc| run(srv, doc, ItemLtEq { op: lteq })
-    }
-}
-
-fn run(
-    _srv: astsrv::Srv,
-    doc: doc::Doc,
-    lteq: ItemLtEq
-) -> doc::Doc {
-    let fold = Fold {
-        fold_mod: fold_mod,
-        .. fold::default_any_fold(lteq)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_mod(
-    fold: &fold::Fold<ItemLtEq>,
-    doc: doc::ModDoc
-) -> doc::ModDoc {
-    let doc = fold::default_any_fold_mod(fold, doc);
-    doc::ModDoc {
-        items: sort::merge_sort(doc.items, fold.ctxt.op),
-        .. doc
-    }
-}
-
-#[test]
-fn test() {
-    fn name_lteq(item1: &doc::ItemTag, item2: &doc::ItemTag) -> bool {
-        (*item1).name_() <= (*item2).name_()
-    }
-
-    let source = ~"mod z { mod y { } fn x() { } } mod w { }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = (mk_pass(~"", name_lteq).f)(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().mods()[1].name_(), ~"w");
-        assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"x");
-        assert_eq!(doc.cratemod().mods()[2].items[1].name_(), ~"y");
-        assert_eq!(doc.cratemod().mods()[2].name_(), ~"z");
-    }
-}
-
-#[test]
-fn should_be_stable() {
-    fn always_eq(_item1: &doc::ItemTag, _item2: &doc::ItemTag) -> bool {
-        true
-    }
-
-    let source = ~"mod a { mod b { } } mod c { mod d { } }";
-    do astsrv::from_str(source) |srv| {
-        let doc = extract::from_srv(srv.clone(), ~"");
-        let doc = (mk_pass(~"", always_eq).f)(srv.clone(), doc);
-        // hidden __std_macros module at the start.
-        assert_eq!(doc.cratemod().mods()[1].items[0].name_(), ~"b");
-        assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"d");
-        let doc = (mk_pass(~"", always_eq).f)(srv.clone(), doc);
-        assert_eq!(doc.cratemod().mods()[1].items[0].name_(), ~"b");
-        assert_eq!(doc.cratemod().mods()[2].items[0].name_(), ~"d");
-    }
-}
diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs
deleted file mode 100644 (file)
index 41c0dcf..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Generic pass for performing an operation on all descriptions
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-use std::cell::Cell;
-
-pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass {
-    let op = Cell::new(op);
-    Pass {
-        name: name.clone(),
-        f: |srv: astsrv::Srv, doc: doc::Doc| -> doc::Doc {
-            run(srv, doc, op.take())
-        }
-    }
-}
-
-type Op = @fn(&str) -> ~str;
-
-struct WrappedOp {
-    op: Op,
-}
-
-impl Clone for WrappedOp {
-    fn clone(&self) -> WrappedOp {
-        WrappedOp {
-            op: self.op,
-        }
-    }
-}
-
-fn run(
-    _srv: astsrv::Srv,
-    doc: doc::Doc,
-    op: Op
-) -> doc::Doc {
-    let op = WrappedOp {
-        op: op
-    };
-    let fold = Fold {
-        fold_item: fold_item,
-        fold_enum: fold_enum,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        .. fold::default_any_fold(op)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn maybe_apply_op(op: WrappedOp, s: &Option<~str>) -> Option<~str> {
-    s.map(|s| (op.op)(*s) )
-}
-
-fn fold_item(fold: &fold::Fold<WrappedOp>, doc: doc::ItemDoc)
-             -> doc::ItemDoc {
-    let doc = fold::default_seq_fold_item(fold, doc);
-
-    doc::ItemDoc {
-        brief: maybe_apply_op(fold.ctxt, &doc.brief),
-        desc: maybe_apply_op(fold.ctxt, &doc.desc),
-        sections: apply_to_sections(fold.ctxt, doc.sections.clone()),
-        .. doc
-    }
-}
-
-fn apply_to_sections(op: WrappedOp, sections: ~[doc::Section])
-                     -> ~[doc::Section] {
-    sections.map(|section| doc::Section {
-        header: (op.op)(section.header.clone()),
-        body: (op.op)(section.body.clone())
-    })
-}
-
-fn fold_enum(fold: &fold::Fold<WrappedOp>, doc: doc::EnumDoc)
-             -> doc::EnumDoc {
-    let doc = fold::default_seq_fold_enum(fold, doc);
-    let fold_copy = *fold;
-
-    doc::EnumDoc {
-        variants: do doc.variants.map |variant| {
-            doc::VariantDoc {
-                desc: maybe_apply_op(fold_copy.ctxt, &variant.desc),
-                .. (*variant).clone()
-            }
-        },
-        .. doc
-    }
-}
-
-fn fold_trait(fold: &fold::Fold<WrappedOp>, doc: doc::TraitDoc)
-              -> doc::TraitDoc {
-    let doc = fold::default_seq_fold_trait(fold, doc);
-
-    doc::TraitDoc {
-        methods: apply_to_methods(fold.ctxt, doc.methods.clone()),
-        .. doc
-    }
-}
-
-fn apply_to_methods(op: WrappedOp, docs: ~[doc::MethodDoc])
-                    -> ~[doc::MethodDoc] {
-    do docs.map |doc| {
-        doc::MethodDoc {
-            brief: maybe_apply_op(op, &doc.brief),
-            desc: maybe_apply_op(op, &doc.desc),
-            sections: apply_to_sections(op, doc.sections.clone()),
-            .. (*doc).clone()
-        }
-    }
-}
-
-fn fold_impl(fold: &fold::Fold<WrappedOp>, doc: doc::ImplDoc)
-             -> doc::ImplDoc {
-    let doc = fold::default_seq_fold_impl(fold, doc);
-
-    doc::ImplDoc {
-        methods: apply_to_methods(fold.ctxt, doc.methods.clone()),
-        .. doc
-    }
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use attr_pass;
-    use desc_to_brief_pass;
-    use doc;
-    use extract;
-    use sectionalize_pass;
-    use text_pass::mk_pass;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (desc_to_brief_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (sectionalize_pass::mk_pass().f)(srv.clone(), doc);
-            (mk_pass(~"", |s| s.trim().to_owned() ).f)(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_execute_op_on_enum_brief() {
-        let doc = mk_doc(~"#[doc = \" a \"] enum a { b }");
-        assert_eq!(doc.cratemod().enums()[0].brief(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_enum_desc() {
-        let doc = mk_doc(~"#[doc = \" a \"] enum a { b }");
-        assert_eq!(doc.cratemod().enums()[0].desc(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_variant_desc() {
-        let doc = mk_doc(~"enum a { #[doc = \" a \"] b }");
-        assert!(doc.cratemod().enums()[0].variants[0].desc == Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_trait_brief() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] trait i { fn a(); }");
-        assert_eq!(doc.cratemod().traits()[0].brief(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_trait_desc() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] trait i { fn a(); }");
-        assert_eq!(doc.cratemod().traits()[0].desc(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_trait_method_brief() {
-        let doc = mk_doc(
-            ~"trait i { #[doc = \" a \"] fn a(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].brief == Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_trait_method_desc() {
-        let doc = mk_doc(
-            ~"trait i { #[doc = \" a \"] fn a(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].desc == Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_impl_brief() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] impl int { fn a() { } }");
-        assert_eq!(doc.cratemod().impls()[0].brief(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_impl_desc() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] impl int { fn a() { } }");
-        assert_eq!(doc.cratemod().impls()[0].desc(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_impl_method_brief() {
-        let doc = mk_doc(
-            ~"impl int { #[doc = \" a \"] fn a() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].brief == Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_impl_method_desc() {
-        let doc = mk_doc(
-            ~"impl int { #[doc = \" a \"] fn a() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].desc == Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_type_brief() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] type t = int;");
-        assert_eq!(doc.cratemod().types()[0].brief(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_op_on_type_desc() {
-        let doc = mk_doc(
-            ~"#[doc = \" a \"] type t = int;");
-        assert_eq!(doc.cratemod().types()[0].desc(), Some(~"a"));
-    }
-
-    #[test]
-    fn should_execute_on_item_section_headers() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              #    Header    \n\
-              Body\"]\
-              fn a() { }");
-        assert!(doc.cratemod().fns()[0].sections()[0].header == ~"Header");
-    }
-
-    #[test]
-    fn should_execute_on_item_section_bodies() {
-        let doc = mk_doc(
-            ~"#[doc = \"\
-              # Header\n\
-              Body      \"]\
-              fn a() { }");
-        assert!(doc.cratemod().fns()[0].sections()[0].body == ~"Body");
-    }
-
-    #[test]
-    fn should_execute_on_trait_method_section_headers() {
-        let doc = mk_doc(
-            ~"trait i {
-#[doc = \"\
-              # Header    \n\
-              Body\"]\
-              fn a(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].sections[0].header
-                == ~"Header");
-    }
-
-    #[test]
-    fn should_execute_on_trait_method_section_bodies() {
-        let doc = mk_doc(
-            ~"trait i {
-#[doc = \"\
-              # Header\n\
-              Body     \"]\
-              fn a(); }");
-        assert!(doc.cratemod().traits()[0].methods[0].sections[0].body ==
-                ~"Body");
-    }
-
-    #[test]
-    fn should_execute_on_impl_method_section_headers() {
-        let doc = mk_doc(
-            ~"impl bool {
-#[doc = \"\
-              # Header   \n\
-              Body\"]\
-              fn a() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].sections[0].header
-                == ~"Header");
-    }
-
-    #[test]
-    fn should_execute_on_impl_method_section_bodies() {
-        let doc = mk_doc(
-            ~"impl bool {
-#[doc = \"\
-              # Header\n\
-              Body    \"]\
-              fn a() { } }");
-        assert!(doc.cratemod().impls()[0].methods[0].sections[0].body ==
-                ~"Body");
-    }
-}
diff --git a/src/librustdoc/trim_pass.rs b/src/librustdoc/trim_pass.rs
deleted file mode 100644 (file)
index aaba042..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Pulls a brief description out of a long description.
-
-If the first paragraph of a long description is short enough then it
-is interpreted as the brief description.
-*/
-
-use pass::Pass;
-use text_pass;
-
-pub fn mk_pass() -> Pass {
-    text_pass::mk_pass(~"trim", |s| s.trim().to_owned() )
-}
-
-#[cfg(test)]
-mod test {
-    use astsrv;
-    use attr_pass;
-    use doc;
-    use extract;
-    use prune_hidden_pass;
-    use trim_pass::mk_pass;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            let doc = (attr_pass::mk_pass().f)(srv.clone(), doc);
-            let doc = (prune_hidden_pass::mk_pass().f)(srv.clone(), doc);
-            (mk_pass().f)(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_trim_text() {
-        use std::option::Some;
-
-        let doc = mk_doc(~"#[doc = \" desc \"] \
-                                 mod m {
-}");
-        assert_eq!(doc.cratemod().mods()[0].desc(), Some(~"desc"));
-    }
-}
diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs
deleted file mode 100644 (file)
index aa4407a..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Pulls type information out of the AST and attaches it to the document
-
-
-use astsrv;
-use doc::ItemUtils;
-use doc;
-use extract::to_str;
-use extract;
-use fold::Fold;
-use fold;
-use pass::Pass;
-
-use syntax::ast;
-use syntax::print::pprust;
-use syntax::parse::token;
-use syntax::ast_map;
-
-pub fn mk_pass() -> Pass {
-    Pass {
-        name: ~"tystr",
-        f: run
-    }
-}
-
-pub fn run(
-    srv: astsrv::Srv,
-    doc: doc::Doc
-) -> doc::Doc {
-    let fold = Fold {
-        ctxt: srv.clone(),
-        fold_fn: fold_fn,
-        fold_static: fold_static,
-        fold_enum: fold_enum,
-        fold_trait: fold_trait,
-        fold_impl: fold_impl,
-        fold_type: fold_type,
-        fold_struct: fold_struct,
-        .. fold::default_any_fold(srv)
-    };
-    (fold.fold_doc)(&fold, doc)
-}
-
-fn fold_fn(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::FnDoc
-) -> doc::FnDoc {
-
-    let srv = fold.ctxt.clone();
-
-    doc::SimpleItemDoc {
-        sig: get_fn_sig(srv, doc.id()),
-        .. doc
-    }
-}
-
-fn get_fn_sig(srv: astsrv::Srv, fn_id: doc::AstId) -> Option<~str> {
-    do astsrv::exec(srv) |ctxt| {
-        match ctxt.ast_map.get_copy(&fn_id) {
-            ast_map::node_item(@ast::item {
-                ident: ident,
-                node: ast::item_fn(ref decl, purity, _, ref tys, _), _
-            }, _) => {
-                Some(pprust::fun_to_str(decl,
-                                        purity,
-                                        ident,
-                                        None,
-                                        tys,
-                                        token::get_ident_interner()))
-            }
-            ast_map::node_foreign_item(@ast::foreign_item {
-                ident: ident,
-                node: ast::foreign_item_fn(ref decl, ref tys), _
-            }, _, _, _) => {
-                Some(pprust::fun_to_str(decl,
-                                        ast::impure_fn,
-                                        ident,
-                                        None,
-                                        tys,
-                                        token::get_ident_interner()))
-            }
-            _ => fail!("get_fn_sig: fn_id not bound to a fn item")
-        }
-    }
-}
-
-fn fold_static(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::StaticDoc
-) -> doc::StaticDoc {
-    let srv = fold.ctxt.clone();
-
-    doc::SimpleItemDoc {
-        sig: Some({
-            let doc = doc.clone();
-            do astsrv::exec(srv) |ctxt| {
-                match ctxt.ast_map.get_copy(&doc.id()) {
-                    ast_map::node_item(@ast::item {
-                        node: ast::item_static(ref ty, _, _), _
-                    }, _) => {
-                        pprust::ty_to_str(ty, extract::interner())
-                    }
-                    _ => fail!("fold_static: id not bound to a static item")
-                }
-            }}),
-        .. doc
-    }
-}
-
-fn fold_enum(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::EnumDoc
-) -> doc::EnumDoc {
-    let doc_id = doc.id();
-    let srv = fold.ctxt.clone();
-
-    doc::EnumDoc {
-        variants: do doc.variants.iter().map |variant| {
-            let sig = {
-                let variant = (*variant).clone();
-                do astsrv::exec(srv.clone()) |ctxt| {
-                    match ctxt.ast_map.get_copy(&doc_id) {
-                        ast_map::node_item(@ast::item {
-                            node: ast::item_enum(ref enum_definition, _), _
-                        }, _) => {
-                            let ast_variant =
-                                (*do enum_definition.variants.iter().find |v| {
-                                to_str(v.node.name) == variant.name
-                            }.unwrap()).clone();
-
-                            pprust::variant_to_str(
-                                &ast_variant, extract::interner())
-                        }
-                        _ => fail!("enum variant not bound to an enum item")
-                    }
-                }
-            };
-
-            doc::VariantDoc {
-                sig: Some(sig),
-                .. (*variant).clone()
-            }
-        }.collect(),
-        .. doc
-    }
-}
-
-fn fold_trait(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::TraitDoc
-) -> doc::TraitDoc {
-    doc::TraitDoc {
-        methods: merge_methods(fold.ctxt.clone(), doc.id(), doc.methods.clone()),
-        .. doc
-    }
-}
-
-fn merge_methods(
-    srv: astsrv::Srv,
-    item_id: doc::AstId,
-    docs: ~[doc::MethodDoc]
-) -> ~[doc::MethodDoc] {
-    do docs.iter().map |doc| {
-        doc::MethodDoc {
-            sig: get_method_sig(srv.clone(), item_id, doc.name.clone()),
-            .. (*doc).clone()
-        }
-    }.collect()
-}
-
-fn get_method_sig(
-    srv: astsrv::Srv,
-    item_id: doc::AstId,
-    method_name: ~str
-) -> Option<~str> {
-    do astsrv::exec(srv) |ctxt| {
-        match ctxt.ast_map.get_copy(&item_id) {
-            ast_map::node_item(@ast::item {
-                node: ast::item_trait(_, _, ref methods), _
-            }, _) => {
-                match methods.iter().find(|&method| {
-                    match (*method).clone() {
-                        ast::required(ty_m) => to_str(ty_m.ident) == method_name,
-                        ast::provided(m) => to_str(m.ident) == method_name,
-                    }
-                }) {
-                    Some(method) => {
-                        match (*method).clone() {
-                            ast::required(ty_m) => {
-                                Some(pprust::fun_to_str(
-                                    &ty_m.decl,
-                                    ty_m.purity,
-                                    ty_m.ident,
-                                    Some(ty_m.explicit_self.node),
-                                    &ty_m.generics,
-                                    extract::interner()
-                                ))
-                            }
-                            ast::provided(m) => {
-                                Some(pprust::fun_to_str(
-                                    &m.decl,
-                                    m.purity,
-                                    m.ident,
-                                    Some(m.explicit_self.node),
-                                    &m.generics,
-                                    extract::interner()
-                                ))
-                            }
-                        }
-                    }
-                    _ => fail!("method not found")
-                }
-            }
-            ast_map::node_item(@ast::item {
-                node: ast::item_impl(_, _, _, ref methods), _
-            }, _) => {
-                match methods.iter().find(|method| {
-                    to_str(method.ident) == method_name
-                }) {
-                    Some(method) => {
-                        Some(pprust::fun_to_str(
-                            &method.decl,
-                            method.purity,
-                            method.ident,
-                            Some(method.explicit_self.node),
-                            &method.generics,
-                            extract::interner()
-                        ))
-                    }
-                    None => fail!("method not found")
-                }
-            }
-            _ => fail!("get_method_sig: item ID not bound to trait or impl")
-        }
-    }
-}
-
-fn fold_impl(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::ImplDoc
-) -> doc::ImplDoc {
-
-    let srv = fold.ctxt.clone();
-
-    let (bounds, trait_types, self_ty) = {
-        let doc = doc.clone();
-        do astsrv::exec(srv) |ctxt| {
-            match ctxt.ast_map.get_copy(&doc.id()) {
-                ast_map::node_item(@ast::item {
-                    node: ast::item_impl(ref generics, ref opt_trait_type, ref self_ty, _), _
-                }, _) => {
-                    let bounds = pprust::generics_to_str(generics, extract::interner());
-                    let bounds = if bounds.is_empty() { None } else { Some(bounds) };
-                    let trait_types = do opt_trait_type.map_default(~[]) |p| {
-                        ~[pprust::path_to_str(&p.path, extract::interner())]
-                    };
-                    (bounds,
-                     trait_types,
-                     Some(pprust::ty_to_str(
-                         self_ty, extract::interner())))
-                }
-                _ => fail!("expected impl")
-            }
-        }
-    };
-
-    doc::ImplDoc {
-        bounds_str: bounds,
-        trait_types: trait_types,
-        self_ty: self_ty,
-        methods: merge_methods(fold.ctxt.clone(), doc.id(), doc.methods.clone()),
-        .. doc
-    }
-}
-
-fn fold_type(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::TyDoc
-) -> doc::TyDoc {
-
-    let srv = fold.ctxt.clone();
-
-    doc::SimpleItemDoc {
-        sig: {
-            let doc = doc.clone();
-            do astsrv::exec(srv) |ctxt| {
-                match ctxt.ast_map.get_copy(&doc.id()) {
-                    ast_map::node_item(@ast::item {
-                        ident: ident,
-                        node: ast::item_ty(ref ty, ref params), _
-                    }, _) => {
-                        Some(fmt!(
-                            "type %s%s = %s",
-                            to_str(ident),
-                            pprust::generics_to_str(params,
-                                                    extract::interner()),
-                            pprust::ty_to_str(ty, extract::interner())
-                        ))
-                    }
-                    _ => fail!("expected type")
-                }
-            }
-        },
-        .. doc
-    }
-}
-
-fn fold_struct(
-    fold: &fold::Fold<astsrv::Srv>,
-    doc: doc::StructDoc
-) -> doc::StructDoc {
-    let srv = fold.ctxt.clone();
-
-    doc::StructDoc {
-        sig: {
-            let doc = doc.clone();
-            do astsrv::exec(srv) |ctxt| {
-                match ctxt.ast_map.get_copy(&doc.id()) {
-                    ast_map::node_item(item, _) => {
-                        let item = strip_struct_extra_stuff(item);
-                        Some(pprust::item_to_str(item,
-                                                 extract::interner()))
-                    }
-                    _ => fail!("not an item")
-                }
-            }
-        },
-        .. doc
-    }
-}
-
-/// Removes various things from the struct item definition that
-/// shouldn't be displayed in the struct signature. Probably there
-/// should be a simple pprust::struct_to_str function that does
-/// what I actually want
-fn strip_struct_extra_stuff(item: @ast::item) -> @ast::item {
-    let node = match item.node.clone() {
-        ast::item_struct(def, tys) => ast::item_struct(def, tys),
-        _ => fail!("not a struct")
-    };
-
-    @ast::item {
-        attrs: ~[], // Remove the attributes
-        node: node,
-        .. (*item).clone()
-    }
-}
-
-#[cfg(test)]
-mod test {
-
-    use astsrv;
-    use doc;
-    use extract;
-    use tystr_pass::run;
-
-    fn mk_doc(source: ~str) -> doc::Doc {
-        do astsrv::from_str(source.clone()) |srv| {
-            let doc = extract::from_srv(srv.clone(), ~"");
-            run(srv.clone(), doc)
-        }
-    }
-
-    #[test]
-    fn should_add_fn_sig() {
-        let doc = mk_doc(~"fn a<T>() -> int { }");
-        assert!(doc.cratemod().fns()[0].sig == Some(~"fn a<T>() -> int"));
-    }
-
-    #[test]
-    fn should_add_foreign_fn_sig() {
-        let doc = mk_doc(~"extern { fn a<T>() -> int; }");
-        assert!(doc.cratemod().nmods()[0].fns[0].sig ==
-                Some(~"fn a<T>() -> int"));
-    }
-
-    #[test]
-    fn should_add_static_types() {
-        let doc = mk_doc(~"static a: bool = true;");
-        assert!(doc.cratemod().statics()[0].sig == Some(~"bool"));
-    }
-
-    #[test]
-    fn should_add_variant_sigs() {
-        let doc = mk_doc(~"enum a { b(int) }");
-        assert!(doc.cratemod().enums()[0].variants[0].sig ==
-                Some(~"b(int)"));
-    }
-
-    #[test]
-    fn should_add_trait_method_sigs() {
-        let doc = mk_doc(~"trait i { fn a<T>(&mut self) -> int; }");
-        assert!(doc.cratemod().traits()[0].methods[0].sig
-                == Some(~"fn a<T>(&mut self) -> int"));
-    }
-
-    #[test]
-    fn should_add_impl_bounds() {
-        let doc = mk_doc(~"impl<T, U, V: Clone> Option<T, U, V> { }");
-        assert!(doc.cratemod().impls()[0].bounds_str == Some(~"<T, U, V: Clone>"));
-    }
-
-    #[test]
-    fn should_add_impl_trait_types() {
-        let doc = mk_doc(~"impl j for int { fn a<T>() { } }");
-        assert!(doc.cratemod().impls()[0].trait_types[0] == ~"j");
-    }
-
-    #[test]
-    fn should_not_add_impl_trait_types_if_none() {
-        let doc = mk_doc(~"impl int { fn a() { } }");
-        assert!(doc.cratemod().impls()[0].trait_types.len() == 0);
-    }
-
-    #[test]
-    fn should_add_impl_self_ty() {
-        let doc = mk_doc(~"impl int { fn a() { } }");
-        assert!(doc.cratemod().impls()[0].self_ty == Some(~"int"));
-    }
-
-    #[test]
-    fn should_add_impl_method_sigs() {
-        let doc = mk_doc(~"impl int { fn a<T>(&self) -> int { fail!() } }");
-        assert!(doc.cratemod().impls()[0].methods[0].sig
-                == Some(~"fn a<T>(&self) -> int"));
-    }
-
-    #[test]
-    fn should_add_type_signatures() {
-        let doc = mk_doc(~"type t<T> = int;");
-        assert!(doc.cratemod().types()[0].sig == Some(~"type t<T> = int"));
-    }
-
-    #[test]
-    fn should_add_struct_defs() {
-        let doc = mk_doc(~"struct S { field: () }");
-        assert!(doc.cratemod().structs()[0].sig.unwrap().contains(
-            "struct S {"));
-    }
-
-    #[test]
-    fn should_not_serialize_struct_attrs() {
-        // All we care about are the fields
-        let doc = mk_doc(~"#[wut] struct S { field: () }");
-        assert!(!doc.cratemod().structs()[0].sig.unwrap().contains("wut"));
-    }
-}
diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs
deleted file mode 100644 (file)
index 4c2464f..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Removes the common level of indention from description strings. For
-instance, if an entire doc comment is indented 8 spaces we want to
-remove those 8 spaces from every line.
-
-The first line of a string is allowed to be intend less than
-subsequent lines in the same paragraph in order to account for
-instances where the string containing the doc comment is opened in the
-middle of a line, and each of the following lines is indented.
-*/
-
-
-use std::num;
-use std::uint;
-use pass::Pass;
-use text_pass;
-
-pub fn mk_pass() -> Pass {
-    text_pass::mk_pass(~"unindent", unindent)
-}
-
-fn unindent(s: &str) -> ~str {
-    let lines = s.any_line_iter().collect::<~[&str]>();
-    let mut saw_first_line = false;
-    let mut saw_second_line = false;
-    let min_indent = do lines.iter().fold(uint::max_value)
-        |min_indent, line| {
-
-        // After we see the first non-whitespace line, look at
-        // the line we have. If it is not whitespace, and therefore
-        // part of the first paragraph, then ignore the indentation
-        // level of the first line
-        let ignore_previous_indents =
-            saw_first_line &&
-            !saw_second_line &&
-            !line.is_whitespace();
-
-        let min_indent = if ignore_previous_indents {
-            uint::max_value
-        } else {
-            min_indent
-        };
-
-        if saw_first_line {
-            saw_second_line = true;
-        }
-
-        if line.is_whitespace() {
-            min_indent
-        } else {
-            saw_first_line = true;
-            let mut spaces = 0;
-            do line.iter().all |char| {
-                // Only comparing against space because I wouldn't
-                // know what to do with mixed whitespace chars
-                if char == ' ' {
-                    spaces += 1;
-                    true
-                } else {
-                    false
-                }
-            };
-            num::min(min_indent, spaces)
-        }
-    };
-
-    match lines {
-        [head, .. tail] => {
-            let mut unindented = ~[ head.trim() ];
-            unindented.push_all(do tail.map |&line| {
-                if line.is_whitespace() {
-                    line
-                } else {
-                    assert!(line.len() >= min_indent);
-                    line.slice_from(min_indent)
-                }
-            });
-            unindented.connect("\n")
-        }
-        [] => s.to_owned()
-    }
-}
-
-#[test]
-fn should_unindent() {
-    let s = ~"    line1\n    line2";
-    let r = unindent(s);
-    assert_eq!(r, ~"line1\nline2");
-}
-
-#[test]
-fn should_unindent_multiple_paragraphs() {
-    let s = ~"    line1\n\n    line2";
-    let r = unindent(s);
-    assert_eq!(r, ~"line1\n\nline2");
-}
-
-#[test]
-fn should_leave_multiple_indent_levels() {
-    // Line 2 is indented another level beyond the
-    // base indentation and should be preserved
-    let s = ~"    line1\n\n        line2";
-    let r = unindent(s);
-    assert_eq!(r, ~"line1\n\n    line2");
-}
-
-#[test]
-fn should_ignore_first_line_indent() {
-    // Thi first line of the first paragraph may not be indented as
-    // far due to the way the doc string was written:
-    //
-    // #[doc = "Start way over here
-    //          and continue here"]
-    let s = ~"line1\n    line2";
-    let r = unindent(s);
-    assert_eq!(r, ~"line1\nline2");
-}
-
-#[test]
-fn should_not_ignore_first_line_indent_in_a_single_line_para() {
-    let s = ~"line1\n\n    line2";
-    let r = unindent(s);
-    assert_eq!(r, ~"line1\n\n    line2");
-}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
new file mode 100644 (file)
index 0000000..14be80f
--- /dev/null
@@ -0,0 +1,183 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Rust AST Visitor. Extracts useful information and massages it into a form
+//! usable for clean
+
+use syntax::abi::AbiSet;
+use syntax::{ast, ast_map};
+use syntax::codemap::Span;
+
+use doctree::*;
+use std::local_data;
+
+pub struct RustdocVisitor {
+    module: Module,
+    attrs: ~[ast::Attribute],
+}
+
+impl RustdocVisitor {
+    pub fn new() -> RustdocVisitor {
+        RustdocVisitor {
+            module: Module::new(None),
+            attrs: ~[],
+        }
+    }
+}
+
+impl RustdocVisitor {
+    pub fn visit(@mut self, crate: &ast::Crate) {
+        self.attrs = crate.attrs.clone();
+        fn visit_struct_def(item: &ast::item, sd: @ast::struct_def, generics:
+                            &ast::Generics) -> Struct {
+            debug!("Visiting struct");
+            let struct_type = struct_type_from_def(sd);
+            Struct {
+                id: item.id,
+                struct_type: struct_type,
+                name: item.ident,
+                vis: item.vis,
+                attrs: item.attrs.clone(),
+                generics: generics.clone(),
+                fields: sd.fields.iter().map(|x| (*x).clone()).to_owned_vec(),
+                where: item.span
+            }
+        }
+
+        fn visit_enum_def(it: &ast::item, def: &ast::enum_def, params: &ast::Generics) -> Enum {
+            debug!("Visiting enum");
+            let mut vars: ~[Variant] = ~[];
+            for x in def.variants.iter() {
+                vars.push(Variant {
+                    name: x.node.name,
+                    attrs: x.node.attrs.clone(),
+                    vis: x.node.vis,
+                    id: x.node.id,
+                    kind: x.node.kind.clone(),
+                    where: x.span,
+                });
+            }
+            Enum {
+                name: it.ident,
+                variants: vars,
+                vis: it.vis,
+                generics: params.clone(),
+                attrs: it.attrs.clone(),
+                id: it.id,
+                where: it.span,
+            }
+        }
+
+        fn visit_fn(item: &ast::item, fd: &ast::fn_decl, _purity: &ast::purity,
+                     _abi: &AbiSet, gen: &ast::Generics) -> Function {
+            debug!("Visiting fn");
+            Function {
+                id: item.id,
+                vis: item.vis,
+                attrs: item.attrs.clone(),
+                decl: fd.clone(),
+                name: item.ident,
+                where: item.span,
+                generics: gen.clone(),
+            }
+        }
+
+        fn visit_mod_contents(span: Span, attrs: ~[ast::Attribute], vis:
+                              ast::visibility, id: ast::NodeId, m: &ast::_mod) -> Module {
+            let am = local_data::get(super::ctxtkey, |x| *x.unwrap()).tycx.items;
+            let name = match am.find(&id) {
+                Some(m) => match m {
+                    &ast_map::node_item(ref it, _) => Some(it.ident),
+                    _ => fail!("mod id mapped to non-item in the ast map")
+                },
+                None => None
+            };
+            let mut om = Module::new(name);
+            om.view_items = m.view_items.clone();
+            om.where = span;
+            om.attrs = attrs;
+            om.vis = vis;
+            om.id = id;
+            for i in m.items.iter() {
+                visit_item(*i, &mut om);
+            }
+            om
+        }
+
+        fn visit_item(item: &ast::item, om: &mut Module) {
+            debug!("Visiting item %?", item);
+            match item.node {
+                ast::item_mod(ref m) => {
+                    om.mods.push(visit_mod_contents(item.span, item.attrs.clone(),
+                                                    item.vis, item.id, m));
+                },
+                ast::item_enum(ref ed, ref gen) => om.enums.push(visit_enum_def(item, ed, gen)),
+                ast::item_struct(sd, ref gen) => om.structs.push(visit_struct_def(item, sd, gen)),
+                ast::item_fn(ref fd, ref pur, ref abi, ref gen, _) =>
+                    om.fns.push(visit_fn(item, fd, pur, abi, gen)),
+                ast::item_ty(ref ty, ref gen) => {
+                    let t = Typedef {
+                        ty: ty.clone(),
+                        gen: gen.clone(),
+                        name: item.ident,
+                        id: item.id,
+                        attrs: item.attrs.clone(),
+                        where: item.span,
+                        vis: item.vis,
+                    };
+                    om.typedefs.push(t);
+                },
+                ast::item_static(ref ty, ref mut_, ref exp) => {
+                    let s = Static {
+                        type_: ty.clone(),
+                        mutability: mut_.clone(),
+                        expr: exp.clone(),
+                        id: item.id,
+                        name: item.ident,
+                        attrs: item.attrs.clone(),
+                        where: item.span,
+                        vis: item.vis,
+                    };
+                    om.statics.push(s);
+                },
+                ast::item_trait(ref gen, ref tr, ref met) => {
+                    let t = Trait {
+                        name: item.ident,
+                        methods: met.clone(),
+                        generics: gen.clone(),
+                        parents: tr.clone(),
+                        id: item.id,
+                        attrs: item.attrs.clone(),
+                        where: item.span,
+                        vis: item.vis,
+                    };
+                    om.traits.push(t);
+                },
+                ast::item_impl(ref gen, ref tr, ref ty, ref meths) => {
+                    let i = Impl {
+                        generics: gen.clone(),
+                        trait_: tr.clone(),
+                        for_: ty.clone(),
+                        methods: meths.clone(),
+                        attrs: item.attrs.clone(),
+                        id: item.id,
+                        where: item.span,
+                        vis: item.vis,
+                    };
+                    om.impls.push(i);
+                },
+                _ => (),
+            }
+        }
+
+        self.module = visit_mod_contents(crate.span, crate.attrs.clone(),
+                                         ast::public, ast::CRATE_NODE_ID, &crate.module);
+    }
+}
index 8d61a971157fc35e69687b423794dac6c797753e..368596b3f44707fbcc544f033adbda46012930b4 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #[link(name = "rusti",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc",
        url = "https://github.com/mozilla/rust/tree/master/src/rusti")];
 
index 72ebc55d3e55936a68a1ea9c6188511f44b0e3e2..077d1cf02f86aeac2b6cdff30cc9fc037bb99041 100644 (file)
@@ -11,7 +11,7 @@
 // rustpkg - a package manager and build system for Rust
 
 #[link(name = "rustpkg",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
        url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
 
index 800eca4291f0e0fca432f58dfae3f32dc408c5cb..f496e89acf75dfae2c5e879c221b38f52cb805ce 100644 (file)
@@ -24,7 +24,7 @@
 use iter::{FilterMap, Chain, Repeat, Zip};
 use num;
 use option::{None, Option, Some};
-use rand::RngUtil;
+use rand::Rng;
 use rand;
 use uint;
 use util::replace;
index 94156f6e81ffb8219be1fa5cc64ea89924f89d05..ca524a255ae8630975fc04a78cf173ea5c6bf43a 100644 (file)
@@ -734,7 +734,7 @@ fn from_str_issue7588() {
 #[cfg(test)]
 mod bench {
     use extra::test::BenchHarness;
-    use rand::{XorShiftRng,RngUtil};
+    use rand::{XorShiftRng, Rng};
     use float;
     use to_str::ToStr;
 
index 1dc1d1d677648c923f2a3233921f29e99e5dfd05..08a1f879e7804634c50e1e9e631c170e35c3f8f0 100644 (file)
@@ -1718,7 +1718,7 @@ mod tests {
     use os::{remove_file, setenv, unsetenv};
     use os;
     use path::Path;
-    use rand::RngUtil;
+    use rand::Rng;
     use rand;
     use run;
     use str::StrSlice;
@@ -1738,7 +1738,7 @@ pub fn test_args() {
 
     fn make_rand_name() -> ~str {
         let mut rng = rand::rng();
-        let n = ~"TEST" + rng.gen_str(10u);
+        let n = ~"TEST" + rng.gen_ascii_str(10u);
         assert!(getenv(n).is_none());
         n
     }
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
deleted file mode 100644 (file)
index 7166456..0000000
+++ /dev/null
@@ -1,1225 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-Random number generation.
-
-The key functions are `random()` and `RngUtil::gen()`. These are polymorphic
-and so can be used to generate any type that implements `Rand`. Type inference
-means that often a simple call to `rand::random()` or `rng.gen()` will
-suffice, but sometimes an annotation is required, e.g. `rand::random::<float>()`.
-
-See the `distributions` submodule for sampling random numbers from
-distributions like normal and exponential.
-
-# Examples
-
-~~~ {.rust}
-use std::rand;
-use std::rand::RngUtil;
-
-fn main() {
-    let mut rng = rand::rng();
-    if rng.gen() { // bool
-        printfln!("int: %d, uint: %u", rng.gen(), rng.gen())
-    }
-}
-~~~
-
-~~~ {.rust}
-use std::rand;
-
-fn main () {
-    let tuple_ptr = rand::random::<~(f64, char)>();
-    printfln!(tuple_ptr)
-}
-~~~
-*/
-
-use cast;
-use clone::Clone;
-use cmp;
-use container::Container;
-use int;
-use iter::{Iterator, range, range_step};
-use local_data;
-use num;
-use prelude::*;
-use str;
-use sys;
-use u32;
-use uint;
-use vec;
-use libc::size_t;
-
-#[path="rand/distributions.rs"]
-pub mod distributions;
-
-/// A type that can be randomly generated using an Rng
-pub trait Rand {
-    /// Generates a random instance of this type using the specified source of
-    /// randomness
-    fn rand<R: Rng>(rng: &mut R) -> Self;
-}
-
-impl Rand for int {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> int {
-        if int::bits == 32 {
-            rng.next() as int
-        } else {
-            rng.gen::<i64>() as int
-        }
-    }
-}
-
-impl Rand for i8 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i8 {
-        rng.next() as i8
-    }
-}
-
-impl Rand for i16 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i16 {
-        rng.next() as i16
-    }
-}
-
-impl Rand for i32 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i32 {
-        rng.next() as i32
-    }
-}
-
-impl Rand for i64 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> i64 {
-        (rng.next() as i64 << 32) | rng.next() as i64
-    }
-}
-
-impl Rand for uint {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> uint {
-        if uint::bits == 32 {
-            rng.next() as uint
-        } else {
-            rng.gen::<u64>() as uint
-        }
-    }
-}
-
-impl Rand for u8 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u8 {
-        rng.next() as u8
-    }
-}
-
-impl Rand for u16 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u16 {
-        rng.next() as u16
-    }
-}
-
-impl Rand for u32 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u32 {
-        rng.next()
-    }
-}
-
-impl Rand for u64 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> u64 {
-        (rng.next() as u64 << 32) | rng.next() as u64
-    }
-}
-
-impl Rand for float {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> float {
-        rng.gen::<f64>() as float
-    }
-}
-
-impl Rand for f32 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> f32 {
-        rng.gen::<f64>() as f32
-    }
-}
-
-static SCALE : f64 = (u32::max_value as f64) + 1.0f64;
-impl Rand for f64 {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> f64 {
-        let u1 = rng.next() as f64;
-        let u2 = rng.next() as f64;
-        let u3 = rng.next() as f64;
-
-        ((u1 / SCALE + u2) / SCALE + u3) / SCALE
-    }
-}
-
-impl Rand for bool {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> bool {
-        rng.next() & 1u32 == 1u32
-    }
-}
-
-macro_rules! tuple_impl {
-    // use variables to indicate the arity of the tuple
-    ($($tyvar:ident),* ) => {
-        // the trailing commas are for the 1 tuple
-        impl<
-            $( $tyvar : Rand ),*
-            > Rand for ( $( $tyvar ),* , ) {
-
-            #[inline]
-            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
-                (
-                    // use the $tyvar's to get the appropriate number of
-                    // repeats (they're not actually needed)
-                    $(
-                        _rng.gen::<$tyvar>()
-                    ),*
-                    ,
-                )
-            }
-        }
-    }
-}
-
-impl Rand for () {
-    #[inline]
-    fn rand<R: Rng>(_: &mut R) -> () { () }
-}
-tuple_impl!{A}
-tuple_impl!{A, B}
-tuple_impl!{A, B, C}
-tuple_impl!{A, B, C, D}
-tuple_impl!{A, B, C, D, E}
-tuple_impl!{A, B, C, D, E, F}
-tuple_impl!{A, B, C, D, E, F, G}
-tuple_impl!{A, B, C, D, E, F, G, H}
-tuple_impl!{A, B, C, D, E, F, G, H, I}
-tuple_impl!{A, B, C, D, E, F, G, H, I, J}
-
-impl<T:Rand> Rand for Option<T> {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
-        if rng.gen() {
-            Some(rng.gen())
-        } else {
-            None
-        }
-    }
-}
-
-impl<T: Rand> Rand for ~T {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
-}
-
-impl<T: Rand + 'static> Rand for @T {
-    #[inline]
-    fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
-}
-
-#[abi = "cdecl"]
-pub mod rustrt {
-    use libc::size_t;
-
-    extern {
-        pub fn rand_seed_size() -> size_t;
-        pub fn rand_gen_seed(buf: *mut u8, sz: size_t);
-    }
-}
-
-/// A random number generator
-pub trait Rng {
-    /// Return the next random integer
-    fn next(&mut self) -> u32;
-}
-
-/// A value with a particular weight compared to other values
-pub struct Weighted<T> {
-    /// The numerical weight of this item
-    weight: uint,
-    /// The actual item which is being weighted
-    item: T,
-}
-
-/// Helper functions attached to the Rng type
-pub trait RngUtil {
-    /// Return a random value of a Rand type
-    fn gen<T:Rand>(&mut self) -> T;
-    /**
-     * Return a int randomly chosen from the range [start, end),
-     * failing if start >= end
-     */
-    fn gen_int_range(&mut self, start: int, end: int) -> int;
-    /**
-     * Return a uint randomly chosen from the range [start, end),
-     * failing if start >= end
-     */
-    fn gen_uint_range(&mut self, start: uint, end: uint) -> uint;
-    /**
-     * Return a char randomly chosen from chars, failing if chars is empty
-     */
-    fn gen_char_from(&mut self, chars: &str) -> char;
-    /**
-     * Return a bool with a 1 in n chance of true
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     printfln!("%b", rng.gen_weighted_bool(3));
-     * }
-     * ~~~
-     */
-    fn gen_weighted_bool(&mut self, n: uint) -> bool;
-    /**
-     * Return a random string of the specified length composed of A-Z,a-z,0-9
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     println(rng.gen_str(8));
-     * }
-     * ~~~
-     */
-    fn gen_str(&mut self, len: uint) -> ~str;
-    /**
-     * Return a random byte string of the specified length
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     printfln!(rng.gen_bytes(8));
-     * }
-     * ~~~
-     */
-    fn gen_bytes(&mut self, len: uint) -> ~[u8];
-    /**
-     * Choose an item randomly, failing if values is empty
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     printfln!("%d", rng.choose([1,2,4,8,16,32]));
-     * }
-     * ~~~
-     */
-    fn choose<T:Clone>(&mut self, values: &[T]) -> T;
-    /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Clone>(&mut self, values: &[T]) -> Option<T>;
-    /**
-     * Choose an item respecting the relative weights, failing if the sum of
-     * the weights is 0
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     let x = [rand::Weighted {weight: 4, item: 'a'},
-     *              rand::Weighted {weight: 2, item: 'b'},
-     *              rand::Weighted {weight: 2, item: 'c'}];
-     *     printfln!("%c", rng.choose_weighted(x));
-     * }
-     * ~~~
-     */
-    fn choose_weighted<T:Clone>(&mut self, v : &[Weighted<T>]) -> T;
-    /**
-     * Choose Some(item) respecting the relative weights, returning none if
-     * the sum of the weights is 0
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     let x = [rand::Weighted {weight: 4, item: 'a'},
-     *              rand::Weighted {weight: 2, item: 'b'},
-     *              rand::Weighted {weight: 2, item: 'c'}];
-     *     printfln!(rng.choose_weighted_option(x));
-     * }
-     * ~~~
-     */
-    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
-                                     -> Option<T>;
-    /**
-     * Return a vec containing copies of the items, in order, where
-     * the weight of the item determines how many copies there are
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     let x = [rand::Weighted {weight: 4, item: 'a'},
-     *              rand::Weighted {weight: 2, item: 'b'},
-     *              rand::Weighted {weight: 2, item: 'c'}];
-     *     printfln!(rng.weighted_vec(x));
-     * }
-     * ~~~
-     */
-    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T];
-    /**
-     * Shuffle a vec
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     printfln!(rng.shuffle([1,2,3]));
-     * }
-     * ~~~
-     */
-    fn shuffle<T:Clone>(&mut self, values: &[T]) -> ~[T];
-    /**
-     * Shuffle a mutable vec in place
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     let mut y = [1,2,3];
-     *     rng.shuffle_mut(y);
-     *     printfln!(y);
-     *     rng.shuffle_mut(y);
-     *     printfln!(y);
-     * }
-     * ~~~
-     */
-    fn shuffle_mut<T>(&mut self, values: &mut [T]);
-
-    /**
-     * Sample up to `n` values from an iterator.
-     *
-     * # Example
-     *
-     * ~~~ {.rust}
-     *
-     * use std::rand;
-     * use std::rand::RngUtil;
-     *
-     * fn main() {
-     *     let mut rng = rand::rng();
-     *     let vals = range(1, 100).to_owned_vec();
-     *     let sample = rng.sample(vals.iter(), 5);
-     *     printfln!(sample);
-     * }
-     * ~~~
-     */
-    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A];
-}
-
-/// Extension methods for random number generators
-impl<R: Rng> RngUtil for R {
-    /// Return a random value for a Rand type
-    #[inline]
-    fn gen<T: Rand>(&mut self) -> T {
-        Rand::rand(self)
-    }
-
-    /**
-     * Return an int randomly chosen from the range [start, end),
-     * failing if start >= end
-     */
-    fn gen_int_range(&mut self, start: int, end: int) -> int {
-        assert!(start < end);
-        start + num::abs(self.gen::<int>() % (end - start))
-    }
-
-    /**
-     * Return a uint randomly chosen from the range [start, end),
-     * failing if start >= end
-     */
-    fn gen_uint_range(&mut self, start: uint, end: uint) -> uint {
-        assert!(start < end);
-        start + (self.gen::<uint>() % (end - start))
-    }
-
-    /**
-     * Return a char randomly chosen from chars, failing if chars is empty
-     */
-    fn gen_char_from(&mut self, chars: &str) -> char {
-        assert!(!chars.is_empty());
-        let mut cs = ~[];
-        for c in chars.iter() { cs.push(c) }
-        self.choose(cs)
-    }
-
-    /// Return a bool with a 1-in-n chance of true
-    fn gen_weighted_bool(&mut self, n: uint) -> bool {
-        if n == 0u {
-            true
-        } else {
-            self.gen_uint_range(1u, n + 1u) == 1u
-        }
-    }
-
-    /**
-     * Return a random string of the specified length composed of A-Z,a-z,0-9
-     */
-    fn gen_str(&mut self, len: uint) -> ~str {
-        let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
-                       abcdefghijklmnopqrstuvwxyz\
-                       0123456789";
-        let mut s = ~"";
-        let mut i = 0u;
-        while (i < len) {
-            s = s + str::from_char(self.gen_char_from(charset));
-            i += 1u;
-        }
-        s
-    }
-
-    /// Return a random byte string of the specified length
-    fn gen_bytes(&mut self, len: uint) -> ~[u8] {
-        do vec::from_fn(len) |_i| {
-            self.gen()
-        }
-    }
-
-    /// Choose an item randomly, failing if values is empty
-    fn choose<T:Clone>(&mut self, values: &[T]) -> T {
-        self.choose_option(values).unwrap()
-    }
-
-    /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Clone>(&mut self, values: &[T]) -> Option<T> {
-        if values.is_empty() {
-            None
-        } else {
-            Some(values[self.gen_uint_range(0u, values.len())].clone())
-        }
-    }
-    /**
-     * Choose an item respecting the relative weights, failing if the sum of
-     * the weights is 0
-     */
-    fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
-        self.choose_weighted_option(v).unwrap()
-    }
-
-    /**
-     * Choose Some(item) respecting the relative weights, returning none if
-     * the sum of the weights is 0
-     */
-    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
-                                       -> Option<T> {
-        let mut total = 0u;
-        for item in v.iter() {
-            total += item.weight;
-        }
-        if total == 0u {
-            return None;
-        }
-        let chosen = self.gen_uint_range(0u, total);
-        let mut so_far = 0u;
-        for item in v.iter() {
-            so_far += item.weight;
-            if so_far > chosen {
-                return Some(item.item.clone());
-            }
-        }
-        unreachable!();
-    }
-
-    /**
-     * Return a vec containing copies of the items, in order, where
-     * the weight of the item determines how many copies there are
-     */
-    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T] {
-        let mut r = ~[];
-        for item in v.iter() {
-            for _ in range(0u, item.weight) {
-                r.push(item.item.clone());
-            }
-        }
-        r
-    }
-
-    /// Shuffle a vec
-    fn shuffle<T:Clone>(&mut self, values: &[T]) -> ~[T] {
-        let mut m = values.to_owned();
-        self.shuffle_mut(m);
-        m
-    }
-
-    /// Shuffle a mutable vec in place
-    fn shuffle_mut<T>(&mut self, values: &mut [T]) {
-        let mut i = values.len();
-        while i >= 2u {
-            // invariant: elements with index >= i have been locked in place.
-            i -= 1u;
-            // lock element i in place.
-            values.swap(i, self.gen_uint_range(0u, i + 1u));
-        }
-    }
-
-    /// Randomly sample up to `n` elements from an iterator
-    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
-        let mut reservoir : ~[A] = vec::with_capacity(n);
-        for (i, elem) in iter.enumerate() {
-            if i < n {
-                reservoir.push(elem);
-                loop
-            }
-
-            let k = self.gen_uint_range(0, i + 1);
-            if k < reservoir.len() {
-                reservoir[k] = elem
-            }
-        }
-        reservoir
-    }
-}
-
-/// Create a random number generator with a default algorithm and seed.
-///
-/// It returns the cryptographically-safest `Rng` algorithm currently
-/// available in Rust. If you require a specifically seeded `Rng` for
-/// consistency over time you should pick one algorithm and create the
-/// `Rng` yourself.
-pub fn rng() -> IsaacRng {
-    IsaacRng::new()
-}
-
-/// Create a weak random number generator with a default algorithm and seed.
-///
-/// It returns the fastest `Rng` algorithm currently available in Rust without
-/// consideration for cryptography or security. If you require a specifically
-/// seeded `Rng` for consistency over time you should pick one algorithm and
-/// create the `Rng` yourself.
-pub fn weak_rng() -> XorShiftRng {
-    XorShiftRng::new()
-}
-
-static RAND_SIZE_LEN: u32 = 8;
-static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
-
-/// A random number generator that uses the [ISAAC
-/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
-///
-/// The ISAAC algorithm is suitable for cryptographic purposes.
-pub struct IsaacRng {
-    priv cnt: u32,
-    priv rsl: [u32, .. RAND_SIZE],
-    priv mem: [u32, .. RAND_SIZE],
-    priv a: u32,
-    priv b: u32,
-    priv c: u32
-}
-
-impl IsaacRng {
-    /// Create an ISAAC random number generator with a random seed.
-    pub fn new() -> IsaacRng {
-        IsaacRng::new_seeded(seed())
-    }
-
-    /// Create an ISAAC random number generator with a seed. This can be any
-    /// length, although the maximum number of bytes used is 1024 and any more
-    /// will be silently ignored. A generator constructed with a given seed
-    /// will generate the same sequence of values as all other generators
-    /// constructed with the same seed.
-    pub fn new_seeded(seed: &[u8]) -> IsaacRng {
-        let mut rng = IsaacRng {
-            cnt: 0,
-            rsl: [0, .. RAND_SIZE],
-            mem: [0, .. RAND_SIZE],
-            a: 0, b: 0, c: 0
-        };
-
-        let array_size = sys::size_of_val(&rng.rsl);
-        let copy_length = cmp::min(array_size, seed.len());
-
-        // manually create a &mut [u8] slice of randrsl to copy into.
-        let dest = unsafe { cast::transmute((&mut rng.rsl, array_size)) };
-        vec::bytes::copy_memory(dest, seed, copy_length);
-        rng.init(true);
-        rng
-    }
-
-    /// Create an ISAAC random number generator using the default
-    /// fixed seed.
-    pub fn new_unseeded() -> IsaacRng {
-        let mut rng = IsaacRng {
-            cnt: 0,
-            rsl: [0, .. RAND_SIZE],
-            mem: [0, .. RAND_SIZE],
-            a: 0, b: 0, c: 0
-        };
-        rng.init(false);
-        rng
-    }
-
-    /// Initialises `self`. If `use_rsl` is true, then use the current value
-    /// of `rsl` as a seed, otherwise construct one algorithmically (not
-    /// randomly).
-    fn init(&mut self, use_rsl: bool) {
-        let mut a = 0x9e3779b9;
-        let mut b = a;
-        let mut c = a;
-        let mut d = a;
-        let mut e = a;
-        let mut f = a;
-        let mut g = a;
-        let mut h = a;
-
-        macro_rules! mix(
-            () => {{
-                a^=b<<11; d+=a; b+=c;
-                b^=c>>2;  e+=b; c+=d;
-                c^=d<<8;  f+=c; d+=e;
-                d^=e>>16; g+=d; e+=f;
-                e^=f<<10; h+=e; f+=g;
-                f^=g>>4;  a+=f; g+=h;
-                g^=h<<8;  b+=g; h+=a;
-                h^=a>>9;  c+=h; a+=b;
-            }}
-        );
-
-        do 4.times { mix!(); }
-
-        if use_rsl {
-            macro_rules! memloop (
-                ($arr:expr) => {{
-                    for i in range_step(0u32, RAND_SIZE, 8) {
-                        a+=$arr[i  ]; b+=$arr[i+1];
-                        c+=$arr[i+2]; d+=$arr[i+3];
-                        e+=$arr[i+4]; f+=$arr[i+5];
-                        g+=$arr[i+6]; h+=$arr[i+7];
-                        mix!();
-                        self.mem[i  ]=a; self.mem[i+1]=b;
-                        self.mem[i+2]=c; self.mem[i+3]=d;
-                        self.mem[i+4]=e; self.mem[i+5]=f;
-                        self.mem[i+6]=g; self.mem[i+7]=h;
-                    }
-                }}
-            );
-
-            memloop!(self.rsl);
-            memloop!(self.mem);
-        } else {
-            for i in range_step(0u32, RAND_SIZE, 8) {
-                mix!();
-                self.mem[i  ]=a; self.mem[i+1]=b;
-                self.mem[i+2]=c; self.mem[i+3]=d;
-                self.mem[i+4]=e; self.mem[i+5]=f;
-                self.mem[i+6]=g; self.mem[i+7]=h;
-            }
-        }
-
-        self.isaac();
-    }
-
-    /// Refills the output buffer (`self.rsl`)
-    #[inline]
-    fn isaac(&mut self) {
-        self.c += 1;
-        // abbreviations
-        let mut a = self.a;
-        let mut b = self.b + self.c;
-
-        static MIDPOINT: uint = RAND_SIZE as uint / 2;
-
-        macro_rules! ind (($x:expr) => {
-            self.mem[($x >> 2) & (RAND_SIZE - 1)]
-        });
-        macro_rules! rngstep(
-            ($j:expr, $shift:expr) => {{
-                let base = $j;
-                let mix = if $shift < 0 {
-                    a >> -$shift as uint
-                } else {
-                    a << $shift as uint
-                };
-
-                let x = self.mem[base  + mr_offset];
-                a = (a ^ mix) + self.mem[base + m2_offset];
-                let y = ind!(x) + a + b;
-                self.mem[base + mr_offset] = y;
-
-                b = ind!(y >> RAND_SIZE_LEN) + x;
-                self.rsl[base + mr_offset] = b;
-            }}
-        );
-
-        let r = [(0, MIDPOINT), (MIDPOINT, 0)];
-        for &(mr_offset, m2_offset) in r.iter() {
-            for i in range_step(0u, MIDPOINT, 4) {
-                rngstep!(i + 0, 13);
-                rngstep!(i + 1, -6);
-                rngstep!(i + 2, 2);
-                rngstep!(i + 3, -16);
-            }
-        }
-
-        self.a = a;
-        self.b = b;
-        self.cnt = RAND_SIZE;
-    }
-}
-
-impl Rng for IsaacRng {
-    #[inline]
-    fn next(&mut self) -> u32 {
-        if self.cnt == 0 {
-            // make some more numbers
-            self.isaac();
-        }
-        self.cnt -= 1;
-        self.rsl[self.cnt]
-    }
-}
-
-/// An [Xorshift random number
-/// generator](http://en.wikipedia.org/wiki/Xorshift).
-///
-/// The Xorshift algorithm is not suitable for cryptographic purposes
-/// but is very fast. If you do not know for sure that it fits your
-/// requirements, use a more secure one such as `IsaacRng`.
-pub struct XorShiftRng {
-    priv x: u32,
-    priv y: u32,
-    priv z: u32,
-    priv w: u32,
-}
-
-impl Rng for XorShiftRng {
-    #[inline]
-    fn next(&mut self) -> u32 {
-        let x = self.x;
-        let t = x ^ (x << 11);
-        self.x = self.y;
-        self.y = self.z;
-        self.z = self.w;
-        let w = self.w;
-        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
-        self.w
-    }
-}
-
-impl XorShiftRng {
-    /// Create an xor shift random number generator with a random seed.
-    pub fn new() -> XorShiftRng {
-        #[fixed_stack_segment]; #[inline(never)];
-
-        // generate seeds the same way as seed(), except we have a spceific size
-        let mut s = [0u8, ..16];
-        loop {
-            do s.as_mut_buf |p, sz| {
-                unsafe {
-                    rustrt::rand_gen_seed(p, sz as size_t);
-                }
-            }
-            if !s.iter().all(|x| *x == 0) {
-                break;
-            }
-        }
-        let s: &[u32, ..4] = unsafe { cast::transmute(&s) };
-        XorShiftRng::new_seeded(s[0], s[1], s[2], s[3])
-    }
-
-    /**
-     * Create a random number generator using the specified seed. A generator
-     * constructed with a given seed will generate the same sequence of values
-     * as all other generators constructed with the same seed.
-     */
-    pub fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
-        XorShiftRng {
-            x: x,
-            y: y,
-            z: z,
-            w: w,
-        }
-    }
-}
-
-/// Create a new random seed.
-pub fn seed() -> ~[u8] {
-    #[fixed_stack_segment]; #[inline(never)];
-
-    unsafe {
-        let n = rustrt::rand_seed_size() as uint;
-        let mut s = vec::from_elem(n, 0_u8);
-        do s.as_mut_buf |p, sz| {
-            rustrt::rand_gen_seed(p, sz as size_t)
-        }
-        s
-    }
-}
-
-// used to make space in TLS for a random number generator
-local_data_key!(tls_rng_state: @@mut IsaacRng)
-
-/**
- * Gives back a lazily initialized task-local random number generator,
- * seeded by the system. Intended to be used in method chaining style, ie
- * `task_rng().gen::<int>()`.
- */
-#[inline]
-pub fn task_rng() -> @mut IsaacRng {
-    let r = local_data::get(tls_rng_state, |k| k.map(|&k| *k));
-    match r {
-        None => {
-            let rng = @@mut IsaacRng::new_seeded(seed());
-            local_data::set(tls_rng_state, rng);
-            *rng
-        }
-        Some(rng) => *rng
-    }
-}
-
-// Allow direct chaining with `task_rng`
-impl<R: Rng> Rng for @mut R {
-    #[inline]
-    fn next(&mut self) -> u32 {
-        (**self).next()
-    }
-}
-
-/**
- * Returns a random value of a Rand type, using the task's random number
- * generator.
- */
-#[inline]
-pub fn random<T: Rand>() -> T {
-    task_rng().gen()
-}
-
-#[cfg(test)]
-mod test {
-    use iter::{Iterator, range};
-    use option::{Option, Some};
-    use super::*;
-
-    #[test]
-    fn test_rng_seeded() {
-        let seed = seed();
-        let mut ra = IsaacRng::new_seeded(seed);
-        let mut rb = IsaacRng::new_seeded(seed);
-        assert_eq!(ra.gen_str(100u), rb.gen_str(100u));
-    }
-
-    #[test]
-    fn test_rng_seeded_custom_seed() {
-        // much shorter than generated seeds which are 1024 bytes
-        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let mut ra = IsaacRng::new_seeded(seed);
-        let mut rb = IsaacRng::new_seeded(seed);
-        assert_eq!(ra.gen_str(100u), rb.gen_str(100u));
-    }
-
-    #[test]
-    fn test_rng_seeded_custom_seed2() {
-        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let mut ra = IsaacRng::new_seeded(seed);
-        // Regression test that isaac is actually using the above vector
-        let r = ra.next();
-        error!("%?", r);
-        assert!(r == 890007737u32 // on x86_64
-                     || r == 2935188040u32); // on x86
-    }
-
-    #[test]
-    fn test_gen_int_range() {
-        let mut r = rng();
-        let a = r.gen_int_range(-3, 42);
-        assert!(a >= -3 && a < 42);
-        assert_eq!(r.gen_int_range(0, 1), 0);
-        assert_eq!(r.gen_int_range(-12, -11), -12);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_gen_int_from_fail() {
-        let mut r = rng();
-        r.gen_int_range(5, -2);
-    }
-
-    #[test]
-    fn test_gen_uint_range() {
-        let mut r = rng();
-        let a = r.gen_uint_range(3u, 42u);
-        assert!(a >= 3u && a < 42u);
-        assert_eq!(r.gen_uint_range(0u, 1u), 0u);
-        assert_eq!(r.gen_uint_range(12u, 13u), 12u);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_gen_uint_range_fail() {
-        let mut r = rng();
-        r.gen_uint_range(5u, 2u);
-    }
-
-    #[test]
-    fn test_gen_float() {
-        let mut r = rng();
-        let a = r.gen::<float>();
-        let b = r.gen::<float>();
-        debug!((a, b));
-    }
-
-    #[test]
-    fn test_gen_weighted_bool() {
-        let mut r = rng();
-        assert_eq!(r.gen_weighted_bool(0u), true);
-        assert_eq!(r.gen_weighted_bool(1u), true);
-    }
-
-    #[test]
-    fn test_gen_str() {
-        let mut r = rng();
-        debug!(r.gen_str(10u));
-        debug!(r.gen_str(10u));
-        debug!(r.gen_str(10u));
-        assert_eq!(r.gen_str(0u).len(), 0u);
-        assert_eq!(r.gen_str(10u).len(), 10u);
-        assert_eq!(r.gen_str(16u).len(), 16u);
-    }
-
-    #[test]
-    fn test_gen_bytes() {
-        let mut r = rng();
-        assert_eq!(r.gen_bytes(0u).len(), 0u);
-        assert_eq!(r.gen_bytes(10u).len(), 10u);
-        assert_eq!(r.gen_bytes(16u).len(), 16u);
-    }
-
-    #[test]
-    fn test_choose() {
-        let mut r = rng();
-        assert_eq!(r.choose([1, 1, 1]), 1);
-    }
-
-    #[test]
-    fn test_choose_option() {
-        let mut r = rng();
-        let x: Option<int> = r.choose_option([]);
-        assert!(x.is_none());
-        assert_eq!(r.choose_option([1, 1, 1]), Some(1));
-    }
-
-    #[test]
-    fn test_choose_weighted() {
-        let mut r = rng();
-        assert!(r.choose_weighted([
-            Weighted { weight: 1u, item: 42 },
-        ]) == 42);
-        assert!(r.choose_weighted([
-            Weighted { weight: 0u, item: 42 },
-            Weighted { weight: 1u, item: 43 },
-        ]) == 43);
-    }
-
-    #[test]
-    fn test_choose_weighted_option() {
-        let mut r = rng();
-        assert!(r.choose_weighted_option([
-            Weighted { weight: 1u, item: 42 },
-        ]) == Some(42));
-        assert!(r.choose_weighted_option([
-            Weighted { weight: 0u, item: 42 },
-            Weighted { weight: 1u, item: 43 },
-        ]) == Some(43));
-        let v: Option<int> = r.choose_weighted_option([]);
-        assert!(v.is_none());
-    }
-
-    #[test]
-    fn test_weighted_vec() {
-        let mut r = rng();
-        let empty: ~[int] = ~[];
-        assert_eq!(r.weighted_vec([]), empty);
-        assert!(r.weighted_vec([
-            Weighted { weight: 0u, item: 3u },
-            Weighted { weight: 1u, item: 2u },
-            Weighted { weight: 2u, item: 1u },
-        ]) == ~[2u, 1u, 1u]);
-    }
-
-    #[test]
-    fn test_shuffle() {
-        let mut r = rng();
-        let empty: ~[int] = ~[];
-        assert_eq!(r.shuffle([]), empty);
-        assert_eq!(r.shuffle([1, 1, 1]), ~[1, 1, 1]);
-    }
-
-    #[test]
-    fn test_task_rng() {
-        let mut r = task_rng();
-        r.gen::<int>();
-        assert_eq!(r.shuffle([1, 1, 1]), ~[1, 1, 1]);
-        assert_eq!(r.gen_uint_range(0u, 1u), 0u);
-    }
-
-    #[test]
-    fn test_random() {
-        // not sure how to test this aside from just getting some values
-        let _n : uint = random();
-        let _f : f32 = random();
-        let _o : Option<Option<i8>> = random();
-        let _many : ((),
-                     (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
-                     (u8, i8, u16, i16, u32, i32, u64, i64),
-                     (f32, (f64, (float,)))) = random();
-    }
-
-    #[test]
-    fn compare_isaac_implementation() {
-        #[fixed_stack_segment]; #[inline(never)];
-
-        // This is to verify that the implementation of the ISAAC rng is
-        // correct (i.e. matches the output of the upstream implementation,
-        // which is in the runtime)
-        use libc::size_t;
-
-        #[abi = "cdecl"]
-        mod rustrt {
-            use libc::size_t;
-
-            #[allow(non_camel_case_types)] // runtime type
-            pub enum rust_rng {}
-
-            extern {
-                pub fn rand_new_seeded(buf: *u8, sz: size_t) -> *rust_rng;
-                pub fn rand_next(rng: *rust_rng) -> u32;
-                pub fn rand_free(rng: *rust_rng);
-            }
-        }
-
-        // run against several seeds
-        do 10.times {
-            unsafe {
-                let seed = super::seed();
-                let rt_rng = do seed.as_imm_buf |p, sz| {
-                    rustrt::rand_new_seeded(p, sz as size_t)
-                };
-                let mut rng = IsaacRng::new_seeded(seed);
-
-                do 10000.times {
-                    assert_eq!(rng.next(), rustrt::rand_next(rt_rng));
-                }
-                rustrt::rand_free(rt_rng);
-            }
-        }
-    }
-
-    #[test]
-    fn test_sample() {
-        let MIN_VAL = 1;
-        let MAX_VAL = 100;
-
-        let mut r = rng();
-        let vals = range(MIN_VAL, MAX_VAL).to_owned_vec();
-        let small_sample = r.sample(vals.iter(), 5);
-        let large_sample = r.sample(vals.iter(), vals.len() + 5);
-
-        assert_eq!(small_sample.len(), 5);
-        assert_eq!(large_sample.len(), vals.len());
-
-        assert!(small_sample.iter().all(|e| {
-            **e >= MIN_VAL && **e <= MAX_VAL
-        }));
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use extra::test::BenchHarness;
-    use rand::*;
-    use sys::size_of;
-
-    #[bench]
-    fn rand_xorshift(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        do bh.iter {
-            rng.gen::<uint>();
-        }
-        bh.bytes = size_of::<uint>() as u64;
-    }
-
-    #[bench]
-    fn rand_isaac(bh: &mut BenchHarness) {
-        let mut rng = IsaacRng::new();
-        do bh.iter {
-            rng.gen::<uint>();
-        }
-        bh.bytes = size_of::<uint>() as u64;
-    }
-
-    #[bench]
-    fn rand_shuffle_100(bh: &mut BenchHarness) {
-        let mut rng = XorShiftRng::new();
-        let x : &mut[uint] = [1,..100];
-        do bh.iter {
-            rng.shuffle_mut(x);
-        }
-    }
-}
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
new file mode 100644 (file)
index 0000000..7b753f8
--- /dev/null
@@ -0,0 +1,1106 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+Random number generation.
+
+The key functions are `random()` and `Rng::gen()`. These are polymorphic
+and so can be used to generate any type that implements `Rand`. Type inference
+means that often a simple call to `rand::random()` or `rng.gen()` will
+suffice, but sometimes an annotation is required, e.g. `rand::random::<float>()`.
+
+See the `distributions` submodule for sampling random numbers from
+distributions like normal and exponential.
+
+# Examples
+
+~~~ {.rust}
+use std::rand;
+use std::rand::Rng;
+
+fn main() {
+    let mut rng = rand::rng();
+    if rng.gen() { // bool
+        printfln!("int: %d, uint: %u", rng.gen(), rng.gen())
+    }
+}
+~~~
+
+~~~ {.rust}
+use std::rand;
+
+fn main () {
+    let tuple_ptr = rand::random::<~(f64, char)>();
+    printfln!(tuple_ptr)
+}
+~~~
+*/
+
+use cast;
+use cmp;
+use container::Container;
+use int;
+use iter::{Iterator, range, range_step};
+use local_data;
+use prelude::*;
+use str;
+use sys;
+use u32;
+use u64;
+use uint;
+use vec;
+use libc::size_t;
+
+pub mod distributions;
+
+/// A type that can be randomly generated using an Rng
+pub trait Rand {
+    /// Generates a random instance of this type using the specified source of
+    /// randomness
+    fn rand<R: Rng>(rng: &mut R) -> Self;
+}
+
+impl Rand for int {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> int {
+        if int::bits == 32 {
+            rng.next() as int
+        } else {
+            rng.gen::<i64>() as int
+        }
+    }
+}
+
+impl Rand for i8 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i8 {
+        rng.next() as i8
+    }
+}
+
+impl Rand for i16 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i16 {
+        rng.next() as i16
+    }
+}
+
+impl Rand for i32 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i32 {
+        rng.next() as i32
+    }
+}
+
+impl Rand for i64 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> i64 {
+        (rng.next() as i64 << 32) | rng.next() as i64
+    }
+}
+
+impl Rand for uint {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> uint {
+        if uint::bits == 32 {
+            rng.next() as uint
+        } else {
+            rng.gen::<u64>() as uint
+        }
+    }
+}
+
+impl Rand for u8 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u8 {
+        rng.next() as u8
+    }
+}
+
+impl Rand for u16 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u16 {
+        rng.next() as u16
+    }
+}
+
+impl Rand for u32 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u32 {
+        rng.next()
+    }
+}
+
+impl Rand for u64 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> u64 {
+        (rng.next() as u64 << 32) | rng.next() as u64
+    }
+}
+
+impl Rand for float {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> float {
+        rng.gen::<f64>() as float
+    }
+}
+
+impl Rand for f32 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> f32 {
+        rng.gen::<f64>() as f32
+    }
+}
+
+static SCALE : f64 = (u32::max_value as f64) + 1.0f64;
+impl Rand for f64 {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> f64 {
+        let u1 = rng.next() as f64;
+        let u2 = rng.next() as f64;
+        let u3 = rng.next() as f64;
+
+        ((u1 / SCALE + u2) / SCALE + u3) / SCALE
+    }
+}
+
+impl Rand for bool {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> bool {
+        rng.next() & 1u32 == 1u32
+    }
+}
+
+macro_rules! tuple_impl {
+    // use variables to indicate the arity of the tuple
+    ($($tyvar:ident),* ) => {
+        // the trailing commas are for the 1 tuple
+        impl<
+            $( $tyvar : Rand ),*
+            > Rand for ( $( $tyvar ),* , ) {
+
+            #[inline]
+            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
+                (
+                    // use the $tyvar's to get the appropriate number of
+                    // repeats (they're not actually needed)
+                    $(
+                        _rng.gen::<$tyvar>()
+                    ),*
+                    ,
+                )
+            }
+        }
+    }
+}
+
+impl Rand for () {
+    #[inline]
+    fn rand<R: Rng>(_: &mut R) -> () { () }
+}
+tuple_impl!{A}
+tuple_impl!{A, B}
+tuple_impl!{A, B, C}
+tuple_impl!{A, B, C, D}
+tuple_impl!{A, B, C, D, E}
+tuple_impl!{A, B, C, D, E, F}
+tuple_impl!{A, B, C, D, E, F, G}
+tuple_impl!{A, B, C, D, E, F, G, H}
+tuple_impl!{A, B, C, D, E, F, G, H, I}
+tuple_impl!{A, B, C, D, E, F, G, H, I, J}
+
+impl<T:Rand> Rand for Option<T> {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
+        if rng.gen() {
+            Some(rng.gen())
+        } else {
+            None
+        }
+    }
+}
+
+impl<T: Rand> Rand for ~T {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
+}
+
+impl<T: Rand + 'static> Rand for @T {
+    #[inline]
+    fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
+}
+
+#[abi = "cdecl"]
+pub mod rustrt {
+    use libc::size_t;
+
+    extern {
+        pub fn rand_gen_seed(buf: *mut u8, sz: size_t);
+    }
+}
+
+/// A value with a particular weight compared to other values
+pub struct Weighted<T> {
+    /// The numerical weight of this item
+    weight: uint,
+    /// The actual item which is being weighted
+    item: T,
+}
+
+/// A random number generator
+pub trait Rng {
+    /// Return the next random integer
+    fn next(&mut self) -> u32;
+
+
+    /// Return a random value of a Rand type.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    let rng = rand::task_rng();
+    ///    let x: uint = rng.gen();
+    ///    printfln!(x);
+    ///    printfln!(rng.gen::<(float, bool)>());
+    /// }
+    /// ~~~
+    #[inline(always)]
+    fn gen<T: Rand>(&mut self) -> T {
+        Rand::rand(self)
+    }
+
+    /// Return a random vector of the specified length.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    let rng = rand::task_rng();
+    ///    let x: ~[uint] = rng.gen_vec(10);
+    ///    printfln!(x);
+    ///    printfln!(rng.gen_vec::<(float, bool)>(5));
+    /// }
+    /// ~~~
+    fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
+        vec::from_fn(len, |_| self.gen())
+    }
+
+    /// Generate a random primitive integer in the range [`low`,
+    /// `high`). Fails if `low >= high`.
+    ///
+    /// This gives a uniform distribution (assuming this RNG is itself
+    /// uniform), even for edge cases like `gen_integer_range(0u8,
+    /// 170)`, which a naive modulo operation would return numbers
+    /// less than 85 with double the probability to those greater than
+    /// 85.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    let rng = rand::task_rng();
+    ///    let n: uint = rng.gen_integer_range(0u, 10);
+    ///    printfln!(n);
+    ///    let m: i16 = rng.gen_integer_range(-40, 400);
+    ///    printfln!(m);
+    /// }
+    /// ~~~
+    fn gen_integer_range<T: Rand + Int>(&mut self, low: T, high: T) -> T {
+        assert!(low < high, "RNG.gen_integer_range called with low >= high");
+        let range = (high - low).to_u64();
+        let accept_zone = u64::max_value - u64::max_value % range;
+        loop {
+            let rand = self.gen::<u64>();
+            if rand < accept_zone {
+                return low + NumCast::from(rand % range);
+            }
+        }
+    }
+
+    /// Return a bool with a 1 in n chance of true
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng = rand::rng();
+    ///     printfln!("%b", rng.gen_weighted_bool(3));
+    /// }
+    /// ~~~
+    fn gen_weighted_bool(&mut self, n: uint) -> bool {
+        n == 0 || self.gen_integer_range(0, n) == 0
+    }
+
+    /// Return a random string of the specified length composed of
+    /// A-Z,a-z,0-9.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    println(rand::task_rng().gen_ascii_str(10));
+    /// }
+    /// ~~~
+    fn gen_ascii_str(&mut self, len: uint) -> ~str {
+        static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+                                                             abcdefghijklmnopqrstuvwxyz\
+                                                             0123456789");
+        let mut s = str::with_capacity(len);
+        for _ in range(0, len) {
+            s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
+        }
+        s
+    }
+
+    /// Choose an item randomly, failing if `values` is empty.
+    fn choose<T: Clone>(&mut self, values: &[T]) -> T {
+        self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
+    }
+
+    /// Choose `Some(&item)` randomly, returning `None` if values is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///     printfln!(rand::task_rng().choose_option([1,2,4,8,16,32]));
+    ///     printfln!(rand::task_rng().choose_option([]));
+    /// }
+    /// ~~~
+    fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
+        if values.is_empty() {
+            None
+        } else {
+            Some(&values[self.gen_integer_range(0u, values.len())])
+        }
+    }
+
+    /// Choose an item respecting the relative weights, failing if the sum of
+    /// the weights is 0
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng = rand::rng();
+    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
+    ///              rand::Weighted {weight: 2, item: 'b'},
+    ///              rand::Weighted {weight: 2, item: 'c'}];
+    ///     printfln!("%c", rng.choose_weighted(x));
+    /// }
+    /// ~~~
+    fn choose_weighted<T:Clone>(&mut self, v: &[Weighted<T>]) -> T {
+        self.choose_weighted_option(v).expect("Rng.choose_weighted: total weight is 0")
+    }
+
+    /// Choose Some(item) respecting the relative weights, returning none if
+    /// the sum of the weights is 0
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng = rand::rng();
+    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
+    ///              rand::Weighted {weight: 2, item: 'b'},
+    ///              rand::Weighted {weight: 2, item: 'c'}];
+    ///     printfln!(rng.choose_weighted_option(x));
+    /// }
+    /// ~~~
+    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
+                                       -> Option<T> {
+        let mut total = 0u;
+        for item in v.iter() {
+            total += item.weight;
+        }
+        if total == 0u {
+            return None;
+        }
+        let chosen = self.gen_integer_range(0u, total);
+        let mut so_far = 0u;
+        for item in v.iter() {
+            so_far += item.weight;
+            if so_far > chosen {
+                return Some(item.item.clone());
+            }
+        }
+        unreachable!();
+    }
+
+    /// Return a vec containing copies of the items, in order, where
+    /// the weight of the item determines how many copies there are
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng = rand::rng();
+    ///     let x = [rand::Weighted {weight: 4, item: 'a'},
+    ///              rand::Weighted {weight: 2, item: 'b'},
+    ///              rand::Weighted {weight: 2, item: 'c'}];
+    ///     printfln!(rng.weighted_vec(x));
+    /// }
+    /// ~~~
+    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T] {
+        let mut r = ~[];
+        for item in v.iter() {
+            for _ in range(0u, item.weight) {
+                r.push(item.item.clone());
+            }
+        }
+        r
+    }
+
+    /// Shuffle a vec
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///     printfln!(rand::task_rng().shuffle(~[1,2,3]));
+    /// }
+    /// ~~~
+    fn shuffle<T>(&mut self, values: ~[T]) -> ~[T] {
+        let mut v = values;
+        self.shuffle_mut(v);
+        v
+    }
+
+    /// Shuffle a mutable vector in place.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    let rng = rand::task_rng();
+    ///    let mut y = [1,2,3];
+    ///    rng.shuffle_mut(y);
+    ///    printfln!(y);
+    ///    rng.shuffle_mut(y);
+    ///    printfln!(y);
+    /// }
+    /// ~~~
+    fn shuffle_mut<T>(&mut self, values: &mut [T]) {
+        let mut i = values.len();
+        while i >= 2u {
+            // invariant: elements with index >= i have been locked in place.
+            i -= 1u;
+            // lock element i in place.
+            values.swap(i, self.gen_integer_range(0u, i + 1u));
+        }
+    }
+
+    /// Randomly sample up to `n` elements from an iterator.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// use std::rand;
+    ///
+    /// fn main() {
+    ///    let rng = rand::task_rng();
+    ///    let sample = rng.sample(range(1, 100), 5);
+    ///    printfln!(sample);
+    /// }
+    /// ~~~
+    fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
+        let mut reservoir : ~[A] = vec::with_capacity(n);
+        for (i, elem) in iter.enumerate() {
+            if i < n {
+                reservoir.push(elem);
+                loop
+            }
+
+            let k = self.gen_integer_range(0, i + 1);
+            if k < reservoir.len() {
+                reservoir[k] = elem
+            }
+        }
+        reservoir
+    }
+}
+
+/// Create a random number generator with a default algorithm and seed.
+///
+/// It returns the cryptographically-safest `Rng` algorithm currently
+/// available in Rust. If you require a specifically seeded `Rng` for
+/// consistency over time you should pick one algorithm and create the
+/// `Rng` yourself.
+pub fn rng() -> IsaacRng {
+    IsaacRng::new()
+}
+
+/// Create a weak random number generator with a default algorithm and seed.
+///
+/// It returns the fastest `Rng` algorithm currently available in Rust without
+/// consideration for cryptography or security. If you require a specifically
+/// seeded `Rng` for consistency over time you should pick one algorithm and
+/// create the `Rng` yourself.
+pub fn weak_rng() -> XorShiftRng {
+    XorShiftRng::new()
+}
+
+static RAND_SIZE_LEN: u32 = 8;
+static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
+
+/// A random number generator that uses the [ISAAC
+/// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
+///
+/// The ISAAC algorithm is suitable for cryptographic purposes.
+pub struct IsaacRng {
+    priv cnt: u32,
+    priv rsl: [u32, .. RAND_SIZE],
+    priv mem: [u32, .. RAND_SIZE],
+    priv a: u32,
+    priv b: u32,
+    priv c: u32
+}
+
+impl IsaacRng {
+    /// Create an ISAAC random number generator with a random seed.
+    pub fn new() -> IsaacRng {
+        IsaacRng::new_seeded(seed())
+    }
+
+    /// Create an ISAAC random number generator with a seed. This can be any
+    /// length, although the maximum number of bytes used is 1024 and any more
+    /// will be silently ignored. A generator constructed with a given seed
+    /// will generate the same sequence of values as all other generators
+    /// constructed with the same seed.
+    pub fn new_seeded(seed: &[u8]) -> IsaacRng {
+        let mut rng = IsaacRng {
+            cnt: 0,
+            rsl: [0, .. RAND_SIZE],
+            mem: [0, .. RAND_SIZE],
+            a: 0, b: 0, c: 0
+        };
+
+        let array_size = sys::size_of_val(&rng.rsl);
+        let copy_length = cmp::min(array_size, seed.len());
+
+        // manually create a &mut [u8] slice of randrsl to copy into.
+        let dest = unsafe { cast::transmute((&mut rng.rsl, array_size)) };
+        vec::bytes::copy_memory(dest, seed, copy_length);
+        rng.init(true);
+        rng
+    }
+
+    /// Create an ISAAC random number generator using the default
+    /// fixed seed.
+    pub fn new_unseeded() -> IsaacRng {
+        let mut rng = IsaacRng {
+            cnt: 0,
+            rsl: [0, .. RAND_SIZE],
+            mem: [0, .. RAND_SIZE],
+            a: 0, b: 0, c: 0
+        };
+        rng.init(false);
+        rng
+    }
+
+    /// Initialises `self`. If `use_rsl` is true, then use the current value
+    /// of `rsl` as a seed, otherwise construct one algorithmically (not
+    /// randomly).
+    fn init(&mut self, use_rsl: bool) {
+        let mut a = 0x9e3779b9;
+        let mut b = a;
+        let mut c = a;
+        let mut d = a;
+        let mut e = a;
+        let mut f = a;
+        let mut g = a;
+        let mut h = a;
+
+        macro_rules! mix(
+            () => {{
+                a^=b<<11; d+=a; b+=c;
+                b^=c>>2;  e+=b; c+=d;
+                c^=d<<8;  f+=c; d+=e;
+                d^=e>>16; g+=d; e+=f;
+                e^=f<<10; h+=e; f+=g;
+                f^=g>>4;  a+=f; g+=h;
+                g^=h<<8;  b+=g; h+=a;
+                h^=a>>9;  c+=h; a+=b;
+            }}
+        );
+
+        do 4.times { mix!(); }
+
+        if use_rsl {
+            macro_rules! memloop (
+                ($arr:expr) => {{
+                    for i in range_step(0u32, RAND_SIZE, 8) {
+                        a+=$arr[i  ]; b+=$arr[i+1];
+                        c+=$arr[i+2]; d+=$arr[i+3];
+                        e+=$arr[i+4]; f+=$arr[i+5];
+                        g+=$arr[i+6]; h+=$arr[i+7];
+                        mix!();
+                        self.mem[i  ]=a; self.mem[i+1]=b;
+                        self.mem[i+2]=c; self.mem[i+3]=d;
+                        self.mem[i+4]=e; self.mem[i+5]=f;
+                        self.mem[i+6]=g; self.mem[i+7]=h;
+                    }
+                }}
+            );
+
+            memloop!(self.rsl);
+            memloop!(self.mem);
+        } else {
+            for i in range_step(0u32, RAND_SIZE, 8) {
+                mix!();
+                self.mem[i  ]=a; self.mem[i+1]=b;
+                self.mem[i+2]=c; self.mem[i+3]=d;
+                self.mem[i+4]=e; self.mem[i+5]=f;
+                self.mem[i+6]=g; self.mem[i+7]=h;
+            }
+        }
+
+        self.isaac();
+    }
+
+    /// Refills the output buffer (`self.rsl`)
+    #[inline]
+    fn isaac(&mut self) {
+        self.c += 1;
+        // abbreviations
+        let mut a = self.a;
+        let mut b = self.b + self.c;
+
+        static MIDPOINT: uint = RAND_SIZE as uint / 2;
+
+        macro_rules! ind (($x:expr) => {
+            self.mem[($x >> 2) & (RAND_SIZE - 1)]
+        });
+        macro_rules! rngstep(
+            ($j:expr, $shift:expr) => {{
+                let base = $j;
+                let mix = if $shift < 0 {
+                    a >> -$shift as uint
+                } else {
+                    a << $shift as uint
+                };
+
+                let x = self.mem[base  + mr_offset];
+                a = (a ^ mix) + self.mem[base + m2_offset];
+                let y = ind!(x) + a + b;
+                self.mem[base + mr_offset] = y;
+
+                b = ind!(y >> RAND_SIZE_LEN) + x;
+                self.rsl[base + mr_offset] = b;
+            }}
+        );
+
+        let r = [(0, MIDPOINT), (MIDPOINT, 0)];
+        for &(mr_offset, m2_offset) in r.iter() {
+            for i in range_step(0u, MIDPOINT, 4) {
+                rngstep!(i + 0, 13);
+                rngstep!(i + 1, -6);
+                rngstep!(i + 2, 2);
+                rngstep!(i + 3, -16);
+            }
+        }
+
+        self.a = a;
+        self.b = b;
+        self.cnt = RAND_SIZE;
+    }
+}
+
+impl Rng for IsaacRng {
+    #[inline]
+    fn next(&mut self) -> u32 {
+        if self.cnt == 0 {
+            // make some more numbers
+            self.isaac();
+        }
+        self.cnt -= 1;
+        self.rsl[self.cnt]
+    }
+}
+
+/// An [Xorshift random number
+/// generator](http://en.wikipedia.org/wiki/Xorshift).
+///
+/// The Xorshift algorithm is not suitable for cryptographic purposes
+/// but is very fast. If you do not know for sure that it fits your
+/// requirements, use a more secure one such as `IsaacRng`.
+pub struct XorShiftRng {
+    priv x: u32,
+    priv y: u32,
+    priv z: u32,
+    priv w: u32,
+}
+
+impl Rng for XorShiftRng {
+    #[inline]
+    fn next(&mut self) -> u32 {
+        let x = self.x;
+        let t = x ^ (x << 11);
+        self.x = self.y;
+        self.y = self.z;
+        self.z = self.w;
+        let w = self.w;
+        self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
+        self.w
+    }
+}
+
+impl XorShiftRng {
+    /// Create an xor shift random number generator with a random seed.
+    pub fn new() -> XorShiftRng {
+        #[fixed_stack_segment]; #[inline(never)];
+
+        // generate seeds the same way as seed(), except we have a spceific size
+        let mut s = [0u8, ..16];
+        loop {
+            do s.as_mut_buf |p, sz| {
+                unsafe {
+                    rustrt::rand_gen_seed(p, sz as size_t);
+                }
+            }
+            if !s.iter().all(|x| *x == 0) {
+                break;
+            }
+        }
+        let s: &[u32, ..4] = unsafe { cast::transmute(&s) };
+        XorShiftRng::new_seeded(s[0], s[1], s[2], s[3])
+    }
+
+    /**
+     * Create a random number generator using the specified seed. A generator
+     * constructed with a given seed will generate the same sequence of values
+     * as all other generators constructed with the same seed.
+     */
+    pub fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
+        XorShiftRng {
+            x: x,
+            y: y,
+            z: z,
+            w: w,
+        }
+    }
+}
+
+/// Create a new random seed.
+pub fn seed() -> ~[u8] {
+    #[fixed_stack_segment]; #[inline(never)];
+
+    unsafe {
+        let n = RAND_SIZE * 4;
+        let mut s = vec::from_elem(n as uint, 0_u8);
+        do s.as_mut_buf |p, sz| {
+            rustrt::rand_gen_seed(p, sz as size_t)
+        }
+        s
+    }
+}
+
+// used to make space in TLS for a random number generator
+local_data_key!(tls_rng_state: @@mut IsaacRng)
+
+/**
+ * Gives back a lazily initialized task-local random number generator,
+ * seeded by the system. Intended to be used in method chaining style, ie
+ * `task_rng().gen::<int>()`.
+ */
+#[inline]
+pub fn task_rng() -> @mut IsaacRng {
+    let r = local_data::get(tls_rng_state, |k| k.map(|&k| *k));
+    match r {
+        None => {
+            let rng = @@mut IsaacRng::new_seeded(seed());
+            local_data::set(tls_rng_state, rng);
+            *rng
+        }
+        Some(rng) => *rng
+    }
+}
+
+// Allow direct chaining with `task_rng`
+impl<R: Rng> Rng for @mut R {
+    #[inline]
+    fn next(&mut self) -> u32 {
+        (**self).next()
+    }
+}
+
+/**
+ * Returns a random value of a Rand type, using the task's random number
+ * generator.
+ */
+#[inline]
+pub fn random<T: Rand>() -> T {
+    task_rng().gen()
+}
+
+#[cfg(test)]
+mod test {
+    use iter::{Iterator, range};
+    use option::{Option, Some};
+    use super::*;
+
+    #[test]
+    fn test_rng_seeded() {
+        let seed = seed();
+        let mut ra = IsaacRng::new_seeded(seed);
+        let mut rb = IsaacRng::new_seeded(seed);
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_rng_seeded_custom_seed() {
+        // much shorter than generated seeds which are 1024 bytes
+        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
+        let mut ra = IsaacRng::new_seeded(seed);
+        let mut rb = IsaacRng::new_seeded(seed);
+        assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
+    }
+
+    #[test]
+    fn test_rng_seeded_custom_seed2() {
+        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
+        let mut ra = IsaacRng::new_seeded(seed);
+        // Regression test that isaac is actually using the above vector
+        let r = ra.next();
+        error!("%?", r);
+        assert!(r == 890007737u32 // on x86_64
+                     || r == 2935188040u32); // on x86
+    }
+
+    #[test]
+    fn test_gen_integer_range() {
+        let mut r = rng();
+        for _ in range(0, 1000) {
+            let a = r.gen_integer_range(-3i, 42);
+            assert!(a >= -3 && a < 42);
+            assert_eq!(r.gen_integer_range(0, 1), 0);
+            assert_eq!(r.gen_integer_range(-12, -11), -12);
+        }
+
+        for _ in range(0, 1000) {
+            let a = r.gen_integer_range(10, 42);
+            assert!(a >= 10 && a < 42);
+            assert_eq!(r.gen_integer_range(0, 1), 0);
+            assert_eq!(r.gen_integer_range(3_000_000u, 3_000_001), 3_000_000);
+        }
+
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_gen_integer_range_fail_int() {
+        let mut r = rng();
+        r.gen_integer_range(5i, -2);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_gen_integer_range_fail_uint() {
+        let mut r = rng();
+        r.gen_integer_range(5u, 2u);
+    }
+
+    #[test]
+    fn test_gen_float() {
+        let mut r = rng();
+        let a = r.gen::<float>();
+        let b = r.gen::<float>();
+        debug!((a, b));
+    }
+
+    #[test]
+    fn test_gen_weighted_bool() {
+        let mut r = rng();
+        assert_eq!(r.gen_weighted_bool(0u), true);
+        assert_eq!(r.gen_weighted_bool(1u), true);
+    }
+
+    #[test]
+    fn test_gen_ascii_str() {
+        let mut r = rng();
+        debug!(r.gen_ascii_str(10u));
+        debug!(r.gen_ascii_str(10u));
+        debug!(r.gen_ascii_str(10u));
+        assert_eq!(r.gen_ascii_str(0u).len(), 0u);
+        assert_eq!(r.gen_ascii_str(10u).len(), 10u);
+        assert_eq!(r.gen_ascii_str(16u).len(), 16u);
+    }
+
+    #[test]
+    fn test_gen_vec() {
+        let mut r = rng();
+        assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
+        assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
+        assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
+    }
+
+    #[test]
+    fn test_choose() {
+        let mut r = rng();
+        assert_eq!(r.choose([1, 1, 1]), 1);
+    }
+
+    #[test]
+    fn test_choose_option() {
+        let mut r = rng();
+        let v: &[int] = &[];
+        assert!(r.choose_option(v).is_none());
+
+        let i = 1;
+        let v = [1,1,1];
+        assert_eq!(r.choose_option(v), Some(&i));
+    }
+
+    #[test]
+    fn test_choose_weighted() {
+        let mut r = rng();
+        assert!(r.choose_weighted([
+            Weighted { weight: 1u, item: 42 },
+        ]) == 42);
+        assert!(r.choose_weighted([
+            Weighted { weight: 0u, item: 42 },
+            Weighted { weight: 1u, item: 43 },
+        ]) == 43);
+    }
+
+    #[test]
+    fn test_choose_weighted_option() {
+        let mut r = rng();
+        assert!(r.choose_weighted_option([
+            Weighted { weight: 1u, item: 42 },
+        ]) == Some(42));
+        assert!(r.choose_weighted_option([
+            Weighted { weight: 0u, item: 42 },
+            Weighted { weight: 1u, item: 43 },
+        ]) == Some(43));
+        let v: Option<int> = r.choose_weighted_option([]);
+        assert!(v.is_none());
+    }
+
+    #[test]
+    fn test_weighted_vec() {
+        let mut r = rng();
+        let empty: ~[int] = ~[];
+        assert_eq!(r.weighted_vec([]), empty);
+        assert!(r.weighted_vec([
+            Weighted { weight: 0u, item: 3u },
+            Weighted { weight: 1u, item: 2u },
+            Weighted { weight: 2u, item: 1u },
+        ]) == ~[2u, 1u, 1u]);
+    }
+
+    #[test]
+    fn test_shuffle() {
+        let mut r = rng();
+        let empty: ~[int] = ~[];
+        assert_eq!(r.shuffle(~[]), empty);
+        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
+    }
+
+    #[test]
+    fn test_task_rng() {
+        let mut r = task_rng();
+        r.gen::<int>();
+        assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
+        assert_eq!(r.gen_integer_range(0u, 1u), 0u);
+    }
+
+    #[test]
+    fn test_random() {
+        // not sure how to test this aside from just getting some values
+        let _n : uint = random();
+        let _f : f32 = random();
+        let _o : Option<Option<i8>> = random();
+        let _many : ((),
+                     (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
+                     (u8, i8, u16, i16, u32, i32, u64, i64),
+                     (f32, (f64, (float,)))) = random();
+    }
+
+    #[test]
+    fn test_sample() {
+        let MIN_VAL = 1;
+        let MAX_VAL = 100;
+
+        let mut r = rng();
+        let vals = range(MIN_VAL, MAX_VAL).to_owned_vec();
+        let small_sample = r.sample(vals.iter(), 5);
+        let large_sample = r.sample(vals.iter(), vals.len() + 5);
+
+        assert_eq!(small_sample.len(), 5);
+        assert_eq!(large_sample.len(), vals.len());
+
+        assert!(small_sample.iter().all(|e| {
+            **e >= MIN_VAL && **e <= MAX_VAL
+        }));
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    use extra::test::BenchHarness;
+    use rand::*;
+    use sys::size_of;
+
+    #[bench]
+    fn rand_xorshift(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        do bh.iter {
+            rng.gen::<uint>();
+        }
+        bh.bytes = size_of::<uint>() as u64;
+    }
+
+    #[bench]
+    fn rand_isaac(bh: &mut BenchHarness) {
+        let mut rng = IsaacRng::new();
+        do bh.iter {
+            rng.gen::<uint>();
+        }
+        bh.bytes = size_of::<uint>() as u64;
+    }
+
+    #[bench]
+    fn rand_shuffle_100(bh: &mut BenchHarness) {
+        let mut rng = XorShiftRng::new();
+        let x : &mut[uint] = [1,..100];
+        do bh.iter {
+            rng.shuffle_mut(x);
+        }
+    }
+}
index a8cd9bd66d7de36a0536324f6d91e75fcb2ec96b..6336b1cbe2e783dab3c9c4993ae9f5c8f8fc0ce8 100644 (file)
@@ -1095,7 +1095,7 @@ fn shared_port_close() {
     #[test]
     fn megapipe_stress() {
         use rand;
-        use rand::RngUtil;
+        use rand::Rng;
 
         if util::limit_thread_creation_due_to_osx_and_valgrind() { return; }
 
@@ -1106,7 +1106,7 @@ fn megapipe_stress() {
             let total = stress_factor() + 10;
             let mut rng = rand::rng();
             do total.times {
-                let msgs = rng.gen_uint_range(0, 10);
+                let msgs = rng.gen_integer_range(0u, 10);
                 let pipe_clone = pipe.clone();
                 let end_chan_clone = end_chan.clone();
                 do spawntask_random {
index 22888d79984c2da3293af985f6751c48a8240ae3..87b39f06dcf37436676eb36d2dee78d56224bda1 100644 (file)
@@ -26,7 +26,7 @@
 use rt::rtio::{RemoteCallback, PausibleIdleCallback};
 use borrow::{to_uint};
 use cell::Cell;
-use rand::{XorShiftRng, RngUtil};
+use rand::{XorShiftRng, Rng};
 use iter::range;
 use vec::{OwnedVector};
 
@@ -391,7 +391,7 @@ fn find_work(&mut self) -> Option<~Task> {
     fn try_steals(&mut self) -> Option<~Task> {
         let work_queues = &mut self.work_queues;
         let len = work_queues.len();
-        let start_index = self.rng.gen_uint_range(0, len);
+        let start_index = self.rng.gen_integer_range(0, len);
         for index in range(0, len).map(|i| (i + start_index) % len) {
             match work_queues[index].steal() {
                 Some(task) => {
@@ -1215,18 +1215,22 @@ fn drop(&mut self) {
     #[test]
     fn dont_starve_1() {
         use rt::comm::oneshot;
+        use unstable::running_on_valgrind;
 
-        do stress_factor().times {
-            do run_in_mt_newsched_task {
-                let (port, chan) = oneshot();
+        // FIXME: #9407: should work while serialized on valgrind
+        if !running_on_valgrind() {
+            do stress_factor().times {
+                do run_in_mt_newsched_task {
+                    let (port, chan) = oneshot();
 
-                // This task should not be able to starve the sender;
-                // The sender should get stolen to another thread.
-                do spawntask {
-                    while !port.peek() { }
-                }
+                    // This task should not be able to starve the sender;
+                    // The sender should get stolen to another thread.
+                    do spawntask {
+                        while !port.peek() { }
+                    }
 
-                chan.send(());
+                    chan.send(());
+                }
             }
         }
     }
index 8dcb7d8cd04c89a57c150d9efb9570e6e23849b5..f7b55e977e01ede7ab646655896f6ab24ec32f51 100644 (file)
@@ -49,7 +49,7 @@
 
 
 #[link(name = "std",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "c70c24a7-5551-4f73-8e37-380b11d80be8",
        url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
 
@@ -68,7 +68,7 @@
 #[deny(missing_doc)];
 
 // Make extra accessible for benchmarking
-#[cfg(test)] extern mod extra(vers="0.8-pre");
+#[cfg(test)] extern mod extra(vers="0.8");
 
 // Make std testable by not duplicating lang items. See #2912
 #[cfg(test)] extern mod realstd(name = "std");
index 48270702e0dd51230748db4e9b6c13cc2422a4b6..296abb45e835a4a0192db8d7e90602c0645384d5 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #[link(name = "syntax",
-       vers = "0.8-pre",
+       vers = "0.8",
        uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")];
 
 #[license = "MIT/ASL2"];
diff --git a/src/rt/isaac/rand.h b/src/rt/isaac/rand.h
deleted file mode 100644 (file)
index c28b35e..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-------------------------------------------------------------------------------
-rand.h: definitions for a random number generator
-By Bob Jenkins, 1996, Public Domain
-MODIFIED:
-  960327: Creation (addition of randinit, really)
-  970719: use context, not global variables, for internal state
-  980324: renamed seed to flag
-  980605: recommend RANDSIZL=4 for noncryptography.
-  010626: note this is public domain
-------------------------------------------------------------------------------
-*/
-#ifndef STANDARD
-#include "standard.h"
-#endif
-
-#ifndef RAND
-#define RAND
-#define RANDSIZL   (8)  /* I recommend 8 for crypto, 4 for simulations */
-#define RANDSIZ    (1<<RANDSIZL)
-
-/* context of random number generator */
-struct randctx
-{
-  ub4 randcnt;
-  ub4 randrsl[RANDSIZ];
-  ub4 randmem[RANDSIZ];
-  ub4 randa;
-  ub4 randb;
-  ub4 randc;
-};
-typedef  struct randctx  randctx;
-
-/*
-------------------------------------------------------------------------------
- If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
-------------------------------------------------------------------------------
-*/
-void randinit(randctx *r, word flag);
-
-void isaac(randctx *r);
-
-
-/*
-------------------------------------------------------------------------------
- Call isaac_rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
-------------------------------------------------------------------------------
-*/
-#define isaac_rand(r) \
-   (!(r)->randcnt-- ? \
-     (isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
-     (r)->randrsl[(r)->randcnt])
-
-#endif  /* RAND */
diff --git a/src/rt/isaac/randport.cpp b/src/rt/isaac/randport.cpp
deleted file mode 100644 (file)
index a2928a9..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-------------------------------------------------------------------------------
-rand.c: By Bob Jenkins.  My random number generator, ISAAC.  Public Domain
-MODIFIED:
-  960327: Creation (addition of randinit, really)
-  970719: use context, not global variables, for internal state
-  980324: make a portable version
-  010626: Note this is public domain
-  100725: Mask on use of >32 bits, not on assignment: from Paul Eggert
-------------------------------------------------------------------------------
-*/
-#ifndef STANDARD
-#include "standard.h"
-#endif
-#ifndef RAND
-#include "rand.h"
-#endif
-
-
-#define ind(mm,x)  ((mm)[(x>>2)&(RANDSIZ-1)])
-#define rngstep(mix,a,b,mm,m,m2,r,x) \
-{ \
-  x = *m;  \
-  a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
-  *(m++) = y = (ind(mm,x) + a + b) & 0xffffffff; \
-  *(r++) = b = (ind(mm,y>>RANDSIZL) + x) & 0xffffffff; \
-}
-
-void     isaac(randctx *ctx)
-{
-   ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
-   mm=ctx->randmem; r=ctx->randrsl;
-   a = ctx->randa; b = ctx->randb + (++ctx->randc);
-   for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
-   {
-      rngstep( a<<13, a, b, mm, m, m2, r, x);
-      rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
-      rngstep( a<<2 , a, b, mm, m, m2, r, x);
-      rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
-   }
-   for (m2 = mm; m2<mend; )
-   {
-      rngstep( a<<13, a, b, mm, m, m2, r, x);
-      rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
-      rngstep( a<<2 , a, b, mm, m, m2, r, x);
-      rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
-   }
-   ctx->randb = b; ctx->randa = a;
-}
-
-
-#define mix(a,b,c,d,e,f,g,h) \
-{ \
-   a^=b<<11;              d+=a; b+=c; \
-   b^=(c&0xffffffff)>>2;  e+=b; c+=d; \
-   c^=d<<8;               f+=c; d+=e; \
-   d^=(e&0xffffffff)>>16; g+=d; e+=f; \
-   e^=f<<10;              h+=e; f+=g; \
-   f^=(g&0xffffffff)>>4;  a+=f; g+=h; \
-   g^=h<<8;               b+=g; h+=a; \
-   h^=(a&0xffffffff)>>9;  c+=h; a+=b; \
-}
-
-/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
-void randinit(randctx *ctx, word flag)
-{
-   word i;
-   ub4 a,b,c,d,e,f,g,h;
-   ub4 *m,*r;
-   ctx->randa = ctx->randb = ctx->randc = 0;
-   m=ctx->randmem;
-   r=ctx->randrsl;
-   a=b=c=d=e=f=g=h=0x9e3779b9;  /* the golden ratio */
-
-   for (i=0; i<4; ++i)          /* scramble it */
-   {
-     mix(a,b,c,d,e,f,g,h);
-   }
-
-   if (flag)
-   {
-     /* initialize using the contents of r[] as the seed */
-     for (i=0; i<RANDSIZ; i+=8)
-     {
-       a+=r[i  ]; b+=r[i+1];
-       c+=r[i+2]; d+=r[i+3];
-       e+=r[i+4]; f+=r[i+5];
-       g+=r[i+6]; h+=r[i+7];
-       mix(a,b,c,d,e,f,g,h);
-       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
-       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
-     }
-     /* do a second pass to make all of the seed affect all of m */
-     for (i=0; i<RANDSIZ; i+=8)
-     {
-       a+=m[i  ]; b+=m[i+1];
-       c+=m[i+2]; d+=m[i+3];
-       e+=m[i+4]; f+=m[i+5];
-       g+=m[i+6]; h+=m[i+7];
-       mix(a,b,c,d,e,f,g,h);
-       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
-       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
-     }
-   }
-   else
-   {
-     for (i=0; i<RANDSIZ; i+=8)
-     {
-       /* fill in mm[] with messy stuff */
-       mix(a,b,c,d,e,f,g,h);
-       m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
-       m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
-     }
-   }
-
-   isaac(ctx);            /* fill in the first set of results */
-   ctx->randcnt=RANDSIZ;  /* prepare to use the first set of results */
-}
-
-
-#ifdef NEVER
-int main()
-{
-  ub4 i,j;
-  randctx ctx;
-  ctx.randa=ctx.randb=ctx.randc=(ub4)0;
-  for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
-  randinit(&ctx, TRUE);
-  for (i=0; i<2; ++i)
-  {
-    isaac(&ctx);
-    for (j=0; j<256; ++j)
-    {
-      printf("%.8lx",ctx.randrsl[j]);
-      if ((j&7)==7) printf("\n");
-    }
-  }
-}
-#endif
diff --git a/src/rt/isaac/standard.h b/src/rt/isaac/standard.h
deleted file mode 100644 (file)
index c196a37..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-------------------------------------------------------------------------------
-Standard definitions and types, Bob Jenkins
-------------------------------------------------------------------------------
-*/
-#ifndef STANDARD
-# define STANDARD
-# ifndef STDIO
-#  include <stdio.h>
-#  define STDIO
-# endif
-# ifndef STDDEF
-#  include <stddef.h>
-#  define STDDEF
-# endif
-# ifndef STDINT
-#  include <stdint.h>
-#  define STDINT
-# endif
-
-typedef  uint64_t  ub8;
-#define UB8MAXVAL 0xffffffffffffffffLL
-#define UB8BITS 64
-typedef   int64_t  sb8;
-#define SB8MAXVAL 0x7fffffffffffffffLL
-typedef  uint32_t  ub4;   /* unsigned 4-byte quantities */
-#define UB4MAXVAL 0xffffffff
-typedef   int32_t  sb4;
-#define UB4BITS 32
-#define SB4MAXVAL 0x7fffffff
-typedef  uint16_t  ub2;
-#define UB2MAXVAL 0xffff
-#define UB2BITS 16
-typedef   int16_t  sb2;
-#define SB2MAXVAL 0x7fff
-typedef   uint8_t  ub1;
-#define UB1MAXVAL 0xff
-#define UB1BITS 8
-typedef    int8_t  sb1;   /* signed 1-byte quantities */
-#define SB1MAXVAL 0x7f
-typedef      int  word;  /* fastest type available */
-
-#define bis(target,mask)  ((target) |=  (mask))
-#define bic(target,mask)  ((target) &= ~(mask))
-#define bit(target,mask)  ((target) &   (mask))
-#define TRUE  1
-#define FALSE 0
-#define SUCCESS 0  /* 1 on VAX */
-
-#endif /* STANDARD */
index 8877b082588284a063508a283efd81db6bb66d8b..eeb0c95337a8bce53b5398b4e778ae828fa6f4a3 100644 (file)
@@ -69,35 +69,11 @@ rust_env_pairs() {
 }
 #endif
 
-extern "C" CDECL size_t
-rand_seed_size() {
-    return rng_seed_size();
-}
-
 extern "C" CDECL void
 rand_gen_seed(uint8_t* dest, size_t size) {
     rng_gen_seed(dest, size);
 }
 
-extern "C" CDECL void *
-rand_new_seeded(uint8_t* seed, size_t seed_size) {
-    assert(seed != NULL);
-    rust_rng *rng = (rust_rng *) malloc(sizeof(rust_rng));
-    assert(rng != NULL && "rng alloc failed");
-    rng_init(rng, NULL, seed, seed_size);
-    return rng;
-}
-
-extern "C" CDECL uint32_t
-rand_next(rust_rng *rng) {
-    return rng_gen_u32(rng);
-}
-
-extern "C" CDECL void
-rand_free(rust_rng *rng) {
-    free(rng);
-}
-
 extern "C" CDECL char*
 #if defined(__WIN32__)
 rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
index 27015891feebd74ab7932347125ac31fed9fdec6..89754f94b7096842e1076a92229b044762e34c19 100644 (file)
@@ -32,14 +32,6 @@ win32_require(LPCTSTR fn, BOOL ok) {
 }
 #endif
 
-size_t
-rng_seed_size() {
-    randctx rctx;
-    return sizeof(rctx.randrsl);
-}
-
-// Initialization helpers for ISAAC RNG
-
 void
 rng_gen_seed(uint8_t* dest, size_t size) {
 #ifdef __WIN32__
@@ -80,59 +72,6 @@ rng_gen_seed(uint8_t* dest, size_t size) {
 #endif
 }
 
-static void
-isaac_init(randctx *rctx, char *env_seed,
-           uint8_t* user_seed, size_t seed_len) {
-    memset(rctx, 0, sizeof(randctx));
-
-    if (user_seed != NULL) {
-        // ignore bytes after the required length
-        if (seed_len > sizeof(rctx->randrsl)) {
-            seed_len = sizeof(rctx->randrsl);
-        }
-        memcpy(&rctx->randrsl, user_seed, seed_len);
-    } else if (env_seed != NULL) {
-        ub4 seed = (ub4) atoi(env_seed);
-        for (size_t i = 0; i < RANDSIZ; i ++) {
-            memcpy(&rctx->randrsl[i], &seed, sizeof(ub4));
-            seed = (seed + 0x7ed55d16) + (seed << 12);
-        }
-    } else {
-        rng_gen_seed((uint8_t*)&rctx->randrsl,
-                     sizeof(rctx->randrsl));
-    }
-
-    randinit(rctx, 1);
-}
-
-void
-rng_init(rust_rng* rng, char* env_seed,
-         uint8_t *user_seed, size_t seed_len) {
-    isaac_init(&rng->rctx, env_seed, user_seed, seed_len);
-    rng->reseedable = !user_seed && !env_seed;
-}
-
-static void
-rng_maybe_reseed(rust_rng* rng) {
-    // If this RNG has generated more than 32KB of random data and was not
-    // seeded by the user or RUST_SEED, then we should reseed now.
-    const size_t RESEED_THRESHOLD = 32 * 1024;
-    size_t bytes_generated = rng->rctx.randc * sizeof(ub4);
-    if (bytes_generated < RESEED_THRESHOLD || !rng->reseedable) {
-        return;
-    }
-    rng_gen_seed((uint8_t*)rng->rctx.randrsl,
-                 sizeof(rng->rctx.randrsl));
-    randinit(&rng->rctx, 1);
-}
-
-uint32_t
-rng_gen_u32(rust_rng* rng) {
-    uint32_t x = isaac_rand(&rng->rctx);
-    rng_maybe_reseed(rng);
-    return x;
-}
-
 //
 // Local Variables:
 // mode: C++
index a13b5acd0eff220d0ba06e3ebfd94149586ae6d7..08335a6f73f79ab777bd6bd1ba71c66e710cfb36 100644 (file)
 #ifndef RUST_RNG_H
 #define RUST_RNG_H
 
-#include "rand.h"
-
-class rust_kernel;
-
-// Initialization helpers for ISAAC RNG
-
-struct rust_rng {
-    randctx rctx;
-    bool reseedable;
-};
-
-size_t rng_seed_size();
 void rng_gen_seed(uint8_t* dest, size_t size);
-void rng_init(rust_rng *rng, char *env_seed,
-              uint8_t *user_seed, size_t seed_len);
-uint32_t rng_gen_u32(rust_rng *rng);
 
 //
 // Local Variables:
index 7a9149187d8c711792a01e290eb26f02d734d6a2..186fb387eea500c25b5a184c38cb063c0d97baaa 100644 (file)
@@ -9,11 +9,7 @@ rust_localtime
 rust_timegm
 rust_mktime
 precise_time_ns
-rand_free
-rand_new_seeded
-rand_seed_size
 rand_gen_seed
-rand_next
 rust_path_is_dir
 rust_path_exists
 rust_get_stdin
diff --git a/src/rustdoc_ng/.gitignore b/src/rustdoc_ng/.gitignore
deleted file mode 100644 (file)
index 62f94a1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-*.swp
-main
diff --git a/src/rustdoc_ng/clean.rs b/src/rustdoc_ng/clean.rs
deleted file mode 100644 (file)
index 97a5991..0000000
+++ /dev/null
@@ -1,1094 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module contains the "cleaned" pieces of the AST, and the functions
-//! that clean them.
-
-use its = syntax::parse::token::ident_to_str;
-
-use syntax;
-use syntax::ast;
-use syntax::attr::AttributeMethods;
-
-use std;
-use doctree;
-use visit_ast;
-use std::local_data;
-
-pub trait Clean<T> {
-    fn clean(&self) -> T;
-}
-
-impl<T: Clean<U>, U> Clean<~[U]> for ~[T] {
-    fn clean(&self) -> ~[U] {
-        self.iter().map(|x| x.clean()).collect()
-    }
-}
-impl<T: Clean<U>, U> Clean<U> for @T {
-    fn clean(&self) -> U {
-        (**self).clean()
-    }
-}
-
-impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
-    fn clean(&self) -> Option<U> {
-        match self {
-            &None => None,
-            &Some(ref v) => Some(v.clean())
-        }
-    }
-}
-
-impl<T: Clean<U>, U> Clean<~[U]> for syntax::opt_vec::OptVec<T> {
-    fn clean(&self) -> ~[U] {
-        match self {
-            &syntax::opt_vec::Empty => ~[],
-            &syntax::opt_vec::Vec(ref v) => v.clean()
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Crate {
-    name: ~str,
-    module: Option<Item>,
-}
-
-impl Clean<Crate> for visit_ast::RustdocVisitor {
-    fn clean(&self) -> Crate {
-        use syntax::attr::{find_linkage_metas, last_meta_item_value_str_by_name};
-        let maybe_meta = last_meta_item_value_str_by_name(find_linkage_metas(self.attrs), "name");
-
-        Crate {
-            name: match maybe_meta {
-                Some(x) => x.to_owned(),
-                None => fail!("rustdoc_ng requires a #[link(name=\"foo\")] crate attribute"),
-            },
-            module: Some(self.module.clean()),
-        }
-    }
-}
-
-/// Anything with a source location and set of attributes and, optionally, a
-/// name. That is, anything that can be documented. This doesn't correspond
-/// directly to the AST's concept of an item; it's a strict superset.
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Item {
-    /// Stringified span
-    source: ~str,
-    /// Not everything has a name. E.g., impls
-    name: Option<~str>,
-    attrs: ~[Attribute],
-    inner: ItemEnum,
-    visibility: Option<Visibility>,
-    id: ast::NodeId,
-}
-
-impl Item {
-    /// Finds the `doc` attribute as a List and returns the list of attributes
-    /// nested inside.
-    pub fn doc_list<'a>(&'a self) -> Option<&'a [Attribute]> {
-        for attr in self.attrs.iter() {
-            match *attr {
-                List(~"doc", ref list) => { return Some(list.as_slice()); }
-                _ => {}
-            }
-        }
-        return None;
-    }
-
-    /// Finds the `doc` attribute as a NameValue and returns the corresponding
-    /// value found.
-    pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
-        for attr in self.attrs.iter() {
-            match *attr {
-                NameValue(~"doc", ref v) => { return Some(v.as_slice()); }
-                _ => {}
-            }
-        }
-        return None;
-    }
-
-    pub fn is_mod(&self) -> bool {
-        match self.inner { ModuleItem(*) => true, _ => false }
-    }
-    pub fn is_trait(&self) -> bool {
-        match self.inner { TraitItem(*) => true, _ => false }
-    }
-    pub fn is_struct(&self) -> bool {
-        match self.inner { StructItem(*) => true, _ => false }
-    }
-    pub fn is_enum(&self) -> bool {
-        match self.inner { EnumItem(*) => true, _ => false }
-    }
-    pub fn is_fn(&self) -> bool {
-        match self.inner { FunctionItem(*) => true, _ => false }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum ItemEnum {
-    StructItem(Struct),
-    EnumItem(Enum),
-    FunctionItem(Function),
-    ModuleItem(Module),
-    TypedefItem(Typedef),
-    StaticItem(Static),
-    TraitItem(Trait),
-    ImplItem(Impl),
-    ViewItemItem(ViewItem),
-    TyMethodItem(TyMethod),
-    MethodItem(Method),
-    StructFieldItem(StructField),
-    VariantItem(Variant),
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Module {
-    items: ~[Item],
-}
-
-impl Clean<Item> for doctree::Module {
-    fn clean(&self) -> Item {
-        let name = if self.name.is_some() {
-            self.name.unwrap().clean()
-        } else {
-            ~""
-        };
-        Item {
-            name: Some(name),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            visibility: self.vis.clean(),
-            id: self.id,
-            inner: ModuleItem(Module {
-               items: std::vec::concat(&[self.structs.clean(),
-                              self.enums.clean(), self.fns.clean(),
-                              self.mods.clean(), self.typedefs.clean(),
-                              self.statics.clean(), self.traits.clean(),
-                              self.impls.clean(), self.view_items.clean()])
-            })
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum Attribute {
-    Word(~str),
-    List(~str, ~[Attribute]),
-    NameValue(~str, ~str)
-}
-
-impl Clean<Attribute> for ast::MetaItem {
-    fn clean(&self) -> Attribute {
-        match self.node {
-            ast::MetaWord(s) => Word(s.to_owned()),
-            ast::MetaList(ref s, ref l) => List(s.to_owned(), l.clean()),
-            ast::MetaNameValue(s, ref v) => NameValue(s.to_owned(), lit_to_str(v))
-        }
-    }
-}
-
-impl Clean<Attribute> for ast::Attribute {
-    fn clean(&self) -> Attribute {
-        self.desugar_doc().node.value.clean()
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct TyParam {
-    name: ~str,
-    id: ast::NodeId,
-    bounds: ~[TyParamBound]
-}
-
-impl Clean<TyParam> for ast::TyParam {
-    fn clean(&self) -> TyParam {
-        TyParam {
-            name: self.ident.clean(),
-            id: self.id,
-            bounds: self.bounds.clean(),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum TyParamBound {
-    RegionBound,
-    TraitBound(Type)
-}
-
-impl Clean<TyParamBound> for ast::TyParamBound {
-    fn clean(&self) -> TyParamBound {
-        match *self {
-            ast::RegionTyParamBound => RegionBound,
-            ast::TraitTyParamBound(ref t) => TraitBound(t.clean()),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Lifetime(~str);
-
-impl Clean<Lifetime> for ast::Lifetime {
-    fn clean(&self) -> Lifetime {
-        Lifetime(self.ident.clean())
-    }
-}
-
-// maybe use a Generic enum and use ~[Generic]?
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Generics {
-    lifetimes: ~[Lifetime],
-    type_params: ~[TyParam]
-}
-
-impl Generics {
-    fn new() -> Generics {
-        Generics {
-            lifetimes: ~[],
-            type_params: ~[]
-        }
-    }
-}
-
-impl Clean<Generics> for ast::Generics {
-    fn clean(&self) -> Generics {
-        Generics {
-            lifetimes: self.lifetimes.clean(),
-            type_params: self.ty_params.clean(),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Method {
-    generics: Generics,
-    self_: SelfTy,
-    purity: ast::purity,
-    decl: FnDecl,
-}
-
-impl Clean<Item> for ast::method {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.ident.clean()),
-            attrs: self.attrs.clean(),
-            source: self.span.clean(),
-            id: self.self_id.clone(),
-            visibility: None,
-            inner: MethodItem(Method {
-                generics: self.generics.clean(),
-                self_: self.explicit_self.clean(),
-                purity: self.purity.clone(),
-                decl: self.decl.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct TyMethod {
-    purity: ast::purity,
-    decl: FnDecl,
-    generics: Generics,
-    self_: SelfTy,
-}
-
-impl Clean<Item> for ast::TypeMethod {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.ident.clean()),
-            attrs: self.attrs.clean(),
-            source: self.span.clean(),
-            id: self.id,
-            visibility: None,
-            inner: TyMethodItem(TyMethod {
-                purity: self.purity.clone(),
-                decl: self.decl.clean(),
-                self_: self.explicit_self.clean(),
-                generics: self.generics.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum SelfTy {
-    SelfStatic,
-    SelfValue,
-    SelfBorrowed(Option<Lifetime>, Mutability),
-    SelfManaged(Mutability),
-    SelfOwned,
-}
-
-impl Clean<SelfTy> for ast::explicit_self {
-    fn clean(&self) -> SelfTy {
-        match self.node {
-            ast::sty_static => SelfStatic,
-            ast::sty_value => SelfValue,
-            ast::sty_uniq => SelfOwned,
-            ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
-            ast::sty_box(mt) => SelfManaged(mt.clean()),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Function {
-    decl: FnDecl,
-    generics: Generics,
-}
-
-impl Clean<Item> for doctree::Function {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            visibility: self.vis.clean(),
-            id: self.id,
-            inner: FunctionItem(Function {
-                decl: self.decl.clean(),
-                generics: self.generics.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct ClosureDecl {
-    sigil: ast::Sigil,
-    region: Option<Lifetime>,
-    lifetimes: ~[Lifetime],
-    decl: FnDecl,
-    onceness: ast::Onceness,
-    purity: ast::purity,
-    bounds: ~[TyParamBound]
-}
-
-impl Clean<ClosureDecl> for ast::TyClosure {
-    fn clean(&self) -> ClosureDecl {
-        ClosureDecl {
-            sigil: self.sigil,
-            region: self.region.clean(),
-            lifetimes: self.lifetimes.clean(),
-            decl: self.decl.clean(),
-            onceness: self.onceness,
-            purity: self.purity,
-            bounds: match self.bounds {
-                Some(ref x) => x.clean(),
-                None        => ~[]
-            },
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct FnDecl {
-    inputs: ~[Argument],
-    output: Type,
-    cf: RetStyle,
-    attrs: ~[Attribute]
-}
-
-impl Clean<FnDecl> for ast::fn_decl {
-    fn clean(&self) -> FnDecl {
-        FnDecl {
-            inputs: self.inputs.iter().map(|x| x.clean()).collect(),
-            output: (self.output.clean()),
-            cf: self.cf.clean(),
-            attrs: ~[]
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Argument {
-    type_: Type,
-    name: ~str,
-    id: ast::NodeId
-}
-
-impl Clean<Argument> for ast::arg {
-    fn clean(&self) -> Argument {
-        Argument {
-            name: name_from_pat(self.pat),
-            type_: (self.ty.clean()),
-            id: self.id
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum RetStyle {
-    NoReturn,
-    Return
-}
-
-impl Clean<RetStyle> for ast::ret_style {
-    fn clean(&self) -> RetStyle {
-        match *self {
-            ast::return_val => Return,
-            ast::noreturn => NoReturn
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Trait {
-    methods: ~[TraitMethod],
-    generics: Generics,
-    parents: ~[Type],
-}
-
-impl Clean<Item> for doctree::Trait {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id,
-            visibility: self.vis.clean(),
-            inner: TraitItem(Trait {
-                methods: self.methods.clean(),
-                generics: self.generics.clean(),
-                parents: self.parents.clean(),
-            }),
-        }
-    }
-}
-
-impl Clean<Type> for ast::trait_ref {
-    fn clean(&self) -> Type {
-        let t = Unresolved(self.path.clean(), None, self.ref_id);
-        resolve_type(&t)
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum TraitMethod {
-    Required(Item),
-    Provided(Item),
-}
-
-impl TraitMethod {
-    pub fn is_req(&self) -> bool {
-        match self {
-            &Required(*) => true,
-            _ => false,
-        }
-    }
-    pub fn is_def(&self) -> bool {
-        match self {
-            &Provided(*) => true,
-            _ => false,
-        }
-    }
-    pub fn item<'a>(&'a self) -> &'a Item {
-        match *self {
-            Required(ref item) => item,
-            Provided(ref item) => item,
-        }
-    }
-}
-
-impl Clean<TraitMethod> for ast::trait_method {
-    fn clean(&self) -> TraitMethod {
-        match self {
-            &ast::required(ref t) => Required(t.clean()),
-            &ast::provided(ref t) => Provided(t.clean()),
-        }
-    }
-}
-
-/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
-/// type out of the AST/ty::ctxt given one of these, if more information is needed. Most importantly
-/// it does not preserve mutability or boxes.
-#[deriving(Clone, Encodable, Decodable)]
-pub enum Type {
-    /// Most types start out as "Unresolved". It serves as an intermediate stage between cleaning
-    /// and type resolution.
-    Unresolved(Path, Option<~[TyParamBound]>, ast::NodeId),
-    /// structs/enums/traits (anything that'd be an ast::ty_path)
-    ResolvedPath { path: Path, typarams: Option<~[TyParamBound]>, id: ast::NodeId },
-    /// Reference to an item in an external crate (fully qualified path)
-    External(~str, ~str),
-    // I have no idea how to usefully use this.
-    TyParamBinder(ast::NodeId),
-    /// For parameterized types, so the consumer of the JSON don't go looking
-    /// for types which don't exist anywhere.
-    Generic(ast::NodeId),
-    /// For references to self
-    Self(ast::NodeId),
-    /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
-    Primitive(ast::prim_ty),
-    Closure(~ClosureDecl),
-    /// extern "ABI" fn
-    BareFunction(~BareFunctionDecl),
-    Tuple(~[Type]),
-    Vector(~Type),
-    FixedVector(~Type, ~str),
-    String,
-    Bool,
-    /// aka ty_nil
-    Unit,
-    /// aka ty_bot
-    Bottom,
-    Unique(~Type),
-    Managed(Mutability, ~Type),
-    RawPointer(Mutability, ~Type),
-    BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: ~Type},
-    // region, raw, other boxes, mutable
-}
-
-impl Clean<Type> for ast::Ty {
-    fn clean(&self) -> Type {
-        use syntax::ast::*;
-        debug!("cleaning type `%?`", self);
-        let codemap = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess.codemap;
-        debug!("span corresponds to `%s`", codemap.span_to_str(self.span));
-        let t = match self.node {
-            ty_nil => Unit,
-            ty_ptr(ref m) =>  RawPointer(m.mutbl.clean(), ~resolve_type(&m.ty.clean())),
-            ty_rptr(ref l, ref m) =>
-                BorrowedRef {lifetime: l.clean(), mutability: m.mutbl.clean(),
-                             type_: ~resolve_type(&m.ty.clean())},
-            ty_box(ref m) => Managed(m.mutbl.clean(), ~resolve_type(&m.ty.clean())),
-            ty_uniq(ref m) => Unique(~resolve_type(&m.ty.clean())),
-            ty_vec(ref m) => Vector(~resolve_type(&m.ty.clean())),
-            ty_fixed_length_vec(ref m, ref e) => FixedVector(~resolve_type(&m.ty.clean()),
-                                                             e.span.to_src()),
-            ty_tup(ref tys) => Tuple(tys.iter().map(|x| resolve_type(&x.clean())).collect()),
-            ty_path(ref p, ref tpbs, id) => Unresolved(p.clean(), tpbs.clean(), id),
-            ty_closure(ref c) => Closure(~c.clean()),
-            ty_bare_fn(ref barefn) => BareFunction(~barefn.clean()),
-            ty_bot => Bottom,
-            ref x => fail!("Unimplemented type %?", x),
-        };
-        resolve_type(&t)
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct StructField {
-    type_: Type,
-}
-
-impl Clean<Item> for ast::struct_field {
-    fn clean(&self) -> Item {
-        let (name, vis) = match self.node.kind {
-            ast::named_field(id, vis) => (Some(id), Some(vis)),
-            _ => (None, None)
-        };
-        Item {
-            name: name.clean(),
-            attrs: self.node.attrs.clean(),
-            source: self.span.clean(),
-            visibility: vis,
-            id: self.node.id,
-            inner: StructFieldItem(StructField {
-                type_: self.node.ty.clean(),
-            }),
-        }
-    }
-}
-
-pub type Visibility = ast::visibility;
-
-impl Clean<Option<Visibility>> for ast::visibility {
-    fn clean(&self) -> Option<Visibility> {
-        Some(*self)
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Struct {
-    struct_type: doctree::StructType,
-    generics: Generics,
-    fields: ~[Item],
-}
-
-impl Clean<Item> for doctree::Struct {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id,
-            visibility: self.vis.clean(),
-            inner: StructItem(Struct {
-                struct_type: self.struct_type,
-                generics: self.generics.clean(),
-                fields: self.fields.clean(),
-            }),
-        }
-    }
-}
-
-/// This is a more limited form of the standard Struct, different in that it
-/// it lacks the things most items have (name, id, parameterization). Found
-/// only as a variant in an enum.
-#[deriving(Clone, Encodable, Decodable)]
-pub struct VariantStruct {
-    struct_type: doctree::StructType,
-    fields: ~[Item],
-}
-
-impl Clean<VariantStruct> for syntax::ast::struct_def {
-    fn clean(&self) -> VariantStruct {
-        VariantStruct {
-            struct_type: doctree::struct_type_from_def(self),
-            fields: self.fields.clean(),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Enum {
-    variants: ~[Item],
-    generics: Generics,
-}
-
-impl Clean<Item> for doctree::Enum {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id,
-            visibility: self.vis.clean(),
-            inner: EnumItem(Enum {
-                variants: self.variants.clean(),
-                generics: self.generics.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Variant {
-    kind: VariantKind,
-}
-
-impl Clean<Item> for doctree::Variant {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            visibility: self.vis.clean(),
-            id: self.id,
-            inner: VariantItem(Variant {
-                kind: self.kind.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum VariantKind {
-    CLikeVariant,
-    TupleVariant(~[Type]),
-    StructVariant(VariantStruct),
-}
-
-impl Clean<VariantKind> for ast::variant_kind {
-    fn clean(&self) -> VariantKind {
-        match self {
-            &ast::tuple_variant_kind(ref args) => {
-                if args.len() == 0 {
-                    CLikeVariant
-                } else {
-                    TupleVariant(args.iter().map(|x| x.ty.clean()).collect())
-                }
-            },
-            &ast::struct_variant_kind(ref sd) => StructVariant(sd.clean()),
-        }
-    }
-}
-
-impl Clean<~str> for syntax::codemap::Span {
-    fn clean(&self) -> ~str {
-        let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap;
-        cm.span_to_str(*self)
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Path {
-    global: bool,
-    segments: ~[PathSegment],
-}
-
-impl Clean<Path> for ast::Path {
-    fn clean(&self) -> Path {
-        Path {
-            global: self.global,
-            segments: self.segments.clean()
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct PathSegment {
-    name: ~str,
-    lifetime: Option<Lifetime>,
-    types: ~[Type],
-}
-
-impl Clean<PathSegment> for ast::PathSegment {
-    fn clean(&self) -> PathSegment {
-        PathSegment {
-            name: self.identifier.clean(),
-            lifetime: self.lifetime.clean(),
-            types: self.types.clean()
-        }
-    }
-}
-
-fn path_to_str(p: &ast::Path) -> ~str {
-    use syntax::parse::token::interner_get;
-
-    let mut s = ~"";
-    let mut first = true;
-    for i in p.segments.iter().map(|x| interner_get(x.identifier.name)) {
-        if !first || p.global {
-            s.push_str("::");
-        } else {
-            first = false;
-        }
-        s.push_str(i);
-    }
-    s
-}
-
-impl Clean<~str> for ast::Ident {
-    fn clean(&self) -> ~str {
-        its(self).to_owned()
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Typedef {
-    type_: Type,
-    generics: Generics,
-}
-
-impl Clean<Item> for doctree::Typedef {
-    fn clean(&self) -> Item {
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id.clone(),
-            visibility: self.vis.clean(),
-            inner: TypedefItem(Typedef {
-                type_: self.ty.clean(),
-                generics: self.gen.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct BareFunctionDecl {
-    purity: ast::purity,
-    generics: Generics,
-    decl: FnDecl,
-    abi: ~str
-}
-
-impl Clean<BareFunctionDecl> for ast::TyBareFn {
-    fn clean(&self) -> BareFunctionDecl {
-        BareFunctionDecl {
-            purity: self.purity,
-            generics: Generics {
-                lifetimes: self.lifetimes.clean(),
-                type_params: ~[],
-            },
-            decl: self.decl.clean(),
-            abi: self.abis.to_str(),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Static {
-    type_: Type,
-    mutability: Mutability,
-    /// It's useful to have the value of a static documented, but I have no
-    /// desire to represent expressions (that'd basically be all of the AST,
-    /// which is huge!). So, have a string.
-    expr: ~str,
-}
-
-impl Clean<Item> for doctree::Static {
-    fn clean(&self) -> Item {
-        debug!("claning static %s: %?", self.name.clean(), self);
-        Item {
-            name: Some(self.name.clean()),
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id,
-            visibility: self.vis.clean(),
-            inner: StaticItem(Static {
-                type_: self.type_.clean(),
-                mutability: self.mutability.clean(),
-                expr: self.expr.span.to_src(),
-            }),
-        }
-    }
-}
-
-#[deriving(ToStr, Clone, Encodable, Decodable)]
-pub enum Mutability {
-    Mutable,
-    Immutable,
-}
-
-impl Clean<Mutability> for ast::Mutability {
-    fn clean(&self) -> Mutability {
-        match self {
-            &ast::MutMutable => Mutable,
-            &ast::MutImmutable => Immutable,
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct Impl {
-    generics: Generics,
-    trait_: Option<Type>,
-    for_: Type,
-    methods: ~[Item],
-}
-
-impl Clean<Item> for doctree::Impl {
-    fn clean(&self) -> Item {
-        Item {
-            name: None,
-            attrs: self.attrs.clean(),
-            source: self.where.clean(),
-            id: self.id,
-            visibility: self.vis.clean(),
-            inner: ImplItem(Impl {
-                generics: self.generics.clean(),
-                trait_: self.trait_.clean(),
-                for_: self.for_.clean(),
-                methods: self.methods.clean(),
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub struct ViewItem {
-    inner: ViewItemInner
-}
-
-impl Clean<Item> for ast::view_item {
-    fn clean(&self) -> Item {
-        Item {
-            name: None,
-            attrs: self.attrs.clean(),
-            source: self.span.clean(),
-            id: 0,
-            visibility: self.vis.clean(),
-            inner: ViewItemItem(ViewItem {
-                inner: self.node.clean()
-            }),
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum ViewItemInner {
-    ExternMod(~str, Option<~str>, ~[Attribute], ast::NodeId),
-    Import(~[ViewPath])
-}
-
-impl Clean<ViewItemInner> for ast::view_item_ {
-    fn clean(&self) -> ViewItemInner {
-        match self {
-            &ast::view_item_extern_mod(ref i, ref p, ref mi, ref id) =>
-                ExternMod(i.clean(), p.map(|x| x.to_owned()),  mi.clean(), *id),
-            &ast::view_item_use(ref vp) => Import(vp.clean())
-        }
-    }
-}
-
-#[deriving(Clone, Encodable, Decodable)]
-pub enum ViewPath {
-    SimpleImport(~str, Path, ast::NodeId),
-    GlobImport(Path, ast::NodeId),
-    ImportList(Path, ~[ViewListIdent], ast::NodeId)
-}
-
-impl Clean<ViewPath> for ast::view_path {
-    fn clean(&self) -> ViewPath {
-        match self.node {
-            ast::view_path_simple(ref i, ref p, ref id) => SimpleImport(i.clean(), p.clean(), *id),
-            ast::view_path_glob(ref p, ref id) => GlobImport(p.clean(), *id),
-            ast::view_path_list(ref p, ref pl, ref id) => ImportList(p.clean(), pl.clean(), *id),
-        }
-    }
-}
-
-pub type ViewListIdent = ~str;
-
-impl Clean<ViewListIdent> for ast::path_list_ident {
-    fn clean(&self) -> ViewListIdent {
-        self.node.name.clean()
-    }
-}
-
-// Utilities
-
-trait ToSource {
-    fn to_src(&self) -> ~str;
-}
-
-impl ToSource for syntax::codemap::Span {
-    fn to_src(&self) -> ~str {
-        debug!("converting span %s to snippet", self.clean());
-        let cm = local_data::get(super::ctxtkey, |x| x.unwrap().clone()).sess.codemap.clone();
-        let sn = match cm.span_to_snippet(*self) {
-            Some(x) => x,
-            None    => ~""
-        };
-        debug!("got snippet %s", sn);
-        sn
-    }
-}
-
-fn lit_to_str(lit: &ast::lit) -> ~str {
-    match lit.node {
-        ast::lit_str(st) => st.to_owned(),
-        ast::lit_char(c) => ~"'" + std::char::from_u32(c).unwrap().to_str() + "'",
-        ast::lit_int(i, _t) => i.to_str(),
-        ast::lit_uint(u, _t) => u.to_str(),
-        ast::lit_int_unsuffixed(i) => i.to_str(),
-        ast::lit_float(f, _t) => f.to_str(),
-        ast::lit_float_unsuffixed(f) => f.to_str(),
-        ast::lit_bool(b) => b.to_str(),
-        ast::lit_nil => ~"",
-    }
-}
-
-fn name_from_pat(p: &ast::Pat) -> ~str {
-    use syntax::ast::*;
-    match p.node {
-        PatWild => ~"_",
-        PatIdent(_, ref p, _) => path_to_str(p),
-        PatEnum(ref p, _) => path_to_str(p),
-        PatStruct(*) => fail!("tried to get argument name from pat_struct, \
-                                which is not allowed in function arguments"),
-        PatTup(*) => ~"(tuple arg NYI)",
-        PatBox(p) => name_from_pat(p),
-        PatUniq(p) => name_from_pat(p),
-        PatRegion(p) => name_from_pat(p),
-        PatLit(*) => fail!("tried to get argument name from pat_lit, \
-                            which is not allowed in function arguments"),
-        PatRange(*) => fail!("tried to get argument name from pat_range, \
-                              which is not allowed in function arguments"),
-        PatVec(*) => fail!("tried to get argument name from pat_vec, \
-                             which is not allowed in function arguments")
-    }
-}
-
-fn remove_comment_tags(s: &str) -> ~str {
-    if s.starts_with("/") {
-        match s.slice(0,3) {
-            &"///" => return s.slice(3, s.len()).trim().to_owned(),
-            &"/**" | &"/*!" => return s.slice(3, s.len() - 2).trim().to_owned(),
-            _ => return s.trim().to_owned()
-        }
-    } else {
-        return s.to_owned();
-    }
-}
-
-/// Given a Type, resolve it using the def_map
-fn resolve_type(t: &Type) -> Type {
-    use syntax::ast::*;
-
-    let (path, tpbs, id) = match t {
-        &Unresolved(ref path, ref tbps, id) => (path, tbps, id),
-        _ => return (*t).clone(),
-    };
-
-    let dm = local_data::get(super::ctxtkey, |x| *x.unwrap()).tycx.def_map;
-    debug!("searching for %? in defmap", id);
-    let d = match dm.find(&id) {
-        Some(k) => k,
-        None => {
-            let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
-            debug!("could not find %? in defmap (`%s`)", id,
-                   syntax::ast_map::node_id_to_str(ctxt.tycx.items, id, ctxt.sess.intr()));
-            fail!("Unexpected failure: unresolved id not in defmap (this is a bug!)")
-        }
-    };
-
-    let def_id = match *d {
-        DefFn(i, _) => i,
-        DefSelf(i) | DefSelfTy(i) => return Self(i),
-        DefTy(i) => i,
-        DefTrait(i) => {
-            debug!("saw DefTrait in def_to_id");
-            i
-        },
-        DefPrimTy(p) => match p {
-            ty_str => return String,
-            ty_bool => return Bool,
-            _ => return Primitive(p)
-        },
-        DefTyParam(i, _) => return Generic(i.node),
-        DefStruct(i) => i,
-        DefTyParamBinder(i) => {
-            debug!("found a typaram_binder, what is it? %d", i);
-            return TyParamBinder(i);
-        },
-        x => fail!("resolved type maps to a weird def %?", x),
-    };
-
-    if def_id.crate != ast::CRATE_NODE_ID {
-        use rustc::metadata::decoder::*;
-
-        let sess = local_data::get(super::ctxtkey, |x| *x.unwrap()).sess;
-        let cratedata = ::rustc::metadata::cstore::get_crate_data(sess.cstore, def_id.crate);
-        let doc = lookup_item(def_id.node, cratedata.data);
-        let path = syntax::ast_map::path_to_str_with_sep(item_path(doc), "::", sess.intr());
-        let ty = match def_like_to_def(item_to_def_like(doc, def_id, def_id.crate)) {
-            DefFn(*) => ~"fn",
-            DefTy(*) => ~"enum",
-            DefTrait(*) => ~"trait",
-            DefPrimTy(p) => match p {
-                ty_str => ~"str",
-                ty_bool => ~"bool",
-                ty_int(t) => match t.to_str() {
-                    ~"" => ~"i",
-                    s => s
-                },
-                ty_uint(t) => t.to_str(),
-                ty_float(t) => t.to_str(),
-                ty_char => ~"char",
-            },
-            DefTyParam(*) => ~"generic",
-            DefStruct(*) => ~"struct",
-            DefTyParamBinder(*) => ~"typaram_binder",
-            x => fail!("resolved external maps to a weird def %?", x),
-        };
-        let cname = cratedata.name.to_owned();
-        External(cname + "::" + path, ty)
-    } else {
-        ResolvedPath {path: path.clone(), typarams: tpbs.clone(), id: def_id.node}
-    }
-}
diff --git a/src/rustdoc_ng/core.rs b/src/rustdoc_ng/core.rs
deleted file mode 100644 (file)
index 9fb5e8c..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use rustc;
-use rustc::{driver, middle};
-
-use syntax;
-use syntax::parse;
-use syntax::ast;
-
-use std::os;
-use std::local_data;
-
-use visit_ast::RustdocVisitor;
-use clean;
-use clean::Clean;
-
-pub struct DocContext {
-    crate: @ast::Crate,
-    tycx: middle::ty::ctxt,
-    sess: driver::session::Session
-}
-
-/// Parses, resolves, and typechecks the given crate
-fn get_ast_and_resolve(cpath: &Path, libs: ~[Path]) -> DocContext {
-    use syntax::codemap::dummy_spanned;
-    use rustc::driver::driver::*;
-
-    let parsesess = parse::new_parse_sess(None);
-    let input = file_input(cpath.clone());
-
-    let sessopts = @driver::session::options {
-        binary: @"rustdoc",
-        maybe_sysroot: Some(@os::self_exe_path().unwrap().pop()),
-        addl_lib_search_paths: @mut libs,
-        .. (*rustc::driver::session::basic_options()).clone()
-    };
-
-
-    let diagnostic_handler = syntax::diagnostic::mk_handler(None);
-    let span_diagnostic_handler =
-        syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
-
-    let sess = driver::driver::build_session_(sessopts, parsesess.cm,
-                                                  syntax::diagnostic::emit,
-                                                  span_diagnostic_handler);
-
-    let mut cfg = build_configuration(sess);
-    cfg.push(@dummy_spanned(ast::MetaWord(@"stage2")));
-
-    let mut crate = phase_1_parse_input(sess, cfg.clone(), &input);
-    crate = phase_2_configure_and_expand(sess, cfg, crate);
-    let analysis = phase_3_run_analysis_passes(sess, crate);
-
-    debug!("crate: %?", crate);
-    DocContext { crate: crate, tycx: analysis.ty_cx, sess: sess }
-}
-
-pub fn run_core (libs: ~[Path], path: &Path) -> clean::Crate {
-    let ctxt = @get_ast_and_resolve(path, libs);
-    debug!("defmap:");
-    for (k, v) in ctxt.tycx.def_map.iter() {
-        debug!("%?: %?", k, v);
-    }
-    local_data::set(super::ctxtkey, ctxt);
-
-    let v = @mut RustdocVisitor::new();
-    v.visit(ctxt.crate);
-
-    v.clean()
-}
diff --git a/src/rustdoc_ng/doctree.rs b/src/rustdoc_ng/doctree.rs
deleted file mode 100644 (file)
index 67722b1..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module is used to store stuff from Rust's AST in a more convenient
-//! manner (and with prettier names) before cleaning.
-
-use syntax;
-use syntax::codemap::Span;
-use syntax::ast;
-use syntax::ast::{Ident, NodeId};
-
-pub struct Module {
-    name: Option<Ident>,
-    attrs: ~[ast::Attribute],
-    where: Span,
-    structs: ~[Struct],
-    enums: ~[Enum],
-    fns: ~[Function],
-    mods: ~[Module],
-    id: NodeId,
-    typedefs: ~[Typedef],
-    statics: ~[Static],
-    traits: ~[Trait],
-    vis: ast::visibility,
-    impls: ~[Impl],
-    view_items: ~[ast::view_item],
-}
-
-impl Module {
-    pub fn new(name: Option<Ident>) -> Module {
-        Module {
-            name       : name,
-            id: 0,
-            vis: ast::private,
-            where: syntax::codemap::dummy_sp(),
-            attrs      : ~[],
-            structs    : ~[],
-            enums      : ~[],
-            fns        : ~[],
-            mods       : ~[],
-            typedefs   : ~[],
-            statics    : ~[],
-            traits     : ~[],
-            impls      : ~[],
-            view_items : ~[],
-        }
-    }
-}
-
-#[deriving(ToStr, Clone, Encodable, Decodable)]
-pub enum StructType {
-    /// A normal struct
-    Plain,
-    /// A tuple struct
-    Tuple,
-    /// A newtype struct (tuple struct with one element)
-    Newtype,
-    /// A unit struct
-    Unit
-}
-
-pub enum TypeBound {
-    RegionBound,
-    TraitBound(ast::trait_ref)
-}
-
-pub struct Struct {
-    vis: ast::visibility,
-    id: NodeId,
-    struct_type: StructType,
-    name: Ident,
-    generics: ast::Generics,
-    attrs: ~[ast::Attribute],
-    fields: ~[@ast::struct_field],
-    where: Span,
-}
-
-pub struct Enum {
-    vis: ast::visibility,
-    variants: ~[Variant],
-    generics: ast::Generics,
-    attrs: ~[ast::Attribute],
-    id: NodeId,
-    where: Span,
-    name: Ident,
-}
-
-pub struct Variant {
-    name: Ident,
-    attrs: ~[ast::Attribute],
-    kind: ast::variant_kind,
-    id: ast::NodeId,
-    vis: ast::visibility,
-    where: Span,
-}
-
-pub struct Function {
-    decl: ast::fn_decl,
-    attrs: ~[ast::Attribute],
-    id: NodeId,
-    name: Ident,
-    vis: ast::visibility,
-    where: Span,
-    generics: ast::Generics,
-}
-
-pub struct Typedef {
-    ty: ast::Ty,
-    gen: ast::Generics,
-    name: Ident,
-    id: ast::NodeId,
-    attrs: ~[ast::Attribute],
-    where: Span,
-    vis: ast::visibility,
-}
-
-pub struct Static {
-    type_: ast::Ty,
-    mutability: ast::Mutability,
-    expr: @ast::Expr,
-    name: Ident,
-    attrs: ~[ast::Attribute],
-    vis: ast::visibility,
-    id: ast::NodeId,
-    where: Span,
-}
-
-pub struct Trait {
-    name: Ident,
-    methods: ~[ast::trait_method], //should be TraitMethod
-    generics: ast::Generics,
-    parents: ~[ast::trait_ref],
-    attrs: ~[ast::Attribute],
-    id: ast::NodeId,
-    where: Span,
-    vis: ast::visibility,
-}
-
-pub struct Impl {
-    generics: ast::Generics,
-    trait_: Option<ast::trait_ref>,
-    for_: ast::Ty,
-    methods: ~[@ast::method],
-    attrs: ~[ast::Attribute],
-    where: Span,
-    vis: ast::visibility,
-    id: ast::NodeId,
-}
-
-pub fn struct_type_from_def(sd: &ast::struct_def) -> StructType {
-    if sd.ctor_id.is_some() {
-        // We are in a tuple-struct
-        match sd.fields.len() {
-            0 => Unit,
-            1 => Newtype,
-            _ => Tuple
-        }
-    } else {
-        Plain
-    }
-}
diff --git a/src/rustdoc_ng/fold.rs b/src/rustdoc_ng/fold.rs
deleted file mode 100644 (file)
index ae74f4e..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std;
-use clean::*;
-use std::iter::Extendable;
-
-pub trait DocFolder {
-    fn fold_item(&mut self, item: Item) -> Option<Item> {
-        self.fold_item_recur(item)
-    }
-
-    /// don't override!
-    fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
-        use std::util::swap;
-        let Item { attrs, name, source, visibility, id, inner } = item;
-        let inner = inner;
-        let c = |x| self.fold_item(x);
-        let inner = match inner {
-            StructItem(i) => {
-                let mut i = i;
-                let mut foo = ~[]; swap(&mut foo, &mut i.fields);
-                i.fields.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
-                StructItem(i)
-            },
-            ModuleItem(i) => {
-                ModuleItem(self.fold_mod(i))
-            },
-            EnumItem(i) => {
-                let mut i = i;
-                let mut foo = ~[]; swap(&mut foo, &mut i.variants);
-                i.variants.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
-                EnumItem(i)
-            },
-            TraitItem(i) => {
-                fn vtrm<T: DocFolder>(this: &mut T, trm: TraitMethod) -> Option<TraitMethod> {
-                    match trm {
-                        Required(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(Required(x)),
-                                None => return None,
-                            }
-                        },
-                        Provided(it) => {
-                            match this.fold_item(it) {
-                                Some(x) => return Some(Provided(x)),
-                                None => return None,
-                            }
-                        },
-                    }
-                }
-                let mut i = i;
-                let mut foo = ~[]; swap(&mut foo, &mut i.methods);
-                i.methods.extend(&mut foo.move_iter().filter_map(|x| vtrm(self, x)));
-                TraitItem(i)
-            },
-            ImplItem(i) => {
-                let mut i = i;
-                let mut foo = ~[]; swap(&mut foo, &mut i.methods);
-                i.methods.extend(&mut foo.move_iter().filter_map(|x| self.fold_item(x)));
-                ImplItem(i)
-            },
-            VariantItem(i) => {
-                let i2 = i.clone(); // this clone is small
-                match i.kind {
-                    StructVariant(j) => {
-                        let mut j = j;
-                        let mut foo = ~[]; swap(&mut foo, &mut j.fields);
-                        j.fields.extend(&mut foo.move_iter().filter_map(c));
-                        VariantItem(Variant {kind: StructVariant(j), ..i2})
-                    },
-                    _ => VariantItem(i2)
-                }
-            },
-            x => x
-        };
-
-        Some(Item { attrs: attrs, name: name, source: source, inner: inner,
-                    visibility: visibility, id: id })
-    }
-
-    fn fold_mod(&mut self, m: Module) -> Module {
-        Module { items: m.items.move_iter().filter_map(|i| self.fold_item(i)).collect() }
-    }
-
-    fn fold_crate(&mut self, mut c: Crate) -> Crate {
-        c.module = match std::util::replace(&mut c.module, None) {
-            Some(module) => self.fold_item(module), None => None
-        };
-        return c;
-    }
-}
diff --git a/src/rustdoc_ng/html/format.rs b/src/rustdoc_ng/html/format.rs
deleted file mode 100644 (file)
index 4d0f692..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt;
-use std::local_data;
-use std::rt::io;
-
-use syntax::ast;
-
-use clean;
-use html::render::{cache_key, current_location_key};
-
-pub struct VisSpace(Option<ast::visibility>);
-pub struct Method<'self>(&'self clean::SelfTy, &'self clean::FnDecl);
-
-impl fmt::Default for clean::Generics {
-    fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) {
-        if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return }
-        f.buf.write("&lt;".as_bytes());
-
-        for (i, life) in g.lifetimes.iter().enumerate() {
-            if i > 0 { f.buf.write(", ".as_bytes()); }
-            write!(f.buf, "{}", *life);
-        }
-
-        if g.type_params.len() > 0 {
-            if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); }
-
-            for (i, tp) in g.type_params.iter().enumerate() {
-                if i > 0 { f.buf.write(", ".as_bytes()) }
-                f.buf.write(tp.name.as_bytes());
-
-                if tp.bounds.len() > 0 {
-                    f.buf.write(": ".as_bytes());
-                    for (i, bound) in tp.bounds.iter().enumerate() {
-                        if i > 0 { f.buf.write(" + ".as_bytes()); }
-                        write!(f.buf, "{}", *bound);
-                    }
-                }
-            }
-        }
-        f.buf.write("&gt;".as_bytes());
-    }
-}
-
-impl fmt::Default for clean::Lifetime {
-    fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) {
-        f.buf.write("'".as_bytes());
-        f.buf.write(l.as_bytes());
-    }
-}
-
-impl fmt::Default for clean::TyParamBound {
-    fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) {
-        match *bound {
-            clean::RegionBound => {
-                f.buf.write("'static".as_bytes())
-            }
-            clean::TraitBound(ref ty) => {
-                write!(f.buf, "{}", *ty);
-            }
-        }
-    }
-}
-
-impl fmt::Default for clean::Path {
-    fn fmt(path: &clean::Path, f: &mut fmt::Formatter) {
-        if path.global { f.buf.write("::".as_bytes()) }
-        for (i, seg) in path.segments.iter().enumerate() {
-            if i > 0 { f.buf.write("::".as_bytes()) }
-            f.buf.write(seg.name.as_bytes());
-
-            if seg.lifetime.is_some() || seg.types.len() > 0 {
-                f.buf.write("&lt;".as_bytes());
-                match seg.lifetime {
-                    Some(ref lifetime) => write!(f.buf, "{}", *lifetime),
-                    None => {}
-                }
-                for (i, ty) in seg.types.iter().enumerate() {
-                    if i > 0 || seg.lifetime.is_some() {
-                        f.buf.write(", ".as_bytes());
-                    }
-                    write!(f.buf, "{}", *ty);
-                }
-                f.buf.write("&gt;".as_bytes());
-            }
-        }
-    }
-}
-
-fn resolved_path(w: &mut io::Writer, id: ast::NodeId, path: &clean::Path) {
-    // The generics will get written to both the title and link
-    let mut generics = ~"";
-    let last = path.segments.last();
-    if last.lifetime.is_some() || last.types.len() > 0 {
-        generics.push_str("&lt;");
-        match last.lifetime {
-            Some(ref lifetime) => generics.push_str(format!("{}", *lifetime)),
-            None => {}
-        }
-        for (i, ty) in last.types.iter().enumerate() {
-            if i > 0 || last.lifetime.is_some() {
-                generics.push_str(", ");
-            }
-            generics.push_str(format!("{}", *ty));
-        }
-        generics.push_str("&gt;");
-    }
-
-    // Did someone say rightward-drift?
-    do local_data::get(current_location_key) |loc| {
-        let loc = loc.unwrap();
-        do local_data::get(cache_key) |cache| {
-            do cache.unwrap().read |cache| {
-                match cache.paths.find(&id) {
-                    // This is a documented path, link to it!
-                    Some(&(ref fqp, shortty)) => {
-                        let fqn = fqp.connect("::");
-                        let mut same = 0;
-                        for (a, b) in loc.iter().zip(fqp.iter()) {
-                            if *a == *b {
-                                same += 1;
-                            } else {
-                                break;
-                            }
-                        }
-
-                        let mut url = ~"";
-                        for _ in range(same, loc.len()) {
-                            url.push_str("../");
-                        }
-                        if same == fqp.len() {
-                            url.push_str(shortty);
-                            url.push_str(".");
-                            url.push_str(*fqp.last());
-                            url.push_str(".html");
-                        } else {
-                            let remaining = fqp.slice_from(same);
-                            let to_link = remaining.slice_to(remaining.len() - 1);
-                            for component in to_link.iter() {
-                                url.push_str(*component);
-                                url.push_str("/");
-                            }
-                            url.push_str(shortty);
-                            url.push_str(".");
-                            url.push_str(*remaining.last());
-                            url.push_str(".html");
-                        }
-
-                        write!(w, "<a class='{}' href='{}' title='{}'>{}</a>{}",
-                               shortty, url, fqn, last.name, generics);
-                    }
-                    None => {
-                        write!(w, "{}{}", last.name, generics);
-                    }
-                };
-            }
-        }
-    }
-}
-
-impl fmt::Default for clean::Type {
-    fn fmt(g: &clean::Type, f: &mut fmt::Formatter) {
-        match *g {
-            clean::TyParamBinder(id) | clean::Generic(id) => {
-                do local_data::get(cache_key) |cache| {
-                    do cache.unwrap().read |m| {
-                        f.buf.write(m.typarams.get(&id).as_bytes());
-                    }
-                }
-            }
-            clean::Unresolved(*) => unreachable!(),
-            clean::ResolvedPath{id, typarams: ref typarams, path: ref path} => {
-                resolved_path(f.buf, id, path);
-                match *typarams {
-                    Some(ref params) => {
-                        f.buf.write("&lt;".as_bytes());
-                        for (i, param) in params.iter().enumerate() {
-                            if i > 0 { f.buf.write(", ".as_bytes()) }
-                            write!(f.buf, "{}", *param);
-                        }
-                        f.buf.write("&gt;".as_bytes());
-                    }
-                    None => {}
-                }
-            }
-            // XXX: this should be a link
-            clean::External(ref a, _) => {
-                write!(f.buf, "{}", *a);
-            }
-            clean::Self(*) => f.buf.write("Self".as_bytes()),
-            clean::Primitive(prim) => {
-                let s = match prim {
-                    ast::ty_int(ast::ty_i) => "int",
-                    ast::ty_int(ast::ty_i8) => "i8",
-                    ast::ty_int(ast::ty_i16) => "i16",
-                    ast::ty_int(ast::ty_i32) => "i32",
-                    ast::ty_int(ast::ty_i64) => "i64",
-                    ast::ty_uint(ast::ty_u) => "uint",
-                    ast::ty_uint(ast::ty_u8) => "u8",
-                    ast::ty_uint(ast::ty_u16) => "u16",
-                    ast::ty_uint(ast::ty_u32) => "u32",
-                    ast::ty_uint(ast::ty_u64) => "u64",
-                    ast::ty_float(ast::ty_f) => "float",
-                    ast::ty_float(ast::ty_f32) => "f32",
-                    ast::ty_float(ast::ty_f64) => "f64",
-                    ast::ty_str => "str",
-                    ast::ty_bool => "bool",
-                    ast::ty_char => "char",
-                };
-                f.buf.write(s.as_bytes());
-            }
-            clean::Closure(ref decl) => {
-                f.buf.write(match decl.sigil {
-                    ast::BorrowedSigil => "&amp;",
-                    ast::ManagedSigil => "@",
-                    ast::OwnedSigil => "~",
-                }.as_bytes());
-                match decl.region {
-                    Some(ref region) => write!(f.buf, "{} ", *region),
-                    None => {}
-                }
-                write!(f.buf, "{}{}fn{}",
-                       match decl.purity {
-                           ast::unsafe_fn => "unsafe ",
-                           ast::extern_fn => "extern ",
-                           ast::impure_fn => ""
-                       },
-                       match decl.onceness {
-                           ast::Once => "once ",
-                           ast::Many => "",
-                       },
-                       decl.decl);
-                // XXX: where are bounds and lifetimes printed?!
-            }
-            clean::BareFunction(ref decl) => {
-                write!(f.buf, "{}{}fn{}{}",
-                       match decl.purity {
-                           ast::unsafe_fn => "unsafe ",
-                           ast::extern_fn => "extern ",
-                           ast::impure_fn => ""
-                       },
-                       match decl.abi {
-                           ~"" | ~"\"Rust\"" => ~"",
-                           ref s => " " + *s + " ",
-                       },
-                       decl.generics,
-                       decl.decl);
-            }
-            clean::Tuple(ref typs) => {
-                f.buf.write("(".as_bytes());
-                for (i, typ) in typs.iter().enumerate() {
-                    if i > 0 { f.buf.write(", ".as_bytes()) }
-                    write!(f.buf, "{}", *typ);
-                }
-                f.buf.write(")".as_bytes());
-            }
-            clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
-            clean::FixedVector(ref t, ref s) => {
-                write!(f.buf, "[{}, ..{}]", **t, *s);
-            }
-            clean::String => f.buf.write("str".as_bytes()),
-            clean::Bool => f.buf.write("bool".as_bytes()),
-            clean::Unit => f.buf.write("()".as_bytes()),
-            clean::Bottom => f.buf.write("!".as_bytes()),
-            clean::Unique(ref t) => write!(f.buf, "~{}", **t),
-            clean::Managed(m, ref t) => {
-                write!(f.buf, "@{}{}",
-                       match m {
-                           clean::Mutable => "mut ",
-                           clean::Immutable => "",
-                       }, **t)
-            }
-            clean::RawPointer(m, ref t) => {
-                write!(f.buf, "*{}{}",
-                       match m {
-                           clean::Mutable => "mut ",
-                           clean::Immutable => "",
-                       }, **t)
-            }
-            clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
-                let lt = match *l { Some(ref l) => format!("{} ", *l), _ => ~"" };
-                write!(f.buf, "&amp;{}{}{}",
-                       lt,
-                       match mutability {
-                           clean::Mutable => "mut ",
-                           clean::Immutable => "",
-                       },
-                       **ty);
-            }
-        }
-    }
-}
-
-impl fmt::Default for clean::FnDecl {
-    fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) {
-        let mut args = ~"";
-        for (i, input) in d.inputs.iter().enumerate() {
-            if i > 0 { args.push_str(", "); }
-            if input.name.len() > 0 {
-                args.push_str(format!("{}: ", input.name));
-            }
-            args.push_str(format!("{}", input.type_));
-        }
-        write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
-               args = args,
-               arrow = match d.output { clean::Unit => "no", _ => "yes" },
-               ret = d.output);
-    }
-}
-
-impl<'self> fmt::Default for Method<'self> {
-    fn fmt(m: &Method<'self>, f: &mut fmt::Formatter) {
-        let Method(selfty, d) = *m;
-        let mut args = ~"";
-        match *selfty {
-            clean::SelfStatic => {},
-            clean::SelfValue => args.push_str("self"),
-            clean::SelfOwned => args.push_str("~self"),
-            clean::SelfManaged(clean::Mutable) => args.push_str("@mut self"),
-            clean::SelfManaged(clean::Immutable) => args.push_str("@self"),
-            clean::SelfBorrowed(Some(ref lt), clean::Immutable) => {
-                args.push_str(format!("&amp;{} self", *lt));
-            }
-            clean::SelfBorrowed(Some(ref lt), clean::Mutable) => {
-                args.push_str(format!("&amp;{} mut self", *lt));
-            }
-            clean::SelfBorrowed(None, clean::Mutable) => {
-                args.push_str("&amp;mut self");
-            }
-            clean::SelfBorrowed(None, clean::Immutable) => {
-                args.push_str("&amp;self");
-            }
-        }
-        for (i, input) in d.inputs.iter().enumerate() {
-            if i > 0 || args.len() > 0 { args.push_str(", "); }
-            if input.name.len() > 0 {
-                args.push_str(format!("{}: ", input.name));
-            }
-            args.push_str(format!("{}", input.type_));
-        }
-        write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
-               args = args,
-               arrow = match d.output { clean::Unit => "no", _ => "yes" },
-               ret = d.output);
-    }
-}
-
-impl fmt::Default for VisSpace {
-    fn fmt(v: &VisSpace, f: &mut fmt::Formatter) {
-        match **v {
-            Some(ast::public) => { write!(f.buf, "pub "); }
-            Some(ast::private) => { write!(f.buf, "priv "); }
-            Some(ast::inherited) | None => {}
-        }
-    }
-}
diff --git a/src/rustdoc_ng/html/layout.rs b/src/rustdoc_ng/html/layout.rs
deleted file mode 100644 (file)
index fcf1377..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt;
-use std::rt::io;
-
-#[deriving(Clone)]
-pub struct Layout {
-    logo: ~str,
-    favicon: ~str,
-    crate: ~str,
-}
-
-pub struct Page<'self> {
-    title: &'self str,
-    ty: &'self str,
-    root_path: &'self str,
-}
-
-pub fn render<T: fmt::Default, S: fmt::Default>(
-    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
-{
-    write!(dst, "
-<!DOCTYPE html>
-<html lang=\"en\">
-<head>
-    <meta charset=\"utf-8\" />
-    <title>{title}</title>
-
-    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400'
-          rel='stylesheet' type='text/css'>
-    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}main.css\">
-
-    {favicon, select, none{} other{
-        <link rel=\"icon\" href=\"#\" sizes=\"16x16\"
-              type=\"image/vnd.microsoft.icon\" />}}
-</head>
-<body>
-    <!--[if lte IE 8]>
-    <div class=\"warning\">
-        This old browser is unsupported and will most likely display funky
-        things
-    </div>
-    <![endif]-->
-
-    <section class=\"sidebar\">
-        {logo, select, none{} other{
-            <a href='{root_path}index.html'><img src='#' alt=''/></a>
-        }}
-
-        {sidebar}
-    </section>
-
-    <nav class=\"sub\">
-        <form class=\"search-form js-only\">
-            <input class=\"search-input\" name=\"search\"
-                   autocomplete=\"off\" />
-            <button class=\"do-search\">Search</button>
-        </form>
-    </nav>
-
-    <section class=\"content {ty}\">{content}</section>
-
-    <section class=\"footer\"></section>
-
-    <script>
-        var rootPath = \"{root_path}\";
-    </script>
-    <script src=\"{root_path}jquery.js\"></script>
-    <script src=\"{root_path}{crate}/search-index.js\"></script>
-    <script src=\"{root_path}main.js\"></script>
-
-    <div id=\"help\" class=\"hidden\">
-        <div class=\"shortcuts\">
-            <h1>Keyboard shortcuts</h1>
-            <dl>
-                <dt>?</dt>
-                <dd>Show this help dialog</dd>
-                <dt>S</dt>
-                <dd>Focus the search field</dd>
-                <dt>&uarr;</dt>
-                <dd>Move up in search results</dd>
-                <dt>&darr;</dt>
-                <dd>Move down in search results</dd>
-                <dt>&\\#9166;</dt>
-                <dd>Go to active search result</dd>
-            </dl>
-        </div>
-        <div class=\"infos\">
-            <h1>Search tricks</h1>
-            <p>
-                Prefix searches with a type followed by a colon (e.g.
-                <code>fn:</code>) to restrict the search to a given type.
-            </p>
-            <p>
-                Accepted types are: <code>fn</code>, <code>mod</code>,
-                <code>struct</code> (or <code>str</code>), <code>enum</code>,
-                <code>trait</code>, <code>typedef</code> (or
-                <code>tdef</code>).
-            </p>
-        </div>
-    </div>
-</body>
-</html>
-",
-    content   = *t,
-    root_path = page.root_path,
-    ty        = page.ty,
-    logo      = nonestr(layout.logo),
-    title     = page.title,
-    favicon   = nonestr(layout.favicon),
-    sidebar   = *sidebar,
-    crate     = layout.crate,
-    );
-}
-
-fn boolstr(b: bool) -> &'static str {
-    if b { "true" } else { "false" }
-}
-
-fn nonestr<'a>(s: &'a str) -> &'a str {
-    if s == "" { "none" } else { s }
-}
diff --git a/src/rustdoc_ng/html/markdown.rs b/src/rustdoc_ng/html/markdown.rs
deleted file mode 100644 (file)
index 14e2327..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt;
-use std::rt::io::Reader;
-use std::rt::io::pipe::PipeStream;
-use std::rt::io::process::{ProcessConfig, Process, CreatePipe};
-use std::rt::io;
-
-pub struct Markdown<'self>(&'self str);
-
-impl<'self> fmt::Default for Markdown<'self> {
-    fn fmt(md: &Markdown<'self>, fmt: &mut fmt::Formatter) {
-        if md.len() == 0 { return; }
-
-        // Create the pandoc process
-        do io::io_error::cond.trap(|err| {
-            fail2!("Error executing `pandoc`: {}", err.desc);
-        }).inside {
-            let io = ~[CreatePipe(PipeStream::new().unwrap(), true, false),
-                       CreatePipe(PipeStream::new().unwrap(), false, true)];
-            let args = ProcessConfig {
-                program: "pandoc",
-                args: [],
-                env: None,
-                cwd: None,
-                io: io,
-            };
-            let mut p = Process::new(args).expect("couldn't fork for pandoc");
-
-            // Write the markdown to stdin and close it.
-            p.io[0].get_mut_ref().write(md.as_bytes());
-            p.io[0] = None;
-
-            // Ferry the output from pandoc over to the destination buffer.
-            let mut buf = [0, ..1024];
-            loop {
-                match p.io[1].get_mut_ref().read(buf) {
-                    None | Some(0) => { break }
-                    Some(n) => {
-                        fmt.buf.write(buf.slice_to(n));
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/rustdoc_ng/html/render.rs b/src/rustdoc_ng/html/render.rs
deleted file mode 100644 (file)
index b004061..0000000
+++ /dev/null
@@ -1,1108 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cell::Cell;
-use std::comm::{SharedPort, SharedChan};
-use std::comm;
-use std::fmt;
-use std::hashmap::HashMap;
-use std::local_data;
-use std::rt::io::buffered::BufferedWriter;
-use std::rt::io::file::{FileInfo, DirectoryInfo};
-use std::rt::io::file;
-use std::rt::io;
-use std::task;
-use std::unstable::finally::Finally;
-use std::util;
-use std::vec;
-
-use extra::arc::RWArc;
-use extra::json::ToJson;
-use extra::sort;
-
-use syntax::ast;
-
-use clean;
-use doctree;
-use fold::DocFolder;
-use html::format::{VisSpace, Method};
-use html::layout;
-use html::markdown::Markdown;
-
-#[deriving(Clone)]
-pub struct Context {
-    current: ~[~str],
-    root_path: ~str,
-    dst: Path,
-    layout: layout::Layout,
-    sidebar: HashMap<~str, ~[~str]>,
-}
-
-enum Implementor {
-    PathType(clean::Type),
-    OtherType(clean::Generics, /* trait */ clean::Type, /* for */ clean::Type),
-}
-
-struct Cache {
-    // typaram id => name of that typaram
-    typarams: HashMap<ast::NodeId, ~str>,
-    // type id => all implementations for that type
-    impls: HashMap<ast::NodeId, ~[clean::Impl]>,
-    // path id => (full qualified path, shortty) -- used to generate urls
-    paths: HashMap<ast::NodeId, (~[~str], &'static str)>,
-    // trait id => method name => dox
-    traits: HashMap<ast::NodeId, HashMap<~str, ~str>>,
-    // trait id => implementors of the trait
-    implementors: HashMap<ast::NodeId, ~[Implementor]>,
-
-    priv stack: ~[~str],
-    priv parent_stack: ~[ast::NodeId],
-    priv search_index: ~[IndexItem],
-}
-
-struct Item<'self> { cx: &'self Context, item: &'self clean::Item, }
-struct Sidebar<'self> { cx: &'self Context, item: &'self clean::Item, }
-
-struct IndexItem {
-    ty: &'static str,
-    name: ~str,
-    path: ~str,
-    desc: ~str,
-    parent: Option<ast::NodeId>,
-}
-
-local_data_key!(pub cache_key: RWArc<Cache>)
-local_data_key!(pub current_location_key: ~[~str])
-
-/// Generates the documentation for `crate` into the directory `dst`
-pub fn run(mut crate: clean::Crate, dst: Path) {
-    let mut cx = Context {
-        dst: dst,
-        current: ~[],
-        root_path: ~"",
-        sidebar: HashMap::new(),
-        layout: layout::Layout {
-            logo: ~"",
-            favicon: ~"",
-            crate: crate.name.clone(),
-        },
-    };
-    mkdir(&cx.dst);
-
-    match crate.module.get_ref().doc_list() {
-        Some(attrs) => {
-            for attr in attrs.iter() {
-                match *attr {
-                    clean::NameValue(~"html_favicon_url", ref s) => {
-                        cx.layout.favicon = s.to_owned();
-                    }
-                    clean::NameValue(~"html_logo_url", ref s) => {
-                        cx.layout.logo = s.to_owned();
-                    }
-                    _ => {}
-                }
-            }
-        }
-        None => {}
-    }
-
-    // Crawl the crate to build various caches used for the output
-    let mut cache = Cache {
-        impls: HashMap::new(),
-        typarams: HashMap::new(),
-        paths: HashMap::new(),
-        traits: HashMap::new(),
-        implementors: HashMap::new(),
-        stack: ~[],
-        parent_stack: ~[],
-        search_index: ~[],
-    };
-    cache.stack.push(crate.name.clone());
-    crate = cache.fold_crate(crate);
-
-    // Add all the static files
-    write(cx.dst.push("jquery.js"), include_str!("static/jquery-2.0.3.min.js"));
-    write(cx.dst.push("main.js"), include_str!("static/main.js"));
-    write(cx.dst.push("main.css"), include_str!("static/main.css"));
-    write(cx.dst.push("normalize.css"), include_str!("static/normalize.css"));
-    write(cx.dst.push("index.html"), format!("
-        <DOCTYPE html><html><head>
-            <meta http-equiv='refresh'
-                  content=\"0; url={}/index.html\">
-        </head><body></body></html>
-    ", crate.name));
-
-    {
-        mkdir(&cx.dst.push(crate.name));
-        let dst = cx.dst.push(crate.name).push("search-index.js");
-        let mut w = BufferedWriter::new(dst.open_writer(io::CreateOrTruncate));
-        let w = &mut w as &mut io::Writer;
-        write!(w, "var searchIndex = [");
-        for (i, item) in cache.search_index.iter().enumerate() {
-            if i > 0 { write!(w, ","); }
-            write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
-                   item.ty, item.name, item.path,
-                   item.desc.to_json().to_str())
-            match item.parent {
-                Some(id) => { write!(w, ",parent:'{}'", id); }
-                None => {}
-            }
-            write!(w, "\\}");
-        }
-        write!(w, "];");
-        write!(w, "var allPaths = \\{");
-        for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() {
-            if i > 0 { write!(w, ","); }
-            write!(w, "'{}':\\{type:'{}',name:'{}'\\}", id, short, *fqp.last());
-        }
-        write!(w, "\\};");
-        w.flush();
-    }
-
-    // Now render the whole crate.
-    cx.crate(crate, cache);
-}
-
-fn write(dst: Path, contents: &str) {
-    let mut w = dst.open_writer(io::CreateOrTruncate);
-    w.write(contents.as_bytes());
-}
-
-fn mkdir(path: &Path) {
-    do io::io_error::cond.trap(|err| {
-        error2!("Couldn't create directory `{}`: {}",
-                path.to_str(), err.desc);
-        fail!()
-    }).inside {
-        if !path.is_dir() {
-            file::mkdir(path);
-        }
-    }
-}
-
-impl<'self> DocFolder for Cache {
-    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
-        // Register any generics to their corresponding string. This is used
-        // when pretty-printing types
-        match item.inner {
-            clean::StructItem(ref s)   => self.generics(&s.generics),
-            clean::EnumItem(ref e)     => self.generics(&e.generics),
-            clean::FunctionItem(ref f) => self.generics(&f.generics),
-            clean::TypedefItem(ref t)  => self.generics(&t.generics),
-            clean::TraitItem(ref t)    => self.generics(&t.generics),
-            clean::ImplItem(ref i)     => self.generics(&i.generics),
-            clean::TyMethodItem(ref i) => self.generics(&i.generics),
-            clean::MethodItem(ref i)   => self.generics(&i.generics),
-            _ => {}
-        }
-
-        // Propagate a trait methods' documentation to all implementors of the
-        // trait
-        match item.inner {
-            clean::TraitItem(ref t) => {
-                let mut dox = HashMap::new();
-                for meth in t.methods.iter() {
-                    let it = meth.item();
-                    match it.doc_value() {
-                        None => {}
-                        Some(s) => {
-                            dox.insert(it.name.get_ref().to_owned(),
-                                       s.to_owned());
-                        }
-                    }
-                }
-                self.traits.insert(item.id, dox);
-            }
-            _ => {}
-        }
-
-        // Collect all the implementors of traits.
-        match item.inner {
-            clean::ImplItem(ref i) => {
-                match i.trait_ {
-                    Some(clean::ResolvedPath{ id, _ }) => {
-                        let v = do self.implementors.find_or_insert_with(id) |_|{
-                            ~[]
-                        };
-                        match i.for_ {
-                            clean::ResolvedPath{_} => {
-                                v.unshift(PathType(i.for_.clone()));
-                            }
-                            _ => {
-                                v.push(OtherType(i.generics.clone(),
-                                                 i.trait_.get_ref().clone(),
-                                                 i.for_.clone()));
-                            }
-                        }
-                    }
-                    Some(*) | None => {}
-                }
-            }
-            _ => {}
-        }
-
-        // Index this method for searching later on
-        match item.name {
-            Some(ref s) => {
-                let parent = match item.inner {
-                    clean::TyMethodItem(*) | clean::VariantItem(*) => {
-                        Some((Some(*self.parent_stack.last()),
-                              self.stack.slice_to(self.stack.len() - 1)))
-
-                    }
-                    clean::MethodItem(*) => {
-                        if self.parent_stack.len() == 0 {
-                            None
-                        } else {
-                            Some((Some(*self.parent_stack.last()),
-                                  self.stack.as_slice()))
-                        }
-                    }
-                    _ => Some((None, self.stack.as_slice()))
-                };
-                match parent {
-                    Some((parent, path)) => {
-                        self.search_index.push(IndexItem {
-                            ty: shortty(&item),
-                            name: s.to_owned(),
-                            path: path.connect("::"),
-                            desc: shorter(item.doc_value()).to_owned(),
-                            parent: parent,
-                        });
-                    }
-                    None => {}
-                }
-            }
-            None => {}
-        }
-
-        // Keep track of the fully qualified path for this item.
-        let pushed = if item.name.is_some() {
-            let n = item.name.get_ref();
-            if n.len() > 0 {
-                self.stack.push(n.to_owned());
-                true
-            } else { false }
-        } else { false };
-        match item.inner {
-            clean::StructItem(*) | clean::EnumItem(*) |
-            clean::TypedefItem(*) | clean::TraitItem(*) => {
-                self.paths.insert(item.id, (self.stack.clone(), shortty(&item)));
-            }
-            _ => {}
-        }
-
-        // Maintain the parent stack
-        let parent_pushed = match item.inner {
-            clean::TraitItem(*) | clean::EnumItem(*) => {
-                self.parent_stack.push(item.id); true
-            }
-            clean::ImplItem(ref i) => {
-                match i.for_ {
-                    clean::ResolvedPath{ id, _ } => {
-                        self.parent_stack.push(id); true
-                    }
-                    _ => false
-                }
-            }
-            _ => false
-        };
-
-        // Once we've recursively found all the generics, then hoard off all the
-        // implementations elsewhere
-        let ret = match self.fold_item_recur(item) {
-            Some(item) => {
-                match item.inner {
-                    clean::ImplItem(i) => {
-                        match i.for_ {
-                            clean::ResolvedPath { id, _ } => {
-                                let v = do self.impls.find_or_insert_with(id) |_| {
-                                    ~[]
-                                };
-                                v.push(i);
-                            }
-                            _ => {}
-                        }
-                        None
-                    }
-                    _ => Some(item),
-                }
-            }
-            i => i,
-        };
-
-        if pushed { self.stack.pop(); }
-        if parent_pushed { self.parent_stack.pop(); }
-        return ret;
-    }
-}
-
-impl<'self> Cache {
-    fn generics(&mut self, generics: &clean::Generics) {
-        for typ in generics.type_params.iter() {
-            self.typarams.insert(typ.id, typ.name.clone());
-        }
-    }
-}
-
-impl Context {
-    fn recurse<T>(&mut self, s: ~str, f: &fn(&mut Context) -> T) -> T {
-        // Recurse in the directory structure and change the "root path" to make
-        // sure it always points to the top (relatively)
-        if s.len() == 0 {
-            fail2!("what {:?}", self);
-        }
-        let next = self.dst.push(s);
-        let prev = util::replace(&mut self.dst, next);
-        self.root_path.push_str("../");
-        self.current.push(s);
-
-        mkdir(&self.dst);
-        let ret = f(self);
-
-        // Go back to where we were at
-        self.dst = prev;
-        let len = self.root_path.len();
-        self.root_path.truncate(len - 3);
-        self.current.pop();
-
-        return ret;
-    }
-
-    /// Processes
-    fn crate(self, mut crate: clean::Crate, cache: Cache) {
-        enum Work {
-            Die,
-            Process(Context, clean::Item),
-        }
-        enum Progress { JobNew, JobDone }
-        static WORKERS: int = 10;
-
-        let mut item = match crate.module.take() {
-            Some(i) => i,
-            None => return
-        };
-        item.name = Some(crate.name);
-
-        let (port, chan) = comm::stream::<Work>();
-        let port = SharedPort::new(port);
-        let chan = SharedChan::new(chan);
-        let (prog_port, prog_chan) = comm::stream();
-        let prog_chan = SharedChan::new(prog_chan);
-        let cache = RWArc::new(cache);
-
-        for i in range(0, WORKERS) {
-            let port = port.clone();
-            let chan = chan.clone();
-            let prog_chan = prog_chan.clone();
-
-            let mut task = task::task();
-            task.unlinked(); // we kill things manually
-            task.name(format!("worker{}", i));
-            do task.spawn_with(cache.clone()) |cache| {
-                local_data::set(cache_key, cache);
-                loop {
-                    match port.recv() {
-                        Process(cx, item) => {
-                            let mut cx = cx;
-                            let item = Cell::new(item);
-                            do (|| {
-                                do cx.item(item.take()) |cx, item| {
-                                    prog_chan.send(JobNew);
-                                    chan.send(Process(cx.clone(), item));
-                                }
-                            }).finally {
-                                // If we fail, everything else should still get
-                                // completed
-                                prog_chan.send(JobDone);
-                            }
-                        }
-                        Die => break,
-                    }
-                }
-            }
-        }
-
-        let watcher_chan = chan.clone();
-        let (done_port, done_chan) = comm::stream();
-        do task::spawn {
-            let mut jobs = 0;
-            loop {
-                match prog_port.recv() {
-                    JobNew => jobs += 1,
-                    JobDone => jobs -= 1,
-                }
-
-                if jobs == 0 { break }
-            }
-
-            for _ in range(0, WORKERS) {
-                watcher_chan.send(Die);
-            }
-            done_chan.send(());
-        }
-
-        prog_chan.send(JobNew);
-        chan.send(Process(self, item));
-        done_port.recv();
-    }
-
-    fn item(&mut self, item: clean::Item, f: &fn(&mut Context, clean::Item)) {
-        fn render(w: io::file::FileWriter, cx: &mut Context, it: &clean::Item,
-                  pushname: bool) {
-            // A little unfortunate that this is done like this, but it sure
-            // does make formatting *a lot* nicer.
-            local_data::set(current_location_key, cx.current.clone());
-
-            let mut title = cx.current.connect("::");
-            if pushname {
-                if title.len() > 0 { title.push_str("::"); }
-                title.push_str(*it.name.get_ref());
-            }
-            title.push_str(" - Rust");
-            let page = layout::Page {
-                ty: shortty(it),
-                root_path: cx.root_path,
-                title: title,
-            };
-
-            // We have a huge number of calls to write, so try to alleviate some
-            // of the pain by using a buffered writer instead of invoking the
-            // write sycall all the time.
-            let mut writer = BufferedWriter::new(w);
-            layout::render(&mut writer as &mut io::Writer, &cx.layout, &page,
-                           &Sidebar{ cx: cx, item: it },
-                           &Item{ cx: cx, item: it });
-            writer.flush();
-        }
-
-        match item.inner {
-            clean::ModuleItem(*) => {
-                let name = item.name.get_ref().to_owned();
-                let item = Cell::new(item);
-                do self.recurse(name) |this| {
-                    let item = item.take();
-                    let dst = this.dst.push("index.html");
-                    let writer = dst.open_writer(io::CreateOrTruncate);
-                    render(writer.unwrap(), this, &item, false);
-
-                    let m = match item.inner {
-                        clean::ModuleItem(m) => m,
-                        _ => unreachable!()
-                    };
-                    this.sidebar = build_sidebar(&m);
-                    for item in m.items.move_iter() {
-                        f(this, item);
-                    }
-                }
-            }
-            _ if item.name.is_some() => {
-                let dst = self.dst.push(item_path(&item));
-                let writer = dst.open_writer(io::CreateOrTruncate);
-                render(writer.unwrap(), self, &item, true);
-            }
-            _ => {}
-        }
-    }
-}
-
-fn shortty(item: &clean::Item) -> &'static str {
-    match item.inner {
-        clean::ModuleItem(*)      => "mod",
-        clean::StructItem(*)      => "struct",
-        clean::EnumItem(*)        => "enum",
-        clean::FunctionItem(*)    => "fn",
-        clean::TypedefItem(*)     => "typedef",
-        clean::StaticItem(*)      => "static",
-        clean::TraitItem(*)       => "trait",
-        clean::ImplItem(*)        => "impl",
-        clean::ViewItemItem(*)    => "viewitem",
-        clean::TyMethodItem(*)    => "tymethod",
-        clean::MethodItem(*)      => "method",
-        clean::StructFieldItem(*) => "structfield",
-        clean::VariantItem(*)     => "variant",
-    }
-}
-
-impl<'self> Item<'self> {
-    fn ismodule(&self) -> bool {
-        match self.item.inner {
-            clean::ModuleItem(*) => true, _ => false
-        }
-    }
-}
-
-impl<'self> fmt::Default for Item<'self> {
-    fn fmt(it: &Item<'self>, fmt: &mut fmt::Formatter) {
-        // Write the breadcrumb trail header for the top
-        write!(fmt.buf, "<h1 class='fqn'>");
-        match it.item.inner {
-            clean::ModuleItem(*) => write!(fmt.buf, "Module "),
-            clean::FunctionItem(*) => write!(fmt.buf, "Function "),
-            clean::TraitItem(*) => write!(fmt.buf, "Trait "),
-            clean::StructItem(*) => write!(fmt.buf, "Struct "),
-            clean::EnumItem(*) => write!(fmt.buf, "Enum "),
-            _ => {}
-        }
-        let cur = it.cx.current.as_slice();
-        let amt = if it.ismodule() { cur.len() - 1 } else { cur.len() };
-        for (i, component) in cur.iter().enumerate().take(amt) {
-            let mut trail = ~"";
-            for _ in range(0, cur.len() - i - 1) {
-                trail.push_str("../");
-            }
-            write!(fmt.buf, "<a href='{}index.html'>{}</a>::",
-                   trail, component.as_slice());
-        }
-        write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>",
-               shortty(it.item), it.item.name.get_ref().as_slice());
-
-        match it.item.inner {
-            clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
-                                                    it.item, m.items),
-            clean::FunctionItem(ref f) => item_function(fmt.buf, it.item, f),
-            clean::TraitItem(ref t) => item_trait(fmt.buf, it.item, t),
-            clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
-            clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
-            clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t),
-            _ => {}
-        }
-    }
-}
-
-fn item_path(item: &clean::Item) -> ~str {
-    match item.inner {
-        clean::ModuleItem(*) => *item.name.get_ref() + "/index.html",
-        _ => shortty(item) + "." + *item.name.get_ref() + ".html"
-    }
-}
-
-fn full_path(cx: &Context, item: &clean::Item) -> ~str {
-    let mut s = cx.current.connect("::");
-    s.push_str("::");
-    s.push_str(item.name.get_ref().as_slice());
-    return s;
-}
-
-fn blank<'a>(s: Option<&'a str>) -> &'a str {
-    match s {
-        Some(s) => s,
-        None => ""
-    }
-}
-
-fn shorter<'a>(s: Option<&'a str>) -> &'a str {
-    match s {
-        Some(s) => match s.find_str("\n\n") {
-            Some(pos) => s.slice_to(pos),
-            None => s,
-        },
-        None => ""
-    }
-}
-
-fn document(w: &mut io::Writer, item: &clean::Item) {
-    match item.doc_value() {
-        Some(s) => {
-            write!(w, "<div class='docblock'>{}</div>", Markdown(s));
-        }
-        None => {}
-    }
-}
-
-fn item_module(w: &mut io::Writer, cx: &Context,
-               item: &clean::Item, items: &[clean::Item]) {
-    document(w, item);
-    let mut indices = vec::from_fn(items.len(), |i| i);
-
-    fn lt(i1: &clean::Item, i2: &clean::Item) -> bool {
-        if shortty(i1) == shortty(i2) {
-            return i1.name < i2.name;
-        }
-        match (&i1.inner, &i2.inner) {
-            (&clean::ViewItemItem(*), _) => true,
-            (_, &clean::ViewItemItem(*)) => false,
-            (&clean::ModuleItem(*), _) => true,
-            (_, &clean::ModuleItem(*)) => false,
-            (&clean::StructItem(*), _) => true,
-            (_, &clean::StructItem(*)) => false,
-            (&clean::EnumItem(*), _) => true,
-            (_, &clean::EnumItem(*)) => false,
-            (&clean::StaticItem(*), _) => true,
-            (_, &clean::StaticItem(*)) => false,
-            (&clean::TraitItem(*), _) => true,
-            (_, &clean::TraitItem(*)) => false,
-            (&clean::FunctionItem(*), _) => true,
-            (_, &clean::FunctionItem(*)) => false,
-            (&clean::TypedefItem(*), _) => true,
-            (_, &clean::TypedefItem(*)) => false,
-            _ => false,
-        }
-    }
-
-    do sort::quick_sort(indices) |&i1, &i2| {
-        lt(&items[i1], &items[i2])
-    }
-
-    let mut curty = "";
-    for &idx in indices.iter() {
-        let myitem = &items[idx];
-        if myitem.name.is_none() { loop }
-
-        let myty = shortty(myitem);
-        if myty != curty {
-            if curty != "" {
-                write!(w, "</table>");
-            }
-            curty = myty;
-            write!(w, "<h2>{}</h2>\n<table>", match myitem.inner {
-                clean::ModuleItem(*)      => "Modules",
-                clean::StructItem(*)      => "Structs",
-                clean::EnumItem(*)        => "Enums",
-                clean::FunctionItem(*)    => "Functions",
-                clean::TypedefItem(*)     => "Type Definitions",
-                clean::StaticItem(*)      => "Statics",
-                clean::TraitItem(*)       => "Traits",
-                clean::ImplItem(*)        => "Implementations",
-                clean::ViewItemItem(*)    => "Reexports",
-                clean::TyMethodItem(*)    => "Type Methods",
-                clean::MethodItem(*)      => "Methods",
-                clean::StructFieldItem(*) => "Struct Fields",
-                clean::VariantItem(*)     => "Variants",
-            });
-        }
-
-        match myitem.inner {
-            clean::StaticItem(ref s) => {
-                struct Initializer<'self>(&'self str);
-                impl<'self> fmt::Default for Initializer<'self> {
-                    fn fmt(s: &Initializer<'self>, f: &mut fmt::Formatter) {
-                        let tag = if s.contains("\n") { "pre" } else { "code" };
-                        write!(f.buf, "<{tag}>{}</{tag}>",
-                               s.as_slice(), tag=tag);
-                    }
-                }
-
-                write!(w, "
-                    <tr>
-                        <td><code>{}: {} = </code>{}</td>
-                        <td class='docblock'>{}&nbsp;</td>
-                    </tr>
-                ",
-                *myitem.name.get_ref(),
-                s.type_,
-                Initializer(s.expr),
-                Markdown(blank(myitem.doc_value())));
-            }
-
-            _ => {
-                write!(w, "
-                    <tr>
-                        <td><a class='{class}' href='{href}'
-                               title='{title}'>{}</a></td>
-                        <td class='docblock short'>{}</td>
-                    </tr>
-                ",
-                *myitem.name.get_ref(),
-                Markdown(shorter(myitem.doc_value())),
-                class = shortty(myitem),
-                href = item_path(myitem),
-                title = full_path(cx, myitem));
-            }
-        }
-    }
-    write!(w, "</table>");
-}
-
-fn item_function(w: &mut io::Writer, it: &clean::Item, f: &clean::Function) {
-    write!(w, "<pre class='fn'>{vis}fn {name}{generics}{decl}</pre>",
-           vis = VisSpace(it.visibility),
-           name = it.name.get_ref().as_slice(),
-           generics = f.generics,
-           decl = f.decl);
-    document(w, it);
-}
-
-fn item_trait(w: &mut io::Writer, it: &clean::Item, t: &clean::Trait) {
-    let mut parents = ~"";
-    if t.parents.len() > 0 {
-        parents.push_str(": ");
-        for (i, p) in t.parents.iter().enumerate() {
-            if i > 0 { parents.push_str(" + "); }
-            parents.push_str(format!("{}", *p));
-        }
-    }
-
-    // Output the trait definition
-    write!(w, "<pre class='trait'>{}trait {}{}{} ",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           t.generics,
-           parents);
-    let required = t.methods.iter().filter(|m| m.is_req()).to_owned_vec();
-    let provided = t.methods.iter().filter(|m| !m.is_req()).to_owned_vec();
-
-    if t.methods.len() == 0 {
-        write!(w, "\\{ \\}");
-    } else {
-        write!(w, "\\{\n");
-        for m in required.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, ";\n");
-        }
-        if required.len() > 0 && provided.len() > 0 {
-            w.write("\n".as_bytes());
-        }
-        for m in provided.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, " \\{ ... \\}\n");
-        }
-        write!(w, "\\}");
-    }
-    write!(w, "</pre>");
-
-    // Trait documentation
-    document(w, it);
-
-    fn meth(w: &mut io::Writer, m: &clean::TraitMethod) {
-        write!(w, "<h3 id='fn.{}' class='method'><code>",
-               *m.item().name.get_ref());
-        render_method(w, m.item(), false);
-        write!(w, "</code></h3>");
-        document(w, m.item());
-    }
-
-    // Output the documentation for each function individually
-    if required.len() > 0 {
-        write!(w, "
-            <h2 id='required-methods'>Required Methods</h2>
-            <div class='methods'>
-        ");
-        for m in required.iter() {
-            meth(w, *m);
-        }
-        write!(w, "</div>");
-    }
-    if provided.len() > 0 {
-        write!(w, "
-            <h2 id='provided-methods'>Provided Methods</h2>
-            <div class='methods'>
-        ");
-        for m in provided.iter() {
-            meth(w, *m);
-        }
-        write!(w, "</div>");
-    }
-
-    do local_data::get(cache_key) |cache| {
-        do cache.unwrap().read |cache| {
-            match cache.implementors.find(&it.id) {
-                Some(implementors) => {
-                    write!(w, "
-                        <h2 id='implementors'>Implementors</h2>
-                        <ul class='item-list'>
-                    ");
-                    for i in implementors.iter() {
-                        match *i {
-                            PathType(ref ty) => {
-                                write!(w, "<li><code>{}</code></li>", *ty);
-                            }
-                            OtherType(ref generics, ref trait_, ref for_) => {
-                                write!(w, "<li><code>impl{} {} for {}</code></li>",
-                                       *generics, *trait_, *for_);
-                            }
-                        }
-                    }
-                    write!(w, "</ul>");
-                }
-                None => {}
-            }
-        }
-    }
-}
-
-fn render_method(w: &mut io::Writer, meth: &clean::Item, withlink: bool) {
-    fn fun(w: &mut io::Writer, it: &clean::Item, purity: ast::purity,
-           g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
-           withlink: bool) {
-        write!(w, "{}fn {withlink, select,
-                            true{<a href='\\#fn.{name}'>{name}</a>}
-                            other{{name}}
-                        }{generics}{decl}",
-               match purity {
-                   ast::unsafe_fn => "unsafe ",
-                   _ => "",
-               },
-               name = it.name.get_ref().as_slice(),
-               generics = *g,
-               decl = Method(selfty, d),
-               withlink = if withlink {"true"} else {"false"});
-    }
-    match meth.inner {
-        clean::TyMethodItem(ref m) => {
-            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
-        }
-        clean::MethodItem(ref m) => {
-            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
-        }
-        _ => unreachable!()
-    }
-}
-
-fn item_struct(w: &mut io::Writer, it: &clean::Item, s: &clean::Struct) {
-    write!(w, "<pre class='struct'>");
-    render_struct(w, it, Some(&s.generics), s.struct_type, s.fields, "");
-    write!(w, "</pre>");
-
-    document(w, it);
-    render_methods(w, it);
-}
-
-fn item_enum(w: &mut io::Writer, it: &clean::Item, e: &clean::Enum) {
-    write!(w, "<pre class='enum'>{}enum {}{}",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           e.generics);
-    if e.variants.len() == 0 {
-        write!(w, " \\{\\}");
-    } else {
-        write!(w, " \\{\n");
-        for v in e.variants.iter() {
-            let name = v.name.get_ref().as_slice();
-            match v.inner {
-                clean::VariantItem(ref var) => {
-                    match var.kind {
-                        clean::CLikeVariant => write!(w, "    {},\n", name),
-                        clean::TupleVariant(ref tys) => {
-                            write!(w, "    {}(", name);
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 { write!(w, ", ") }
-                                write!(w, "{}", *ty);
-                            }
-                            write!(w, "),\n");
-                        }
-                        clean::StructVariant(ref s) => {
-                            render_struct(w, v, None, s.struct_type, s.fields,
-                                          "    ");
-                        }
-                    }
-                }
-                _ => unreachable!()
-            }
-        }
-        write!(w, "\\}");
-    }
-    write!(w, "</pre>");
-
-    document(w, it);
-    render_methods(w, it);
-}
-
-fn render_struct(w: &mut io::Writer, it: &clean::Item,
-                 g: Option<&clean::Generics>,
-                 ty: doctree::StructType,
-                 fields: &[clean::Item],
-                 tab: &str) {
-    write!(w, "{}struct {}",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice());
-    match g {
-        Some(g) => write!(w, "{}", *g),
-        None => {}
-    }
-    match ty {
-        doctree::Plain => {
-            write!(w, " \\{\n");
-            for field in fields.iter() {
-                match field.inner {
-                    clean::StructFieldItem(ref ty) => {
-                        write!(w, "    {}{}: {},\n{}",
-                               VisSpace(field.visibility),
-                               field.name.get_ref().as_slice(),
-                               ty.type_,
-                               tab);
-                    }
-                    _ => unreachable!()
-                }
-            }
-            write!(w, "\\}");
-        }
-        doctree::Tuple | doctree::Newtype => {
-            write!(w, "(");
-            for (i, field) in fields.iter().enumerate() {
-                if i > 0 { write!(w, ", ") }
-                match field.inner {
-                    clean::StructFieldItem(ref field) => {
-                        write!(w, "{}", field.type_);
-                    }
-                    _ => unreachable!()
-                }
-            }
-            write!(w, ");");
-        }
-        doctree::Unit => { write!(w, ";"); }
-    }
-}
-
-fn render_methods(w: &mut io::Writer, it: &clean::Item) {
-    do local_data::get(cache_key) |cache| {
-        let cache = cache.unwrap();
-        do cache.read |c| {
-            match c.impls.find(&it.id) {
-                Some(v) => {
-                    let mut non_trait = v.iter().filter(|i| i.trait_.is_none());
-                    let non_trait = non_trait.to_owned_vec();
-                    let mut traits = v.iter().filter(|i| i.trait_.is_some());
-                    let traits = traits.to_owned_vec();
-
-                    if non_trait.len() > 0 {
-                        write!(w, "<h2 id='methods'>Methods</h2>");
-                        for &i in non_trait.iter() {
-                            render_impl(w, i);
-                        }
-                    }
-                    if traits.len() > 0 {
-                        write!(w, "<h2 id='implementations'>Trait \
-                                   Implementations</h2>");
-                        for &i in traits.iter() {
-                            render_impl(w, i);
-                        }
-                    }
-                }
-                None => {}
-            }
-        }
-    }
-}
-
-fn render_impl(w: &mut io::Writer, i: &clean::Impl) {
-    write!(w, "<h3 class='impl'><code>impl{} ", i.generics);
-    let trait_id = match i.trait_ {
-        Some(ref ty) => {
-            write!(w, "{} for ", *ty);
-            match *ty {
-                clean::ResolvedPath { id, _ } => Some(id),
-                _ => None,
-            }
-        }
-        None => None
-    };
-    write!(w, "{}</code></h3>", i.for_);
-    write!(w, "<div class='methods'>");
-    for meth in i.methods.iter() {
-        write!(w, "<h4 id='fn.{}' class='method'><code>",
-               *meth.name.get_ref());
-        render_method(w, meth, false);
-        write!(w, "</code></h4>\n");
-        match meth.doc_value() {
-            Some(s) => {
-                write!(w, "<div class='docblock'>{}</div>", Markdown(s));
-                loop
-            }
-            None => {}
-        }
-
-        // No documentation? Attempt to slurp in the trait's documentation
-        let trait_id = match trait_id { Some(id) => id, None => loop };
-        do local_data::get(cache_key) |cache| {
-            do cache.unwrap().read |cache| {
-                let name = meth.name.get_ref().as_slice();
-                match cache.traits.find(&trait_id) {
-                    Some(m) => {
-                        match m.find_equiv(&name) {
-                            Some(s) => {
-                                write!(w, "<div class='docblock'>{}</div>",
-                                       Markdown(s.as_slice()));
-                            }
-                            None => {}
-                        }
-                    }
-                    None => {}
-                }
-            }
-        }
-    }
-    write!(w, "</div>");
-}
-
-fn item_typedef(w: &mut io::Writer, it: &clean::Item, t: &clean::Typedef) {
-    write!(w, "<pre class='typedef'>type {}{} = {};</pre>",
-           it.name.get_ref().as_slice(),
-           t.generics,
-           t.type_);
-
-    document(w, it);
-}
-
-impl<'self> fmt::Default for Sidebar<'self> {
-    fn fmt(s: &Sidebar<'self>, fmt: &mut fmt::Formatter) {
-        let cx = s.cx;
-        let it = s.item;
-        write!(fmt.buf, "<p class='location'>");
-        let len = cx.current.len() - if it.is_mod() {1} else {0};
-        for (i, name) in cx.current.iter().take(len).enumerate() {
-            if i > 0 { write!(fmt.buf, "&\\#8203;::") }
-            write!(fmt.buf, "<a href='{}index.html'>{}</a>",
-                   cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name);
-        }
-        write!(fmt.buf, "</p>");
-
-        fn block(w: &mut io::Writer, short: &str, longty: &str,
-                 cur: &clean::Item, cx: &Context) {
-            let items = match cx.sidebar.find_equiv(&short) {
-                Some(items) => items.as_slice(),
-                None => return
-            };
-            write!(w, "<div class='block {}'><h2>{}</h2>", short, longty);
-            for item in items.iter() {
-                let class = if cur.name.get_ref() == item &&
-                               short == shortty(cur) { "current" } else { "" };
-                write!(w, "<a class='{ty} {class}' href='{curty, select,
-                                mod{../}
-                                other{}
-                           }{ty, select,
-                                mod{{name}/index.html}
-                                other{#.{name}.html}
-                           }'>{name}</a><br/>",
-                       ty = short,
-                       class = class,
-                       curty = shortty(cur),
-                       name = item.as_slice());
-            }
-            write!(w, "</div>");
-        }
-
-        block(fmt.buf, "mod", "Modules", it, cx);
-        block(fmt.buf, "struct", "Structs", it, cx);
-        block(fmt.buf, "enum", "Enums", it, cx);
-        block(fmt.buf, "trait", "Traits", it, cx);
-        block(fmt.buf, "fn", "Functions", it, cx);
-    }
-}
-
-fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> {
-    let mut map = HashMap::new();
-    for item in m.items.iter() {
-        let short = shortty(item);
-        let myname = match item.name {
-            None => loop,
-            Some(ref s) => s.to_owned(),
-        };
-        let v = map.find_or_insert_with(short.to_owned(), |_| ~[]);
-        v.push(myname);
-    }
-
-    for (_, items) in map.mut_iter() {
-        sort::quick_sort(*items, |i1, i2| i1 < i2);
-    }
-    return map;
-}
diff --git a/src/rustdoc_ng/html/static/jquery-2.0.3.min.js b/src/rustdoc_ng/html/static/jquery-2.0.3.min.js
deleted file mode 100644 (file)
index 2be209d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! jQuery v2.0.3 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
-//@ sourceMappingURL=jquery-2.0.3.min.map
-*/
-(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],p="2.0.3",f=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:p,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return f.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,p,f,h,d,g,m,y,v="sizzle"+-new Date,b=e.document,w=0,T=0,C=st(),k=st(),N=st(),E=!1,S=function(e,t){return e===t?(E=!0,0):0},j=typeof undefined,D=1<<31,A={}.hasOwnProperty,L=[],q=L.pop,H=L.push,O=L.push,F=L.slice,P=L.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",W="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",$=W.replace("w","w#"),B="\\["+M+"*("+W+")"+M+"*(?:([*^$|!~]?=)"+M+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+$+")|)|)"+M+"*\\]",I=":("+W+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+B.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=RegExp("^"+M+"*,"+M+"*"),X=RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=RegExp(M+"*[+~]"),Y=RegExp("="+M+"*([^\\]'\"]*)"+M+"*\\]","g"),V=RegExp(I),G=RegExp("^"+$+"$"),J={ID:RegExp("^#("+W+")"),CLASS:RegExp("^\\.("+W+")"),TAG:RegExp("^("+W.replace("w","w*")+")"),ATTR:RegExp("^"+B),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:RegExp("^(?:"+R+")$","i"),needsContext:RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Q=/^[^{]+\{\s*\[native \w/,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Z=/^(?:input|select|textarea|button)$/i,et=/^h\d$/i,tt=/'|\\/g,nt=RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),rt=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{O.apply(L=F.call(b.childNodes),b.childNodes),L[b.childNodes.length].nodeType}catch(it){O={apply:L.length?function(e,t){H.apply(e,F.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function ot(e,t,r,i){var o,s,a,u,l,f,g,m,x,w;if((t?t.ownerDocument||t:b)!==p&&c(t),t=t||p,r=r||[],!e||"string"!=typeof e)return r;if(1!==(u=t.nodeType)&&9!==u)return[];if(h&&!i){if(o=K.exec(e))if(a=o[1]){if(9===u){if(s=t.getElementById(a),!s||!s.parentNode)return r;if(s.id===a)return r.push(s),r}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(a))&&y(t,s)&&s.id===a)return r.push(s),r}else{if(o[2])return O.apply(r,t.getElementsByTagName(e)),r;if((a=o[3])&&n.getElementsByClassName&&t.getElementsByClassName)return O.apply(r,t.getElementsByClassName(a)),r}if(n.qsa&&(!d||!d.test(e))){if(m=g=v,x=t,w=9===u&&e,1===u&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(g=t.getAttribute("id"))?m=g.replace(tt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",l=f.length;while(l--)f[l]=m+mt(f[l]);x=U.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return O.apply(r,x.querySelectorAll(w)),r}catch(T){}finally{g||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,r,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>i.cacheLength&&delete t[e.shift()],t[n]=r}return t}function at(e){return e[v]=!0,e}function ut(e){var t=p.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function lt(e,t){var n=e.split("|"),r=e.length;while(r--)i.attrHandle[n[r]]=t}function ct(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return at(function(t){return t=+t,at(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}s=ot.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},n=ot.support={},c=ot.setDocument=function(e){var t=e?e.ownerDocument||e:b,r=t.defaultView;return t!==p&&9===t.nodeType&&t.documentElement?(p=t,f=t.documentElement,h=!s(t),r&&r.attachEvent&&r!==r.top&&r.attachEvent("onbeforeunload",function(){c()}),n.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ut(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),n.getById=ut(function(e){return f.appendChild(e).id=v,!t.getElementsByName||!t.getElementsByName(v).length}),n.getById?(i.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){return e.getAttribute("id")===t}}):(delete i.find.ID,i.filter.ID=function(e){var t=e.replace(nt,rt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=n.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.CLASS=n.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&h?t.getElementsByClassName(e):undefined},g=[],d=[],(n.qsa=Q.test(t.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||d.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll(":checked").length||d.push(":checked")}),ut(function(e){var n=t.createElement("input");n.setAttribute("type","hidden"),e.appendChild(n).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&d.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||d.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),d.push(",.*:")})),(n.matchesSelector=Q.test(m=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&ut(function(e){n.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",I)}),d=d.length&&RegExp(d.join("|")),g=g.length&&RegExp(g.join("|")),y=Q.test(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,r){if(e===r)return E=!0,0;var i=r.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(r);return i?1&i||!n.sortDetached&&r.compareDocumentPosition(e)===i?e===t||y(b,e)?-1:r===t||y(b,r)?1:l?P.call(l,e)-P.call(l,r):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],u=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:l?P.call(l,e)-P.call(l,n):0;if(o===s)return ct(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)u.unshift(r);while(a[i]===u[i])i++;return i?ct(a[i],u[i]):a[i]===b?-1:u[i]===b?1:0},t):p},ot.matches=function(e,t){return ot(e,null,null,t)},ot.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Y,"='$1']"),!(!n.matchesSelector||!h||g&&g.test(t)||d&&d.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return ot(t,p,null,[e]).length>0},ot.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},ot.attr=function(e,t){(e.ownerDocument||e)!==p&&c(e);var r=i.attrHandle[t.toLowerCase()],o=r&&A.call(i.attrHandle,t.toLowerCase())?r(e,t,!h):undefined;return o===undefined?n.attributes||!h?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null:o},ot.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ot.uniqueSort=function(e){var t,r=[],i=0,o=0;if(E=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(S),E){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return e},o=ot.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=ot.selectors={cacheLength:50,createPseudo:at,match:J,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(nt,rt),e[3]=(e[4]||e[5]||"").replace(nt,rt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ot.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ot.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return J.CHILD.test(e[0])?null:(e[3]&&e[4]!==undefined?e[2]=e[4]:n&&V.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(nt,rt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ot.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){p=t;while(p=p[g])if(a?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[v]||(m[v]={}),l=c[e]||[],h=l[0]===w&&l[1],f=l[0]===w&&l[2],p=h&&m.childNodes[h];while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[w,h,f];break}}else if(x&&(l=(t[v]||(t[v]={}))[e])&&l[0]===w)f=l[1];else while(p=++h&&p&&p[g]||(f=h=0)||d.pop())if((a?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(x&&((p[v]||(p[v]={}))[e]=[w,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||ot.error("unsupported pseudo: "+e);return r[v]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?at(function(e,n){var i,o=r(e,t),s=o.length;while(s--)i=P.call(e,o[s]),e[i]=!(n[i]=o[s])}):function(e){return r(e,0,n)}):r}},pseudos:{not:at(function(e){var t=[],n=[],r=a(e.replace(z,"$1"));return r[v]?at(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:at(function(e){return function(t){return ot(e,t).length>0}}),contains:at(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:at(function(e){return G.test(e||"")||ot.error("unsupported lang: "+e),e=e.replace(nt,rt).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return et.test(e.nodeName)},input:function(e){return Z.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},i.pseudos.nth=i.pseudos.eq;for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})i.pseudos[t]=ft(t);function dt(){}dt.prototype=i.filters=i.pseudos,i.setFilters=new dt;function gt(e,t){var n,r,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=i.preFilter;while(a){(!n||(r=_.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),u.push(o=[])),n=!1,(r=X.exec(a))&&(n=r.shift(),o.push({value:n,type:r[0].replace(z," ")}),a=a.slice(n.length));for(s in i.filter)!(r=J[s].exec(a))||l[s]&&!(r=l[s](r))||(n=r.shift(),o.push({value:n,type:s,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ot.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,n){var i=t.dir,o=n&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,a){var u,l,c,p=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[v]||(t[v]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,a)||r,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[v]&&(r=bt(r)),i&&!i[v]&&(i=bt(i,o)),at(function(o,s,a,u){var l,c,p,f=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,f,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(p=l[c])&&(y[h[c]]=!(m[h[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?P.call(o,p):f[c])>-1&&(o[l]=!(s[l]=p))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):O.apply(s,y)})}function wt(e){var t,n,r,o=e.length,s=i.relative[e[0].type],a=s||i.relative[" "],l=s?1:0,c=yt(function(e){return e===t},a,!0),p=yt(function(e){return P.call(t,e)>-1},a,!0),f=[function(e,n,r){return!s&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>l;l++)if(n=i.relative[e[l].type])f=[yt(vt(f),n)];else{if(n=i.filter[e[l].type].apply(null,e[l].matches),n[v]){for(r=++l;o>r;r++)if(i.relative[e[r].type])break;return bt(l>1&&vt(f),l>1&&mt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&wt(e.slice(l,r)),o>r&&wt(e=e.slice(r)),o>r&&mt(e))}f.push(n)}return vt(f)}function Tt(e,t){var n=0,o=t.length>0,s=e.length>0,a=function(a,l,c,f,h){var d,g,m,y=[],v=0,x="0",b=a&&[],T=null!=h,C=u,k=a||s&&i.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(u=l!==p&&l,r=n);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,c)){f.push(d);break}T&&(w=N,r=++n)}o&&((d=!m&&d)&&v--,a&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,c);if(a){if(v>0)while(x--)b[x]||y[x]||(y[x]=q.call(f));y=xt(y)}O.apply(f,y),T&&!a&&y.length>0&&v+t.length>1&&ot.uniqueSort(f)}return T&&(w=N,u=C),b};return o?at(a):a}a=ot.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[v]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ot(e,t[r],n);return n}function kt(e,t,r,o){var s,u,l,c,p,f=gt(e);if(!o&&1===f.length){if(u=f[0]=f[0].slice(0),u.length>2&&"ID"===(l=u[0]).type&&n.getById&&9===t.nodeType&&h&&i.relative[u[1].type]){if(t=(i.find.ID(l.matches[0].replace(nt,rt),t)||[])[0],!t)return r;e=e.slice(u.shift().value.length)}s=J.needsContext.test(e)?0:u.length;while(s--){if(l=u[s],i.relative[c=l.type])break;if((p=i.find[c])&&(o=p(l.matches[0].replace(nt,rt),U.test(u[0].type)&&t.parentNode||t))){if(u.splice(s,1),e=o.length&&mt(u),!e)return O.apply(r,o),r;break}}}return a(e,f)(o,t,!h,r,U.test(e)),r}n.sortStable=v.split("").sort(S).join("")===v,n.detectDuplicates=E,c(),n.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(p.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||lt("type|href|height|width",function(e,t,n){return n?undefined:e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||lt("value",function(e,t,n){return n||"input"!==e.nodeName.toLowerCase()?undefined:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||lt(R,function(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}),x.find=ot,x.expr=ot.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ot.uniqueSort,x.text=ot.getText,x.isXMLDoc=ot.isXML,x.contains=ot.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(p){for(t=e.memory&&p,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(p[0],p[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!a||n&&!u||(t=t||[],t=[e,t.slice?t.slice():t],r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))x.extend(this.cache[i],t);else for(r in t)o[r]=t[r];return o},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){var r;return t===undefined||t&&"string"==typeof t&&n===undefined?(r=this.get(e,t),r!==undefined?r:this.get(e,x.camelCase(t))):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i,o=this.key(e),s=this.cache[o];if(t===undefined)this.cache[o]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):(i=x.camelCase(t),t in s?r=[t,i]:(r=i,r=r in s?[r]:r.match(w)||[])),n=r.length;while(n--)delete s[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){e[this.expando]&&delete this.cache[e[this.expando]]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.slice(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)
-};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t);x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n\f]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,i=0,o=x(this),s=e.match(w)||[];while(t=s[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,x(this).val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.bool.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,p,f,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(f=x.event.special[d]||{},d=(o?f.delegateType:f.bindType)||d,f=x.event.special[d]||{},p=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,f.setup&&f.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),f.add&&(f.add.call(e,p),p.handler.guid||(p.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,p):h.push(p),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,p,f,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){p=x.event.special[h]||{},h=(r?p.delegateType:p.bindType)||h,f=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=f.length;while(o--)c=f[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(f.splice(o,1),c.selector&&f.delegateCount--,p.remove&&p.remove.call(e,c));s&&!f.length&&(p.teardown&&p.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,p,f,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),f=x.event.special[d]||{},i||!f.trigger||f.trigger.apply(r,n)!==!1)){if(!i&&!f.noBubble&&!x.isWindow(r)){for(l=f.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:f.bindType||d,p=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),p&&p.apply(a,n),p=c&&a[c],p&&x.acceptData(a)&&p.apply&&p.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||f._default&&f._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,s=e,a=this.fixHooks[i];a||(this.fixHooks[i]=a=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new x.Event(s),t=r.length;while(t--)n=r[t],e[n]=s[n];return e.target||(e.target=o),3===e.target.nodeType&&(e.target=e.target.parentNode),a.filter?a.filter(e,s):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=/^(?:parents|prev(?:Until|All))/,Q=x.expr.match.needsContext,K={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(et(this,e||[],!0))},filter:function(e){return this.pushStack(et(this,e||[],!1))},is:function(e){return!!et(this,"string"==typeof e&&Q.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],s=Q.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Z(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return Z(e,"nextSibling")},prev:function(e){return Z(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return e.contentDocument||x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(K[e]||x.unique(i),J.test(e)&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function et(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,nt=/<([\w:]+)/,rt=/<|&#?\w+;/,it=/<(?:script|style|link)/i,ot=/^(?:checkbox|radio)$/i,st=/checked\s*(?:[^=]|=\s*.checked.)/i,at=/^$|\/(?:java|ecma)script/i,ut=/^true\/(.*)/,lt=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ct={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ct.optgroup=ct.option,ct.tbody=ct.tfoot=ct.colgroup=ct.caption=ct.thead,ct.th=ct.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=pt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(mt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&dt(mt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(mt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!it.test(e)&&!ct[(nt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(tt,"<$1></$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(mt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=f.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,p=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&st.test(d))return this.each(function(r){var i=p.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(mt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,mt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,ht),l=0;s>l;l++)a=o[l],at.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(lt,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=mt(a),o=mt(e),r=0,i=o.length;i>r;r++)yt(o[r],s[r]);if(t)if(n)for(o=o||mt(e),s=s||mt(a),r=0,i=o.length;i>r;r++)gt(o[r],s[r]);else gt(e,a);return s=mt(a,"script"),s.length>0&&dt(s,!u&&mt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,p=e.length,f=t.createDocumentFragment(),h=[];for(;p>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(rt.test(i)){o=o||f.appendChild(t.createElement("div")),s=(nt.exec(i)||["",""])[1].toLowerCase(),a=ct[s]||ct._default,o.innerHTML=a[1]+i.replace(tt,"<$1></$2>")+a[2],l=a[0];while(l--)o=o.lastChild;x.merge(h,o.childNodes),o=f.firstChild,o.textContent=""}else h.push(t.createTextNode(i));f.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=mt(f.appendChild(i),"script"),u&&dt(o),n)){l=0;while(i=o[l++])at.test(i.type||"")&&n.push(i)}return f},cleanData:function(e){var t,n,r,i,o,s,a=x.event.special,u=0;for(;(n=e[u])!==undefined;u++){if(F.accepts(n)&&(o=n[q.expando],o&&(t=q.cache[o]))){if(r=Object.keys(t.events||{}),r.length)for(s=0;(i=r[s])!==undefined;s++)a[i]?x.event.remove(n,i):x.removeEvent(n,i,t.handle);q.cache[o]&&delete q.cache[o]}delete L.cache[n[L.expando]]}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}});function pt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ht(e){var t=ut.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function dt(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function gt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=q.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function mt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function yt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&ot.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var vt,xt,bt=/^(none|table(?!-c[ea]).+)/,wt=/^margin/,Tt=RegExp("^("+b+")(.*)$","i"),Ct=RegExp("^("+b+")(?!px)[a-z%]+$","i"),kt=RegExp("^([+-])=("+b+")","i"),Nt={BODY:"block"},Et={position:"absolute",visibility:"hidden",display:"block"},St={letterSpacing:0,fontWeight:400},jt=["Top","Right","Bottom","Left"],Dt=["Webkit","O","Moz","ms"];function At(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Dt.length;while(i--)if(t=Dt[i]+n,t in e)return t;return r}function Lt(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function qt(t){return e.getComputedStyle(t,null)}function Ht(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&Lt(r)&&(o[s]=q.access(r,"olddisplay",Rt(r.nodeName)))):o[s]||(i=Lt(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=qt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return Ht(this,!0)},hide:function(){return Ht(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Lt(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=vt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=At(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=kt.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=At(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=vt(e,t,r)),"normal"===i&&t in St&&(i=St[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),vt=function(e,t,n){var r,i,o,s=n||qt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Ct.test(a)&&wt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ot(e,t,n){var r=Tt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ft(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+jt[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+jt[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+jt[o]+"Width",!0,i))):(s+=x.css(e,"padding"+jt[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+jt[o]+"Width",!0,i)));return s}function Pt(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=qt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=vt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Ct.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ft(e,t,n||(s?"border":"content"),r,o)+"px"}function Rt(e){var t=o,n=Nt[e];return n||(n=Mt(e,t),"none"!==n&&n||(xt=(xt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(xt[0].contentWindow||xt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=Mt(e,t),xt.detach()),Nt[e]=n),n}function Mt(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,t){x.cssHooks[t]={get:function(e,n,r){return n?0===e.offsetWidth&&bt.test(x.css(e,"display"))?x.swap(e,Et,function(){return Pt(e,t,r)}):Pt(e,t,r):undefined},set:function(e,n,r){var i=r&&qt(e);return Ot(e,n,r?Ft(e,t,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,t){return t?x.swap(e,{display:"inline-block"},vt,[e,"marginRight"]):undefined}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,t){x.cssHooks[t]={get:function(e,n){return n?(n=vt(e,t),Ct.test(n)?x(e).position()[t]+"px":n):undefined}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+jt[r]+t]=o[r]||o[r-2]||o[0];return i}},wt.test(e)||(x.cssHooks[e+t].set=Ot)});var Wt=/%20/g,$t=/\[\]$/,Bt=/\r?\n/g,It=/^(?:submit|button|image|reset|file)$/i,zt=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&zt.test(this.nodeName)&&!It.test(e)&&(this.checked||!ot.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(Bt,"\r\n")}}):{name:t.name,value:n.replace(Bt,"\r\n")}}).get()}}),x.param=function(e,t){var n,r=[],i=function(e,t){t=x.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){i(this.name,this.value)});else for(n in e)_t(n,e[n],t,i);return r.join("&").replace(Wt,"+")};function _t(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||$t.test(e)?r(e,i):_t(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)_t(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)
-},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var Xt,Ut,Yt=x.now(),Vt=/\?/,Gt=/#.*$/,Jt=/([?&])_=[^&]*/,Qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Kt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Zt=/^(?:GET|HEAD)$/,en=/^\/\//,tn=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,nn=x.fn.load,rn={},on={},sn="*/".concat("*");try{Ut=i.href}catch(an){Ut=o.createElement("a"),Ut.href="",Ut=Ut.href}Xt=tn.exec(Ut.toLowerCase())||[];function un(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function ln(e,t,n,r){var i={},o=e===on;function s(a){var u;return i[a]=!0,x.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):undefined:(t.dataTypes.unshift(l),s(l),!1)}),u}return s(t.dataTypes[0])||!i["*"]&&s("*")}function cn(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)t[n]!==undefined&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,t,n){if("string"!=typeof e&&nn)return nn.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=e.slice(a),e=e.slice(0,a)),x.isFunction(t)?(n=t,t=undefined):t&&"object"==typeof t&&(i="POST"),s.length>0&&x.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?x("<div>").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ut,type:"GET",isLocal:Kt.test(Xt[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":sn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?cn(cn(e,x.ajaxSettings),t):cn(x.ajaxSettings,e)},ajaxPrefilter:un(rn),ajaxTransport:un(on),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),p=c.context||c,f=c.context&&(p.nodeType||p.jquery)?x(p):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Qt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Ut)+"").replace(Gt,"").replace(en,Xt[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=tn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===Xt[1]&&a[2]===Xt[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(Xt[3]||("http:"===Xt[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),ln(rn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Zt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Vt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Jt.test(r)?r.replace(Jt,"$1_="+Yt++):r+(Vt.test(r)?"&":"?")+"_="+Yt++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+sn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(p,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=ln(on,c,t,T)){T.readyState=1,u&&f.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=pn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e||"HEAD"===c.type?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(p,[m,C,T]):h.rejectWith(p,[T,C,y]),T.statusCode(g),g=undefined,u&&f.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(p,[T,C]),u&&(f.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function pn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(p){return{state:"parsererror",error:s?p:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),o.head.appendChild(t[0])},abort:function(){n&&n()}}}});var hn=[],dn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=hn.pop()||x.expando+"_"+Yt++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");return a||"jsonp"===t.dataTypes[0]?(i=t.jsonpCallback=x.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(Vt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||x.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,hn.push(i)),s&&x.isFunction(o)&&o(s[0]),s=o=undefined}),"script"):undefined}),x.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var gn=x.ajaxSettings.xhr(),mn={0:200,1223:204},yn=0,vn={};e.ActiveXObject&&x(e).on("unload",function(){for(var e in vn)vn[e]();vn=undefined}),x.support.cors=!!gn&&"withCredentials"in gn,x.support.ajax=gn=!!gn,x.ajaxTransport(function(e){var t;return x.support.cors||gn&&!e.crossDomain?{send:function(n,r){var i,o,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete vn[o],t=s.onload=s.onerror=null,"abort"===e?s.abort():"error"===e?r(s.status||404,s.statusText):r(mn[s.status]||s.status,s.statusText,"string"==typeof s.responseText?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=vn[o=yn++]=t("abort"),s.send(e.hasContent&&e.data||null)},abort:function(){t&&t()}}:undefined});var xn,bn,wn=/^(?:toggle|show|hide)$/,Tn=RegExp("^(?:([+-])=|)("+b+")([a-z%]*)$","i"),Cn=/queueHooks$/,kn=[An],Nn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Tn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),s=(x.cssNumber[e]||"px"!==o&&+r)&&Tn.exec(x.css(n.elem,e)),a=1,u=20;if(s&&s[3]!==o){o=o||s[3],i=i||[],s=+r||1;do a=a||".5",s/=a,x.style(n.elem,e,s+o);while(a!==(a=n.cur()/r)&&1!==a&&--u)}return i&&(s=n.start=+s||+r||0,n.unit=o,n.end=i[1]?s+(i[1]+1)*i[2]:+i[2]),n}]};function En(){return setTimeout(function(){xn=undefined}),xn=x.now()}function Sn(e,t,n){var r,i=(Nn[t]||[]).concat(Nn["*"]),o=0,s=i.length;for(;s>o;o++)if(r=i[o].call(n,t,e))return r}function jn(e,t,n){var r,i,o=0,s=kn.length,a=x.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=xn||En(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;for(;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:xn||En(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(Dn(c,l.opts.specialEasing);s>o;o++)if(r=kn[o].call(l,e,c,l.opts))return r;return x.map(c,Sn,l),x.isFunction(l.opts.start)&&l.opts.start.call(e,l),x.fx.timer(x.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function Dn(e,t){var n,r,i,o,s;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=x.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(jn,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Nn[n]=Nn[n]||[],Nn[n].unshift(t)},prefilter:function(e,t){t?kn.unshift(e):kn.push(e)}});function An(e,t,n){var r,i,o,s,a,u,l=this,c={},p=e.style,f=e.nodeType&&Lt(e),h=q.get(e,"fxshow");n.queue||(a=x._queueHooks(e,"fx"),null==a.unqueued&&(a.unqueued=0,u=a.empty.fire,a.empty.fire=function(){a.unqueued||u()}),a.unqueued++,l.always(function(){l.always(function(){a.unqueued--,x.queue(e,"fx").length||a.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(p.display="inline-block")),n.overflow&&(p.overflow="hidden",l.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],wn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show")){if("show"!==i||!h||h[r]===undefined)continue;f=!0}c[r]=h&&h[r]||x.style(e,r)}if(!x.isEmptyObject(c)){h?"hidden"in h&&(f=h.hidden):h=q.access(e,"fxshow",{}),o&&(h.hidden=!f),f?x(e).show():l.done(function(){x(e).hide()}),l.done(function(){var t;q.remove(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)s=Sn(f?h[r]:0,r,l),r in h||(h[r]=s.start,f&&(s.end=s.start,s.start="width"===r||"height"===r?1:0))}}function Ln(e,t,n,r,i){return new Ln.prototype.init(e,t,n,r,i)}x.Tween=Ln,Ln.prototype={constructor:Ln,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=Ln.propHooks[this.prop];return e&&e.get?e.get(this):Ln.propHooks._default.get(this)},run:function(e){var t,n=Ln.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ln.propHooks._default.set(this),this}},Ln.prototype.init.prototype=Ln.prototype,Ln.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Ln.propHooks.scrollTop=Ln.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(qn(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Lt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),s=function(){var t=jn(this,x.extend({},e),o);(i||q.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=undefined),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=x.timers,s=q.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Cn.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=q.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,s=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function qn(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=jt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:qn("show"),slideUp:qn("hide"),slideToggle:qn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=Ln.prototype.init,x.fx.tick=function(){var e,t=x.timers,n=0;for(xn=x.now();t.length>n;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||x.fx.stop(),xn=undefined},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){bn||(bn=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(bn),bn=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===undefined?this:this.each(function(t){x.offset.setOffset(this,e,t)});var t,n,i=this[0],o={top:0,left:0},s=i&&i.ownerDocument;if(s)return t=s.documentElement,x.contains(t,i)?(typeof i.getBoundingClientRect!==r&&(o=i.getBoundingClientRect()),n=Hn(s),{top:o.top+n.pageYOffset-t.clientTop,left:o.left+n.pageXOffset-t.clientLeft}):o},x.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l,c=x.css(e,"position"),p=x(e),f={};"static"===c&&(e.style.position="relative"),a=p.offset(),o=x.css(e,"top"),u=x.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=p.position(),s=r.top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),x.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(f.top=t.top-a.top+s),null!=t.left&&(f.left=t.left-a.left+i),"using"in t?t.using.call(e,f):p.css(f)}},x.fn.extend({position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===x.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(r=e.offset()),r.top+=x.css(e[0],"borderTopWidth",!0),r.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-x.css(n,"marginTop",!0),left:t.left-r.left-x.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;x.fn[t]=function(i){return x.access(this,function(t,i,o){var s=Hn(t);return o===undefined?s?s[n]:t[i]:(s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o,undefined)},t,i,arguments.length,null)}});function Hn(e){return x.isWindow(e)?e:9===e.nodeType&&e.defaultView}x.each({Height:"height",Width:"width"},function(e,t){x.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){x.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(r===!0||i===!0?"margin":"border");return x.access(this,function(t,n,r){var i;return x.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):r===undefined?x.css(t,n,s):x.style(t,n,r,s)},t,o?r:undefined,o,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}),"object"==typeof e&&"object"==typeof e.document&&(e.jQuery=e.$=x)})(window);
diff --git a/src/rustdoc_ng/html/static/main.css b/src/rustdoc_ng/html/static/main.css
deleted file mode 100644 (file)
index 2b96516..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/**
- * Copyright 2013 The Rust Project Developers. See the COPYRIGHT
- * file at the top-level directory of this distribution and at
- * http://rust-lang.org/COPYRIGHT.
- *
- * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- * http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- * <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- * option. This file may not be copied, modified, or distributed
- * except according to those terms.
- */
-
-@import "normalize.css";
-
-* {
-  -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
-}
-
-/* Fonts */
-
-body {
-    font: 13px Arial, sans-serif;
-    line-height: 165%;
-}
-
-h1, .sidebar .location {
-    font: 700 22px "Oswald", Arial, sans-serif;
-}
-
-h2, h3, h4 {
-    font: 700 16px "Oswald", Arial, sans-serif;
-    text-transform: uppercase;
-}
-
-h2 code, h3 code, h4 code {
-    text-transform: none;
-    font-size: 1.2em;
-}
-
-code, pre, h1.fqn {
-    font: 15px "Inconsolata", "Consolas", "Courier New", monospace;
-}
-h1.fqn {
-    font-size: 26px;
-    font-weight: normal;
-}
-
-nav {
-    font: 700 26px "Oswald", Arial, sans-serif;
-    text-transform: uppercase;
-}
-
-nav.sub {
-    padding-top: 20px;
-    font: 700 16px "Oswald", Arial, sans-serif;
-    text-transform: uppercase;
-    text-align: right;
-}
-
-/* General structure */
-
-html, body {
-    min-height: 100%;
-    height: 100%;
-}
-
-body {
-    position: relative;
-    height: auto;
-    padding-bottom: 20px;
-}
-
-.sidebar {
-    width: 200px;
-    position: absolute;
-    left: 0;
-    top: 0;
-    min-height: 100%;
-}
-
-.content, nav { max-width: 960px; }
-
-/* Everything else */
-
-.js-only, .hidden { display: none; }
-
-.sidebar {
-    background: #e9e9e9;
-    padding: 10px;
-}
-
-.sidebar img {
-    margin: 20px auto;
-    display: block;
-}
-
-.sidebar .location { margin-bottom: 10px; }
-.sidebar .block, pre { background: #fff; }
-.sidebar .block, pre, .content { border-bottom: 2px solid black; }
-.trait { border-color: #fcae2b !important; }
-.mod { border-color: #809fc7 !important; }
-.enum { border-color: #93bc99 !important; }
-.struct { border-color: #e53700 !important; }
-.fn { border-color: #a2777f !important; }
-
-.block {
-    padding: 10px;
-    margin-bottom: 10px;
-}
-.block h2 { margin-top: 0; }
-
-.content {
-    background: #f3f3f3;
-    padding: 20px 20px 20px 40px;
-}
-.content h1 { margin-top: 0; }
-.content h1, .content h2 { margin-left: -20px; }
-.content pre { padding: 20px; }
-
-.content .highlighted {
-    cursor: pointer;
-    color: #000 !important;
-    background-color: #ccc;
-}
-.content .highlighted a { color: #000 !important; }
-.content .highlighted.trait { background-color: #fece7e; }
-.content .highlighted.mod { background-color: #afc6e4; }
-.content .highlighted.enum { background-color: #b4d1b9; }
-.content .highlighted.struct { background-color: #e7b1a0; }
-.content .highlighted.fn { background-color: #c6afb3; }
-
-.docblock.short.nowrap {
-    display: block;
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-.docblock.short p {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    margin: 0;
-}
-
-.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
-    margin-left: 0;
-}
-
-.docblock h1 { font-size: 1.1em; }
-.docblock h2 { font-size: 1.05em; }
-.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
-
-.content .source { float: right; }
-.content table {
-    border-spacing: 0 5px;
-    border-collapse: separate;
-}
-.content td { vertical-align: top; }
-.content td:first-child { padding-right: 20px; }
-.content td p:first-child { margin-top: 0; }
-.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; }
-
-.content .item-list {
-    list-style-type: none;
-    padding: 0;
-}
-
-.content .item-list li { margin-bottom: 3px; }
-
-.content .multi-column {
-    -moz-column-count: 5;
-    -moz-column-gap: 2.5em;
-    -webkit-column-count: 5;
-    -webkit-column-gap: 2.5em;
-    column-count: 5;
-    column-gap: 2.5em;
-}
-.content .multi-column li { width: 100%; display: inline-block; }
-
-.content .method { font-size: 1em; }
-.content .methods { margin-left: 20px; }
-.content .methods .docblock { margin-left: 20px; }
-
-nav {
-    border-bottom: 1px solid #e0e0e0;
-    padding-bottom: 10px;
-    margin-bottom: 10px;
-}
-nav.main {
-    padding: 20px 0;
-    text-align: center;
-}
-nav.main .current {
-    border-top: 1px solid #000;
-    border-bottom: 1px solid #000;
-}
-nav.main .separator {
-    border: 1px solid #000;
-    display: inline-block;
-    height: 23px;
-    margin: 0 20px;
-}
-nav.sum { text-align: right; }
-nav.sub form { display: inline; }
-
-nav, .content {
-    margin-left: 220px;
-    margin-right: 20px;
-}
-
-a {
-    text-decoration: none;
-    color: #000;
-}
-
-.content a, .block a.current { font-weight: bold; }
-
-.content a.trait, .block a.current.trait { color: #ed9603; }
-.content a.mod, .block a.current.mod { color: #4d76ae; }
-.content a.enum, .block a.current.enum { color: #5e9766; }
-.content a.struct, .block a.current.struct { color: #e53700; }
-.content a.fn, .block a.current.fn { color: #8c6067; }
-
-.search-input {
-    border: 2px solid #f2f2f2;
-    border-radius: 2px;
-    width: 350px;
-}
-.search-results .desc {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    display: block;
-}
-
-#help {
-    background: #e9e9e9;
-    border-radius: 4px;
-    box-shadow: 0 0 6px rgba(0,0,0,.2);
-
-    position: absolute;
-    top: 300px;
-    left: 50%;
-    margin-top: -125px;
-    margin-left: -275px;
-    width: 550px;
-    height: 250px;
-    border: 1px solid #bfbfbf;
-}
-
-#help dt {
-    float: left;
-    border-radius: 3px;
-    border: 1px solid #bfbfbf;
-    background: #fff;
-    width: 23px;
-    text-align: center;
-    clear: left;
-    display: block;
-    margin-top: -1px;
-}
-#help dd { margin: 5px 33px; }
-#help .infos { padding-left: 0; }
-#help h1 { margin-top: 0; }
-#help div {
-    width: 50%;
-    float: left;
-    padding: 20px;
-}
diff --git a/src/rustdoc_ng/html/static/main.js b/src/rustdoc_ng/html/static/main.js
deleted file mode 100644 (file)
index b5ae3da..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*jslint browser: true, es5: true */
-/*globals $: true, searchIndex: true, rootPath: true, allPaths: true */
-
-(function () {
-    "use strict";
-    var resizeTimeout, interval;
-
-    $('.js-only').removeClass('js-only');
-
-    function resizeShortBlocks() {
-        if (resizeTimeout) {
-            clearTimeout(resizeTimeout);
-        }
-        resizeTimeout = setTimeout(function () {
-            var contentWidth = $('.content').width();
-            $('.docblock.short').width(function () {
-                return contentWidth - 40 - $(this).prev().width();
-            }).addClass('nowrap');
-        }, 150);
-    }
-    resizeShortBlocks();
-    $(window).on('resize', resizeShortBlocks);
-
-    $(document).on('keyup', function (e) {
-        if (document.activeElement.tagName === 'INPUT') {
-            return;
-        }
-
-        if (e.keyCode === 188 && $('#help').hasClass('hidden')) { // question mark
-            e.preventDefault();
-            $('#help').removeClass('hidden');
-        } else if (e.keyCode === 27 && !$('#help').hasClass('hidden')) { // esc
-            e.preventDefault();
-            $('#help').addClass('hidden');
-        } else if (e.keyCode === 83) { // S
-            e.preventDefault();
-            $('.search-input').focus();
-        }
-    }).on('click', function (e) {
-        if (!$(e.target).closest('#help').length) {
-            $('#help').addClass('hidden');
-        }
-    });
-
-    $('.version-selector').on('change', function () {
-        var i, match,
-            url = document.location.href,
-            stripped = '',
-            len = rootPath.match(/\.\.\//g).length + 1;
-
-        for (i = 0; i < len; i += 1) {
-            match = url.match(/\/[^\/]*$/);
-            if (i < len - 1) {
-                stripped = match[0] + stripped;
-            }
-            url = url.substring(0, url.length - match[0].length);
-        }
-
-        url += '/' + $('.version-selector').val() + stripped;
-
-        document.location.href = url;
-    });
-
-    function initSearch(searchIndex) {
-        var currentResults, index;
-
-        // clear cached values from the search bar
-        $(".search-input")[0].value = '';
-
-        function execQuery(query, max, searchWords) {
-            var valLower = query.query.toLowerCase(),
-                val = valLower,
-                typeFilter = query.type,
-                results = [],
-                aa = 0,
-                bb = 0;
-
-            // quoted values mean literal search
-            bb = searchWords.length;
-            if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && val.charAt(val.length - 1) === val.charAt(0)) {
-                val = val.substr(1, val.length - 2);
-                for (aa = 0; aa < bb; aa += 1) {
-                    if (searchWords[aa] === val) {
-                        // filter type: ... queries
-                        if (!typeFilter || typeFilter === searchIndex[aa].ty) {
-                            results.push([aa, -1]);
-                        }
-                    }
-                    if (results.length === max) {
-                        break;
-                    }
-                }
-            } else {
-                // gather matching search results up to a certain maximum
-                val = val.replace(/\_/g, "");
-                for (aa = 0; aa < bb; aa += 1) {
-                    if (searchWords[aa].indexOf(val) > -1 || searchWords[aa].replace(/_/g, "").indexOf(val) > -1) {
-                        // filter type: ... queries
-                        if (!typeFilter || typeFilter === searchIndex[aa].ty) {
-                            results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
-                        }
-                    }
-                    if (results.length === max) {
-                        break;
-                    }
-                }
-            }
-            bb = results.length;
-            for (aa = 0; aa < bb; aa += 1) {
-                results[aa].push(searchIndex[results[aa][0]].ty);
-            }
-            for (aa = 0; aa < bb; aa += 1) {
-                results[aa].push(searchIndex[results[aa][0]].path);
-            }
-
-            // if there are no results then return to default and fail
-            if (results.length === 0) {
-                return [];
-            }
-
-            // sort by exact match
-            results.sort(function search_complete_sort0(aaa, bbb) {
-                if (searchWords[aaa[0]] === valLower && searchWords[bbb[0]] !== valLower) {
-                    return 1;
-                }
-            });
-            // first sorting attempt
-            // sort by item name length
-            results.sort(function search_complete_sort1(aaa, bbb) {
-                if (searchWords[aaa[0]].length > searchWords[bbb[0]].length) {
-                    return 1;
-                }
-            });
-            // second sorting attempt
-            // sort by item name
-            results.sort(function search_complete_sort1(aaa, bbb) {
-                if (searchWords[aaa[0]].length === searchWords[bbb[0]].length && searchWords[aaa[0]] > searchWords[bbb[0]]) {
-                    return 1;
-                }
-            });
-            // third sorting attempt
-            // sort by index of keyword in item name
-            if (results[0][1] !== -1) {
-                results.sort(function search_complete_sort1(aaa, bbb) {
-                    if (aaa[1] > bbb[1] && bbb[1] === 0) {
-                        return 1;
-                    }
-                });
-            }
-            // fourth sorting attempt
-            // sort by type
-            results.sort(function search_complete_sort3(aaa, bbb) {
-                if (searchWords[aaa[0]] === searchWords[bbb[0]] && aaa[2] > bbb[2]) {
-                    return 1;
-                }
-            });
-            // fifth sorting attempt
-            // sort by path
-            results.sort(function search_complete_sort4(aaa, bbb) {
-                if (searchWords[aaa[0]] === searchWords[bbb[0]] && aaa[2] === bbb[2] && aaa[3] > bbb[3]) {
-                    return 1;
-                }
-            });
-            // sixth sorting attempt
-            // remove duplicates, according to the data provided
-            for (aa = results.length - 1; aa > 0; aa -= 1) {
-                if (searchWords[results[aa][0]] === searchWords[results[aa - 1][0]] && results[aa][2] === results[aa - 1][2] && results[aa][3] === results[aa - 1][3]) {
-                    results[aa][0] = -1;
-                }
-            }
-
-            return results;
-        }
-
-        function getQuery() {
-            var matches, type, query = $('.search-input').val();
-
-            matches = query.match(/^(fn|mod|str(uct)?|enum|trait|t(ype)?d(ef)?)\s*:\s*/i);
-            if (matches) {
-                type = matches[1].replace(/^td$/, 'typedef').replace(/^str$/, 'struct').replace(/^tdef$/, 'typedef').replace(/^typed$/, 'typedef');
-                query = query.substring(matches[0].length);
-            }
-
-            return {
-                query: query,
-                type: type,
-                id: query + type,
-            };
-        }
-
-        function initSearchNav() {
-            var hoverTimeout, $results = $('.search-results .result');
-
-            $results.on('click', function () {
-                document.location.href = $(this).find('a').prop('href');
-            }).on('mouseover', function () {
-                var $el = $(this);
-                clearTimeout(hoverTimeout);
-                hoverTimeout = setTimeout(function () {
-                    $results.removeClass('highlighted');
-                    $el.addClass('highlighted');
-                }, 20);
-            });
-
-            $(document).off('keyup.searchnav');
-            $(document).on('keyup.searchnav', function (e) {
-                var $active = $results.filter('.highlighted');
-
-                if (e.keyCode === 38) { // up
-                    e.preventDefault();
-                    if (!$active.length || !$active.prev()) {
-                        return;
-                    }
-
-                    $active.prev().addClass('highlighted');
-                    $active.removeClass('highlighted');
-                } else if (e.keyCode === 40) { // down
-                    e.preventDefault();
-                    if (!$active.length) {
-                        $results.first().addClass('highlighted');
-                    } else if ($active.next().length) {
-                        $active.next().addClass('highlighted');
-                        $active.removeClass('highlighted');
-                    }
-                } else if (e.keyCode === 13) { // return
-                    e.preventDefault();
-                    if ($active.length) {
-                        document.location.href = $active.find('a').prop('href');
-                    }
-                }
-            });
-        }
-
-        function showResults(results) {
-            var output, shown, query = getQuery();
-
-            currentResults = query.id;
-            output = '<h1>Results for ' + query.query + (query.type ? ' (type: ' + query.type + ')' : '') + '</h1>';
-            output += '<table class="search-results">';
-
-            if (results.length > 0) {
-                shown = [];
-
-                results.forEach(function (item) {
-                    var name, type;
-
-                    if (shown.indexOf(item) !== -1) {
-                        return;
-                    }
-
-                    shown.push(item);
-                    name = item.name;
-                    type = item.ty;
-
-                    output += '<tr class="' + type + ' result"><td>';
-
-                    if (type === 'mod') {
-                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + name + '/index.html" class="' + type + '">' + name + '</a>';
-                    } else if (type === 'static' || type === 'reexport') {
-                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/index.html" class="' + type + '">' + name + '</a>';
-                    } else if (item.parent !== undefined) {
-                        var myparent = allPaths[item.parent];
-                        output += item.path + '::' + myparent.name + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + myparent.type + '.' + myparent.name + '.html" class="' + type + '">' + name + '</a>';
-                    } else {
-                        output += item.path + '::<a href="' + rootPath + item.path.replace(/::/g, '/') + '/' + type + '.' + name + '.html" class="' + type + '">' + name + '</a>';
-                    }
-
-                    output += '</td><td><span class="desc">' + item.desc + '</span></td></tr>';
-                });
-            } else {
-                output += 'No results :( <a href="https://duckduckgo.com/?q=' + encodeURIComponent('rust ' + query.query) + '">Try on DuckDuckGo?</a>';
-            }
-
-            output += "</p>";
-            $('.content').html(output);
-            $('.search-results .desc').width($('.content').width() - 40 - $('.content td:first-child').first().width());
-            initSearchNav();
-        }
-
-        function search(e) {
-            var query, filterdata = [], obj, i, len,
-                results = [],
-                maxResults = 200,
-                resultIndex;
-
-            query = getQuery();
-            if (e) {
-                e.preventDefault();
-            }
-
-            if (!query.query || query.id === currentResults) {
-                return;
-            }
-
-            resultIndex = execQuery(query, 20000, index);
-            len = resultIndex.length;
-            for (i = 0; i < len; i += 1) {
-                if (resultIndex[i][0] > -1) {
-                    obj = searchIndex[resultIndex[i][0]];
-                    filterdata.push([obj.name, obj.ty, obj.path, obj.desc]);
-                    results.push(obj);
-                }
-                if (results.length >= maxResults) {
-                    break;
-                }
-            }
-
-            // TODO add sorting capability through this function?
-            //
-            //            // the handler for the table heading filtering
-            //            filterdraw = function search_complete_filterdraw(node) {
-            //                var name = "",
-            //                    arrow = "",
-            //                    op = 0,
-            //                    tbody = node.parentNode.parentNode.nextSibling,
-            //                    anchora = {},
-            //                    tra = {},
-            //                    tha = {},
-            //                    td1a = {},
-            //                    td2a = {},
-            //                    td3a = {},
-            //                    aaa = 0,
-            //                    bbb = 0;
-            //
-            //                // the 4 following conditions set the rules for each
-            //                // table heading
-            //                if (node === ths[0]) {
-            //                    op = 0;
-            //                    name = "name";
-            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
-            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
-            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
-            //                }
-            //                if (node === ths[1]) {
-            //                    op = 1;
-            //                    name = "type";
-            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
-            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
-            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
-            //                }
-            //                if (node === ths[2]) {
-            //                    op = 2;
-            //                    name = "path";
-            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
-            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
-            //                    ths[3].innerHTML = ths[3].innerHTML.split(" ")[0];
-            //                }
-            //                if (node === ths[3]) {
-            //                    op = 3;
-            //                    name = "description";
-            //                    ths[0].innerHTML = ths[0].innerHTML.split(" ")[0];
-            //                    ths[1].innerHTML = ths[1].innerHTML.split(" ")[0];
-            //                    ths[2].innerHTML = ths[2].innerHTML.split(" ")[0];
-            //                }
-            //
-            //                // ascending or descending search
-            //                arrow = node.innerHTML.split(" ")[1];
-            //                if (arrow === undefined || arrow === "\u25b2") {
-            //                    arrow = "\u25bc";
-            //                } else {
-            //                    arrow = "\u25b2";
-            //                }
-            //
-            //                // filter the data
-            //                filterdata.sort(function search_complete_filterDraw_sort(xx, yy) {
-            //                    if ((arrow === "\u25b2" && xx[op].toLowerCase() < yy[op].toLowerCase()) || (arrow === "\u25bc" && xx[op].toLowerCase() > yy[op].toLowerCase())) {
-            //                        return 1;
-            //                    }
-            //                });
-            //            };
-
-            showResults(results);
-        }
-
-        function buildIndex(searchIndex) {
-            var len = searchIndex.length,
-                i = 0,
-                searchWords = [];
-
-            // before any analysis is performed lets gather the search terms to
-            // search against apart from the rest of the data.  This is a quick
-            // operation that is cached for the life of the page state so that
-            // all other search operations have access to this cached data for
-            // faster analysis operations
-            for (i = 0; i < len; i += 1) {
-                if (typeof searchIndex[i].name === "string") {
-                    searchWords.push(searchIndex[i].name.toLowerCase());
-                } else {
-                    searchWords.push("");
-                }
-            }
-
-            return searchWords;
-        }
-
-        function startSearch() {
-            var keyUpTimeout;
-            $('.do-search').on('click', search);
-            $('.search-input').on('keyup', function () {
-                clearTimeout(keyUpTimeout);
-                keyUpTimeout = setTimeout(search, 100);
-            });
-        }
-
-        index = buildIndex(searchIndex);
-        startSearch();
-    }
-
-    initSearch(searchIndex);
-}());
diff --git a/src/rustdoc_ng/html/static/normalize.css b/src/rustdoc_ng/html/static/normalize.css
deleted file mode 100644 (file)
index 6adf56e..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/*! normalize.css v2.1.2 | 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 styling not present in IE 8/9.
- */
-
-[hidden] {
-    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
-   ========================================================================== */
-
-/**
- * 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.
- * 2. Remove excess padding in IE 8/9.
- */
-
-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/src/rustdoc_ng/passes.rs b/src/rustdoc_ng/passes.rs
deleted file mode 100644 (file)
index e580ab0..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::num;
-use std::uint;
-
-use clean;
-use syntax::ast;
-use clean::Item;
-use plugins;
-use fold;
-use fold::DocFolder;
-
-/// Strip items marked `#[doc(hidden)]`
-pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult {
-    struct Stripper;
-    impl fold::DocFolder for Stripper {
-        fn fold_item(&mut self, i: Item) -> Option<Item> {
-            for attr in i.attrs.iter() {
-                match attr {
-                    &clean::List(~"doc", ref l) => {
-                        for innerattr in l.iter() {
-                            match innerattr {
-                                &clean::Word(ref s) if "hidden" == *s => {
-                                    debug!("found one in strip_hidden; removing");
-                                    return None;
-                                },
-                                _ => (),
-                            }
-                        }
-                    },
-                    _ => ()
-                }
-            }
-            self.fold_item_recur(i)
-        }
-    }
-    let mut stripper = Stripper;
-    let crate = stripper.fold_crate(crate);
-    (crate, None)
-}
-
-pub fn unindent_comments(crate: clean::Crate) -> plugins::PluginResult {
-    struct CommentCleaner;
-    impl fold::DocFolder for CommentCleaner {
-        fn fold_item(&mut self, i: Item) -> Option<Item> {
-            let mut i = i;
-            let mut avec: ~[clean::Attribute] = ~[];
-            for attr in i.attrs.iter() {
-                match attr {
-                    &clean::NameValue(~"doc", ref s) => avec.push(
-                        clean::NameValue(~"doc", unindent(*s))),
-                    x => avec.push(x.clone())
-                }
-            }
-            i.attrs = avec;
-            self.fold_item_recur(i)
-        }
-    }
-    let mut cleaner = CommentCleaner;
-    let crate = cleaner.fold_crate(crate);
-    (crate, None)
-}
-
-pub fn collapse_privacy(crate: clean::Crate) -> plugins::PluginResult {
-    struct PrivacyCollapser {
-        stack: ~[clean::Visibility]
-    }
-    impl fold::DocFolder for PrivacyCollapser {
-        fn fold_item(&mut self, mut i: Item) -> Option<Item> {
-            if i.visibility.is_some() {
-                if i.visibility == Some(ast::inherited) {
-                    i.visibility = Some(self.stack.last().clone());
-                } else {
-                    self.stack.push(i.visibility.clone().unwrap());
-                }
-            }
-            self.fold_item_recur(i)
-        }
-    }
-    let mut privacy = PrivacyCollapser { stack: ~[] };
-    let crate = privacy.fold_crate(crate);
-    (crate, None)
-}
-
-pub fn collapse_docs(crate: clean::Crate) -> plugins::PluginResult {
-    struct Collapser;
-    impl fold::DocFolder for Collapser {
-        fn fold_item(&mut self, i: Item) -> Option<Item> {
-            let mut docstr = ~"";
-            let mut i = i;
-            for attr in i.attrs.iter() {
-                match *attr {
-                    clean::NameValue(~"doc", ref s) => {
-                        docstr.push_str(s.clone());
-                        docstr.push_char('\n');
-                    },
-                    _ => ()
-                }
-            }
-            let mut a: ~[clean::Attribute] = i.attrs.iter().filter(|&a| match a {
-                &clean::NameValue(~"doc", _) => false,
-                _ => true
-            }).map(|x| x.clone()).collect();
-            if "" != docstr {
-                a.push(clean::NameValue(~"doc", docstr.trim().to_owned()));
-            }
-            i.attrs = a;
-            self.fold_item_recur(i)
-        }
-    }
-    let mut collapser = Collapser;
-    let crate = collapser.fold_crate(crate);
-    (crate, None)
-}
-
-// n.b. this is copied from src/librustdoc/unindent_pass.rs
-pub fn unindent(s: &str) -> ~str {
-    let lines = s.any_line_iter().collect::<~[&str]>();
-    let mut saw_first_line = false;
-    let mut saw_second_line = false;
-    let min_indent = do lines.iter().fold(uint::max_value) |min_indent, line| {
-
-        // After we see the first non-whitespace line, look at
-        // the line we have. If it is not whitespace, and therefore
-        // part of the first paragraph, then ignore the indentation
-        // level of the first line
-        let ignore_previous_indents =
-            saw_first_line &&
-            !saw_second_line &&
-            !line.is_whitespace();
-
-        let min_indent = if ignore_previous_indents {
-            uint::max_value
-        } else {
-            min_indent
-        };
-
-        if saw_first_line {
-            saw_second_line = true;
-        }
-
-        if line.is_whitespace() {
-            min_indent
-        } else {
-            saw_first_line = true;
-            let mut spaces = 0;
-            do line.iter().all |char| {
-                // Only comparing against space because I wouldn't
-                // know what to do with mixed whitespace chars
-                if char == ' ' {
-                    spaces += 1;
-                    true
-                } else {
-                    false
-                }
-            };
-            num::min(min_indent, spaces)
-        }
-    };
-
-    match lines {
-        [head, .. tail] => {
-            let mut unindented = ~[ head.trim() ];
-            unindented.push_all(do tail.map |&line| {
-                if line.is_whitespace() {
-                    line
-                } else {
-                    assert!(line.len() >= min_indent);
-                    line.slice_from(min_indent)
-                }
-            });
-            unindented.connect("\n")
-        }
-        [] => s.to_owned()
-    }
-}
-
-#[cfg(test)]
-mod unindent_tests {
-    use super::unindent;
-
-    #[test]
-    fn should_unindent() {
-        let s = ~"    line1\n    line2";
-        let r = unindent(s);
-        assert_eq!(r, ~"line1\nline2");
-    }
-
-    #[test]
-    fn should_unindent_multiple_paragraphs() {
-        let s = ~"    line1\n\n    line2";
-        let r = unindent(s);
-        assert_eq!(r, ~"line1\n\nline2");
-    }
-
-    #[test]
-    fn should_leave_multiple_indent_levels() {
-        // Line 2 is indented another level beyond the
-        // base indentation and should be preserved
-        let s = ~"    line1\n\n        line2";
-        let r = unindent(s);
-        assert_eq!(r, ~"line1\n\n    line2");
-    }
-
-    #[test]
-    fn should_ignore_first_line_indent() {
-        // Thi first line of the first paragraph may not be indented as
-        // far due to the way the doc string was written:
-        //
-        // #[doc = "Start way over here
-        //          and continue here"]
-        let s = ~"line1\n    line2";
-        let r = unindent(s);
-        assert_eq!(r, ~"line1\nline2");
-    }
-
-    #[test]
-    fn should_not_ignore_first_line_indent_in_a_single_line_para() {
-        let s = ~"line1\n\n    line2";
-        let r = unindent(s);
-        assert_eq!(r, ~"line1\n\n    line2");
-    }
-}
diff --git a/src/rustdoc_ng/plugins.rs b/src/rustdoc_ng/plugins.rs
deleted file mode 100644 (file)
index 4bad870..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use clean;
-
-use extra;
-use dl = std::unstable::dynamic_lib;
-
-pub type PluginJson = Option<(~str, extra::json::Json)>;
-pub type PluginResult = (clean::Crate, PluginJson);
-pub type plugin_callback = extern fn (clean::Crate) -> PluginResult;
-
-/// Manages loading and running of plugins
-pub struct PluginManager {
-    priv dylibs: ~[dl::DynamicLibrary],
-    priv callbacks: ~[plugin_callback],
-    /// The directory plugins will be loaded from
-    prefix: Path,
-}
-
-impl PluginManager {
-    /// Create a new plugin manager
-    pub fn new(prefix: Path) -> PluginManager {
-        PluginManager {
-            dylibs: ~[],
-            callbacks: ~[],
-            prefix: prefix,
-        }
-    }
-
-    /// Load a plugin with the given name.
-    ///
-    /// Turns `name` into the proper dynamic library filename for the given
-    /// platform. On windows, it turns into name.dll, on OS X, name.dylib, and
-    /// elsewhere, libname.so.
-    pub fn load_plugin(&mut self, name: ~str) {
-        let x = self.prefix.push(libname(name));
-        let lib_result = dl::DynamicLibrary::open(Some(&x));
-        let lib = lib_result.unwrap();
-        let plugin = unsafe { lib.symbol("rustdoc_plugin_entrypoint") }.unwrap();
-        self.dylibs.push(lib);
-        self.callbacks.push(plugin);
-    }
-
-    /// Load a normal Rust function as a plugin.
-    ///
-    /// This is to run passes over the cleaned crate. Plugins run this way
-    /// correspond to the A-aux tag on Github.
-    pub fn add_plugin(&mut self, plugin: plugin_callback) {
-        self.callbacks.push(plugin);
-    }
-    /// Run all the loaded plugins over the crate, returning their results
-    pub fn run_plugins(&self, crate: clean::Crate) -> (clean::Crate, ~[PluginJson]) {
-        let mut out_json = ~[];
-        let mut crate = crate;
-        for &callback in self.callbacks.iter() {
-            let (c, res) = callback(crate);
-            crate = c;
-            out_json.push(res);
-        }
-        (crate, out_json)
-    }
-}
-
-#[cfg(target_os="win32")]
-fn libname(mut n: ~str) -> ~str {
-    n.push_str(".dll");
-    n
-}
-
-#[cfg(target_os="macos")]
-fn libname(mut n: ~str) -> ~str {
-    n.push_str(".dylib");
-    n
-}
-
-#[cfg(not(target_os="win32"), not(target_os="macos"))]
-fn libname(n: ~str) -> ~str {
-    let mut i = ~"lib";
-    i.push_str(n);
-    i.push_str(".so");
-    i
-}
diff --git a/src/rustdoc_ng/rustdoc_ng.rs b/src/rustdoc_ng/rustdoc_ng.rs
deleted file mode 100644 (file)
index 4bff60c..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[link(name = "rustdoc_ng",
-       vers = "0.8-pre",
-       uuid = "8c6e4598-1596-4aa5-a24c-b811914bbbc6",
-       url = "https://github.com/mozilla/rust/tree/master/src/rustdoc_ng")];
-
-#[desc = "rustdoc, the Rust documentation extractor"];
-#[license = "MIT/ASL2"];
-#[crate_type = "lib"];
-
-extern mod syntax;
-extern mod rustc;
-extern mod extra;
-
-use extra::serialize::Encodable;
-use extra::time;
-use std::cell::Cell;
-use std::rt::io;
-use std::rt::io::Writer;
-use std::rt::io::file::FileInfo;
-
-pub mod clean;
-pub mod core;
-pub mod doctree;
-pub mod fold;
-pub mod html {
-    pub mod render;
-    pub mod layout;
-    pub mod markdown;
-    pub mod format;
-}
-pub mod passes;
-pub mod plugins;
-pub mod visit_ast;
-
-pub static SCHEMA_VERSION: &'static str = "0.8.0";
-
-local_data_key!(pub ctxtkey: @core::DocContext)
-
-enum OutputFormat {
-    HTML, JSON
-}
-
-pub fn main() {
-    main_args(std::os::args());
-}
-
-pub fn main_args(args: &[~str]) {
-    use extra::getopts::groups::*;
-
-    let opts = ~[
-        optmulti("L", "library-path", "directory to add to crate search path",
-                 "DIR"),
-        optmulti("", "plugin-path", "directory to load plugins from", "DIR"),
-        optmulti("", "passes", "space separated list of passes to also run",
-                 "PASSES"),
-        optmulti("", "plugins", "space separated list of plugins to also load",
-                 "PLUGINS"),
-        optflag("h", "help", "show this help message"),
-        optflag("", "nodefaults", "don't run the default passes"),
-        optopt("o", "output", "where to place the output", "PATH"),
-    ];
-
-    let matches = getopts(args.tail(), opts).unwrap();
-
-    let myusage = || {
-        println(usage(format!("{} [options] [html|json] <crate>", args[0]), opts));
-    };
-
-    if matches.opt_present("h") || matches.opt_present("help") {
-        myusage();
-        return;
-    }
-
-    let (format, cratefile) = match matches.free.clone() {
-        [~"json", crate] => (JSON, crate),
-        [~"html", crate] => (HTML, crate),
-        [s, _] => {
-            println!("Unknown output format: `{}`", s);
-            myusage();
-            exit(1);
-        }
-        [_, .._] => {
-            println!("Expected exactly one crate to process");
-            myusage();
-            exit(1);
-        }
-        _ => {
-            println!("Expected an output format and then one crate");
-            myusage();
-            exit(1);
-        }
-    };
-
-    // First, parse the crate and extract all relevant information.
-    let libs = Cell::new(matches.opt_strs("L").map(|s| Path(*s)));
-    let cr = Cell::new(Path(cratefile));
-    info2!("starting to run rustc");
-    let crate = do std::task::try {
-        let cr = cr.take();
-        core::run_core(libs.take(), &cr)
-    }.unwrap();
-    info2!("finished with rustc");
-
-    // Process all of the crate attributes, extracting plugin metadata along
-    // with the passes which we are supposed to run.
-    let mut default_passes = !matches.opt_present("nodefaults");
-    let mut passes = matches.opt_strs("passes");
-    let mut plugins = matches.opt_strs("plugins");
-    match crate.module.get_ref().doc_list() {
-        Some(nested) => {
-            for inner in nested.iter() {
-                match *inner {
-                    clean::Word(~"no_default_passes") => {
-                        default_passes = false;
-                    }
-                    clean::NameValue(~"passes", ref value) => {
-                        for pass in value.word_iter() {
-                            passes.push(pass.to_owned());
-                        }
-                    }
-                    clean::NameValue(~"plugins", ref value) => {
-                        for p in value.word_iter() {
-                            plugins.push(p.to_owned());
-                        }
-                    }
-                    _ => {}
-                }
-            }
-        }
-        None => {}
-    }
-    if default_passes {
-        passes.unshift(~"collapse-docs");
-        passes.unshift(~"unindent-comments");
-    }
-
-    // Load all plugins/passes into a PluginManager
-    let mut pm = plugins::PluginManager::new(Path("/tmp/rustdoc_ng/plugins"));
-    for pass in passes.iter() {
-        let plugin = match pass.as_slice() {
-            "strip-hidden" => passes::strip_hidden,
-            "unindent-comments" => passes::unindent_comments,
-            "collapse-docs" => passes::collapse_docs,
-            "collapse-privacy" => passes::collapse_privacy,
-            s => { error!("unknown pass %s, skipping", s); loop },
-        };
-        pm.add_plugin(plugin);
-    }
-    info2!("loading plugins...");
-    for pname in plugins.move_iter() {
-        pm.load_plugin(pname);
-    }
-
-    // Run everything!
-    info2!("Executing passes/plugins");
-    let (crate, res) = pm.run_plugins(crate);
-
-    info2!("going to format");
-    let started = time::precise_time_ns();
-    let output = matches.opt_str("o").map(|s| Path(*s));
-    match format {
-        HTML => { html::render::run(crate, output.unwrap_or(Path("doc"))) }
-        JSON => { jsonify(crate, res, output.unwrap_or(Path("doc.json"))) }
-    }
-    let ended = time::precise_time_ns();
-    info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
-}
-
-fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
-    // {
-    //   "schema": version,
-    //   "crate": { parsed crate ... },
-    //   "plugins": { output of plugins ... }
-    // }
-    let mut json = ~extra::treemap::TreeMap::new();
-    json.insert(~"schema", extra::json::String(SCHEMA_VERSION.to_owned()));
-    let plugins_json = ~res.move_iter().filter_map(|opt| opt).collect();
-
-    // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
-    // straight to the Rust JSON representation.
-    let crate_json_str = do std::io::with_str_writer |w| {
-        crate.encode(&mut extra::json::Encoder(w));
-    };
-    let crate_json = match extra::json::from_str(crate_json_str) {
-        Ok(j) => j,
-        Err(_) => fail!("Rust generated JSON is invalid??")
-    };
-
-    json.insert(~"crate", crate_json);
-    json.insert(~"plugins", extra::json::Object(plugins_json));
-
-    let mut file = dst.open_writer(io::Create).unwrap();
-    let output = extra::json::Object(json).to_str();
-    file.write(output.as_bytes());
-}
-
-fn exit(status: int) -> ! {
-    #[fixed_stack_segment]; #[inline(never)];
-    use std::libc;
-    unsafe { libc::exit(status as libc::c_int) }
-}
diff --git a/src/rustdoc_ng/visit_ast.rs b/src/rustdoc_ng/visit_ast.rs
deleted file mode 100644 (file)
index 14be80f..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Rust AST Visitor. Extracts useful information and massages it into a form
-//! usable for clean
-
-use syntax::abi::AbiSet;
-use syntax::{ast, ast_map};
-use syntax::codemap::Span;
-
-use doctree::*;
-use std::local_data;
-
-pub struct RustdocVisitor {
-    module: Module,
-    attrs: ~[ast::Attribute],
-}
-
-impl RustdocVisitor {
-    pub fn new() -> RustdocVisitor {
-        RustdocVisitor {
-            module: Module::new(None),
-            attrs: ~[],
-        }
-    }
-}
-
-impl RustdocVisitor {
-    pub fn visit(@mut self, crate: &ast::Crate) {
-        self.attrs = crate.attrs.clone();
-        fn visit_struct_def(item: &ast::item, sd: @ast::struct_def, generics:
-                            &ast::Generics) -> Struct {
-            debug!("Visiting struct");
-            let struct_type = struct_type_from_def(sd);
-            Struct {
-                id: item.id,
-                struct_type: struct_type,
-                name: item.ident,
-                vis: item.vis,
-                attrs: item.attrs.clone(),
-                generics: generics.clone(),
-                fields: sd.fields.iter().map(|x| (*x).clone()).to_owned_vec(),
-                where: item.span
-            }
-        }
-
-        fn visit_enum_def(it: &ast::item, def: &ast::enum_def, params: &ast::Generics) -> Enum {
-            debug!("Visiting enum");
-            let mut vars: ~[Variant] = ~[];
-            for x in def.variants.iter() {
-                vars.push(Variant {
-                    name: x.node.name,
-                    attrs: x.node.attrs.clone(),
-                    vis: x.node.vis,
-                    id: x.node.id,
-                    kind: x.node.kind.clone(),
-                    where: x.span,
-                });
-            }
-            Enum {
-                name: it.ident,
-                variants: vars,
-                vis: it.vis,
-                generics: params.clone(),
-                attrs: it.attrs.clone(),
-                id: it.id,
-                where: it.span,
-            }
-        }
-
-        fn visit_fn(item: &ast::item, fd: &ast::fn_decl, _purity: &ast::purity,
-                     _abi: &AbiSet, gen: &ast::Generics) -> Function {
-            debug!("Visiting fn");
-            Function {
-                id: item.id,
-                vis: item.vis,
-                attrs: item.attrs.clone(),
-                decl: fd.clone(),
-                name: item.ident,
-                where: item.span,
-                generics: gen.clone(),
-            }
-        }
-
-        fn visit_mod_contents(span: Span, attrs: ~[ast::Attribute], vis:
-                              ast::visibility, id: ast::NodeId, m: &ast::_mod) -> Module {
-            let am = local_data::get(super::ctxtkey, |x| *x.unwrap()).tycx.items;
-            let name = match am.find(&id) {
-                Some(m) => match m {
-                    &ast_map::node_item(ref it, _) => Some(it.ident),
-                    _ => fail!("mod id mapped to non-item in the ast map")
-                },
-                None => None
-            };
-            let mut om = Module::new(name);
-            om.view_items = m.view_items.clone();
-            om.where = span;
-            om.attrs = attrs;
-            om.vis = vis;
-            om.id = id;
-            for i in m.items.iter() {
-                visit_item(*i, &mut om);
-            }
-            om
-        }
-
-        fn visit_item(item: &ast::item, om: &mut Module) {
-            debug!("Visiting item %?", item);
-            match item.node {
-                ast::item_mod(ref m) => {
-                    om.mods.push(visit_mod_contents(item.span, item.attrs.clone(),
-                                                    item.vis, item.id, m));
-                },
-                ast::item_enum(ref ed, ref gen) => om.enums.push(visit_enum_def(item, ed, gen)),
-                ast::item_struct(sd, ref gen) => om.structs.push(visit_struct_def(item, sd, gen)),
-                ast::item_fn(ref fd, ref pur, ref abi, ref gen, _) =>
-                    om.fns.push(visit_fn(item, fd, pur, abi, gen)),
-                ast::item_ty(ref ty, ref gen) => {
-                    let t = Typedef {
-                        ty: ty.clone(),
-                        gen: gen.clone(),
-                        name: item.ident,
-                        id: item.id,
-                        attrs: item.attrs.clone(),
-                        where: item.span,
-                        vis: item.vis,
-                    };
-                    om.typedefs.push(t);
-                },
-                ast::item_static(ref ty, ref mut_, ref exp) => {
-                    let s = Static {
-                        type_: ty.clone(),
-                        mutability: mut_.clone(),
-                        expr: exp.clone(),
-                        id: item.id,
-                        name: item.ident,
-                        attrs: item.attrs.clone(),
-                        where: item.span,
-                        vis: item.vis,
-                    };
-                    om.statics.push(s);
-                },
-                ast::item_trait(ref gen, ref tr, ref met) => {
-                    let t = Trait {
-                        name: item.ident,
-                        methods: met.clone(),
-                        generics: gen.clone(),
-                        parents: tr.clone(),
-                        id: item.id,
-                        attrs: item.attrs.clone(),
-                        where: item.span,
-                        vis: item.vis,
-                    };
-                    om.traits.push(t);
-                },
-                ast::item_impl(ref gen, ref tr, ref ty, ref meths) => {
-                    let i = Impl {
-                        generics: gen.clone(),
-                        trait_: tr.clone(),
-                        for_: ty.clone(),
-                        methods: meths.clone(),
-                        attrs: item.attrs.clone(),
-                        id: item.id,
-                        where: item.span,
-                        vis: item.vis,
-                    };
-                    om.impls.push(i);
-                },
-                _ => (),
-            }
-        }
-
-        self.module = visit_mod_contents(crate.span, crate.attrs.clone(),
-                                         ast::public, ast::CRATE_NODE_ID, &crate.module);
-    }
-}
index 5bfef47902ba790ff6ab6db54359e46c9ec8d2e9..807f62ece7ae558051ab8672efa7aa9fdaa9abb5 100644 (file)
@@ -15,7 +15,7 @@
 use extra::time::precise_time_s;
 use std::io;
 use std::os;
-use std::rand::RngUtil;
+use std::rand::Rng;
 use std::rand;
 use std::str;
 use std::util;
@@ -85,7 +85,7 @@ fn vec_plus() {
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
-        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
+        let rv = vec::from_elem(r.gen_integer_range(0u, i + 1), i);
         if r.gen() {
             v.push_all_move(rv);
         } else {
@@ -101,7 +101,7 @@ fn vec_append() {
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
-        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
+        let rv = vec::from_elem(r.gen_integer_range(0u, i + 1), i);
         if r.gen() {
             v = vec::append(v, rv);
         }
@@ -117,7 +117,7 @@ fn vec_push_all() {
 
     let mut v = ~[];
     for i in range(0u, 1500) {
-        let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
+        let mut rv = vec::from_elem(r.gen_integer_range(0u, i + 1), i);
         if r.gen() {
             v.push_all(rv);
         }
index 6565fc36dd289f9e380633c862e16a151ad3bbca..1a3a188b86f8d5500ed7528feb00b4a24fd58cca 100644 (file)
@@ -1,7 +1,7 @@
 // Perlin noise benchmark from https://gist.github.com/1170424
 
 use std::float;
-use std::rand::{Rng, RngUtil};
+use std::rand::Rng;
 use std::rand;
 
 struct Vec2 {
index e84ed47333b736b11c6db848584cb4e5be948616..3f57f75c078cb217e2b7704e9ac09ac51ba8bd9a 100644 (file)
@@ -15,7 +15,7 @@
 #[no_std];
 extern mod std;
 extern mod zed(name = "std");
-extern mod bar(name = "std", vers = "0.8-pre");
+extern mod bar(name = "std", vers = "0.8");
 
 
 use std::str;