Просмотр исходного кода

chore(dashboard): remove old dashboard

Ed Rooth 11 лет назад
Родитель
Сommit
842dd5cab0
44 измененных файлов с 0 добавлено и 15670 удалено
  1. 0 3
      mod/dashboard/.bowerrc
  2. 0 21
      mod/dashboard/.editorconfig
  3. 0 1
      mod/dashboard/.gitattributes
  4. 0 6
      mod/dashboard/.gitignore
  5. 0 3
      mod/dashboard/.jshintignore
  6. 0 27
      mod/dashboard/.jshintrc
  7. 0 7
      mod/dashboard/.travis.yml
  8. 0 355
      mod/dashboard/Gruntfile.js
  9. 0 202
      mod/dashboard/LICENSE
  10. 0 29
      mod/dashboard/README.md
  11. 0 7
      mod/dashboard/app/images/add.svg
  12. 0 6
      mod/dashboard/app/images/back.svg
  13. 0 7
      mod/dashboard/app/images/delete.svg
  14. 0 46
      mod/dashboard/app/images/logo.svg
  15. 0 43
      mod/dashboard/app/scripts/app.js
  16. 0 16
      mod/dashboard/app/scripts/common/directives/enter.js
  17. 0 19
      mod/dashboard/app/scripts/common/directives/highlight.js
  18. 0 103
      mod/dashboard/app/scripts/common/services/etcd.js
  19. 0 10
      mod/dashboard/app/scripts/common/services/prefix-url.js
  20. 0 156
      mod/dashboard/app/scripts/controllers/browser.js
  21. 0 3
      mod/dashboard/app/scripts/controllers/home.js
  22. 0 9
      mod/dashboard/app/scripts/controllers/root.js
  23. 0 210
      mod/dashboard/app/scripts/controllers/stats.js
  24. 0 3
      mod/dashboard/app/scripts/directives.js
  25. 0 0
      mod/dashboard/app/scripts/ng-time-relative.min.js
  26. 0 36
      mod/dashboard/app/scripts/shims.js
  27. 0 6970
      mod/dashboard/app/scripts/vega.js
  28. 0 6167
      mod/dashboard/app/styles/bootstrap.css
  29. 0 186
      mod/dashboard/app/styles/browser.css
  30. 0 381
      mod/dashboard/app/styles/etcd-widgets.css
  31. 0 56
      mod/dashboard/app/styles/main.css
  32. 0 144
      mod/dashboard/app/styles/stats.css
  33. 0 73
      mod/dashboard/app/views/browser.html
  34. 0 4
      mod/dashboard/app/views/home.html
  35. 0 49
      mod/dashboard/app/views/stats.html
  36. 0 22
      mod/dashboard/bower.json
  37. 0 18
      mod/dashboard/build
  38. 0 63
      mod/dashboard/dashboard.go
  39. 0 54
      mod/dashboard/karma-e2e.conf.js
  40. 0 52
      mod/dashboard/karma.conf.js
  41. 0 36
      mod/dashboard/package.json
  42. 0 35
      mod/dashboard/test/.jshintrc
  43. 0 10
      mod/dashboard/test/runner.html
  44. 0 22
      mod/dashboard/test/spec/controllers/main.js

+ 0 - 3
mod/dashboard/.bowerrc

@@ -1,3 +0,0 @@
-{
-    "directory": "app/bower_components"
-}

+ 0 - 21
mod/dashboard/.editorconfig

@@ -1,21 +0,0 @@
-# EditorConfig helps developers define and maintain consistent
-# coding styles between different editors and IDEs
-# editorconfig.org
-
-root = true
-
-
-[*]
-
-# Change these settings to your own preference
-indent_style = space
-indent_size = 2
-
-# We recommend you to keep these unchanged
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-trim_trailing_whitespace = false

+ 0 - 1
mod/dashboard/.gitattributes

@@ -1 +0,0 @@
-* text=auto

+ 0 - 6
mod/dashboard/.gitignore

@@ -1,6 +0,0 @@
-node_modules
-dist
-.tmp
-.sass-cache
-app/bower_components
-/go-bindata

+ 0 - 3
mod/dashboard/.jshintignore

@@ -1,3 +0,0 @@
-app/scripts/vega.js
-app/scripts/moment.min.js
-app/scripts/ng-time-relative.min.js

+ 0 - 27
mod/dashboard/.jshintrc

@@ -1,27 +0,0 @@
-{
-  "node": true,
-  "browser": true,
-  "esnext": true,
-  "bitwise": true,
-  "camelcase": true,
-  "curly": true,
-  "eqeqeq": true,
-  "immed": true,
-  "indent": 2,
-  "latedef": true,
-  "newcap": true,
-  "noarg": true,
-  "quotmark": "single",
-  "regexp": true,
-  "undef": true,
-  "unused": false,
-  "strict": true,
-  "trailing": true,
-  "smarttabs": true,
-  "globals": {
-    "angular": false,
-    "$": false,
-    "vg": false,
-    "moment": false
-  }
-}

+ 0 - 7
mod/dashboard/.travis.yml

@@ -1,7 +0,0 @@
-language: node_js
-node_js:
-  - '0.8'
-  - '0.10'
-before_script:
-  - 'npm install -g bower grunt-cli'
-  - 'bower install'

+ 0 - 355
mod/dashboard/Gruntfile.js

@@ -1,355 +0,0 @@
-// Generated on 2013-10-07 using generator-webapp 0.4.3
-'use strict';
-
-// # Globbing
-// for performance reasons we're only matching one level down:
-// 'test/spec/{,*/}*.js'
-// use this if you want to recursively match all subfolders:
-// 'test/spec/**/*.js'
-
-module.exports = function (grunt) {
-    // show elapsed time at the end
-    require('time-grunt')(grunt);
-    // load all grunt tasks
-    require('load-grunt-tasks')(grunt);
-
-    grunt.initConfig({
-        // configurable paths
-        uglify: {
-          options: {
-            mangle: false
-          },
-        },
-        yeoman: {
-            app: 'app',
-            dist: 'dist'
-        },
-        watch: {
-            compass: {
-                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
-                tasks: ['compass:server', 'autoprefixer']
-            },
-            styles: {
-                files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
-                tasks: ['copy:styles', 'autoprefixer']
-            },
-            livereload: {
-                options: {
-                    livereload: '<%= connect.options.livereload %>'
-                },
-                files: [
-                    '<%= yeoman.app %>/*.html',
-                    '.tmp/styles/{,*/}*.css',
-                    '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
-                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
-                ]
-            }
-        },
-        connect: {
-            options: {
-                port: 9000,
-                livereload: 35729,
-                // change this to '0.0.0.0' to access the server from outside
-                hostname: 'localhost'
-            },
-            livereload: {
-                options: {
-                    open: true,
-                    base: [
-                        '.tmp',
-                        '<%= yeoman.app %>'
-                    ]
-                }
-            },
-            test: {
-                options: {
-                    base: [
-                        '.tmp',
-                        'test',
-                        '<%= yeoman.app %>'
-                    ]
-                }
-            },
-            dist: {
-                options: {
-                    open: true,
-                    base: '<%= yeoman.dist %>'
-                }
-            }
-        },
-        clean: {
-            dist: {
-                files: [{
-                    dot: true,
-                    src: [
-                        '.tmp',
-                        '<%= yeoman.dist %>/*',
-                        '!<%= yeoman.dist %>/.git*'
-                    ]
-                }]
-            },
-            server: '.tmp'
-        },
-        jshint: {
-            options: {
-                jshintrc: '.jshintrc'
-            },
-            all: [
-                '<%= yeoman.app %>/scripts/{,*/}*.js',
-                '!<%= yeoman.app %>/scripts/vendor/*',
-            ]
-        },
-        mocha: {
-            all: {
-                options: {
-                    run: true,
-                    urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html']
-                }
-            }
-        },
-        compass: {
-            options: {
-                sassDir: '<%= yeoman.app %>/styles',
-                cssDir: '.tmp/styles',
-                generatedImagesDir: '.tmp/images/generated',
-                imagesDir: '<%= yeoman.app %>/images',
-                javascriptsDir: '<%= yeoman.app %>/scripts',
-                fontsDir: '<%= yeoman.app %>/styles/fonts',
-                importPath: '<%= yeoman.app %>/bower_components',
-                httpImagesPath: '/images',
-                httpGeneratedImagesPath: '/images/generated',
-                httpFontsPath: '/styles/fonts',
-                relativeAssets: false,
-                assetCacheBuster: false
-            },
-            dist: {
-                options: {
-                    generatedImagesDir: '<%= yeoman.dist %>/images/generated'
-                }
-            },
-            server: {
-                options: {
-                    debugInfo: true
-                }
-            }
-        },
-        autoprefixer: {
-            options: {
-                browsers: ['last 1 version']
-            },
-            dist: {
-                files: [{
-                    expand: true,
-                    cwd: '.tmp/styles/',
-                    src: '{,*/}*.css',
-                    dest: '.tmp/styles/'
-                }]
-            }
-        },
-        // not used since Uglify task does concat,
-        // but still available if needed
-        /*concat: {
-            dist: {}
-        },*/
-        requirejs: {
-            dist: {
-                // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
-                options: {
-                    // `name` and `out` is set by grunt-usemin
-                    baseUrl: '<%= yeoman.app %>/scripts',
-                    optimize: 'none',
-                    // TODO: Figure out how to make sourcemaps work with grunt-usemin
-                    // https://github.com/yeoman/grunt-usemin/issues/30
-                    //generateSourceMaps: true,
-                    // required to support SourceMaps
-                    // http://requirejs.org/docs/errors.html#sourcemapcomments
-                    preserveLicenseComments: false,
-                    useStrict: true,
-                    wrap: true
-                    //uglify2: {} // https://github.com/mishoo/UglifyJS2
-                }
-            }
-        },
-        useminPrepare: {
-            options: {
-                dest: '<%= yeoman.dist %>'
-            },
-            html: ['<%= yeoman.app %>/index.html']
-        },
-        usemin: {
-            options: {
-                dirs: ['<%= yeoman.dist %>']
-            },
-            html: ['<%= yeoman.dist %>/{,*/}*.html'],
-            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']
-        },
-        imagemin: {
-            dist: {
-                files: [{
-                    expand: true,
-                    cwd: '<%= yeoman.app %>/images',
-                    src: '{,*/}*.{png,jpg,jpeg}',
-                    dest: '<%= yeoman.dist %>/images'
-                }]
-            }
-        },
-        svgmin: {
-            dist: {
-                files: [{
-                    expand: true,
-                    cwd: '<%= yeoman.app %>/images',
-                    src: '{,*/}*.svg',
-                    dest: '<%= yeoman.dist %>/images'
-                }]
-            }
-        },
-        cssmin: {
-            // This task is pre-configured if you do not wish to use Usemin
-            // blocks for your CSS. By default, the Usemin block from your
-            // `index.html` will take care of minification, e.g.
-            //
-            //     <!-- build:css({.tmp,app}) styles/main.css -->
-            //
-            // dist: {
-            //     files: {
-            //         '<%= yeoman.dist %>/styles/main.css': [
-            //             '.tmp/styles/{,*/}*.css',
-            //             '<%= yeoman.app %>/styles/{,*/}*.css'
-            //         ]
-            //     }
-            // }
-        },
-        htmlmin: {
-            dist: {
-                options: {
-                    /*removeCommentsFromCDATA: true,
-                    // https://github.com/yeoman/grunt-usemin/issues/44
-                    //collapseWhitespace: true,
-                    collapseBooleanAttributes: true,
-                    removeAttributeQuotes: true,
-                    removeRedundantAttributes: true,
-                    useShortDoctype: true,
-                    removeEmptyAttributes: true,
-                    removeOptionalTags: true*/
-                },
-                files: [{
-                    expand: true,
-                    cwd: '<%= yeoman.app %>',
-                    src: '*.html',
-                    dest: '<%= yeoman.dist %>'
-                }]
-            }
-        },
-
-        ngmin: {
-          dist: {
-            src: '.tmp/concat/scripts/app.js',
-            dest: '.tmp/concat/scripts/app.js'
-          }
-        },
-
-        // Put files not handled in other tasks here
-        copy: {
-            dist: {
-                files: [{
-                    expand: true,
-                    dot: true,
-                    cwd: '<%= yeoman.app %>',
-                    dest: '<%= yeoman.dist %>',
-                    src: [
-                        '*.{ico,png,txt}',
-                        '.htaccess',
-                        'images/{,*/}*.{webp,gif,svg}',
-                        'styles/fonts/{,*/}*.*',
-                        'views/*.*',
-                        //'index.html',
-                        'bower_components/sass-bootstrap/fonts/*.*'
-                    ]
-                }]
-            },
-            styles: {
-                expand: true,
-                dot: true,
-                cwd: '<%= yeoman.app %>/styles',
-                dest: '.tmp/styles/',
-                src: '{,*/}*.css'
-            }
-        },
-        modernizr: {
-            devFile: '<%= yeoman.app %>/bower_components/modernizr/modernizr.js',
-            outputFile: '<%= yeoman.dist %>/bower_components/modernizr/modernizr.js',
-            files: [
-                '<%= yeoman.dist %>/scripts/{,*/}*.js',
-                '<%= yeoman.dist %>/styles/{,*/}*.css',
-                '!<%= yeoman.dist %>/scripts/vendor/*'
-            ],
-            uglify: true
-        },
-        concurrent: {
-            server: [
-                'compass',
-                'copy:styles'
-            ],
-            test: [
-                'copy:styles'
-            ],
-            dist: [
-                //'compass',
-                'copy:styles',
-                'imagemin',
-                'svgmin',
-                'htmlmin'
-            ]
-        },
-        bower: {
-            options: {
-                exclude: ['modernizr']
-            },
-            all: {
-                rjsConfig: '<%= yeoman.app %>/scripts/main.js'
-            }
-        }
-    });
-
-    grunt.registerTask('server', function (target) {
-        if (target === 'dist') {
-            return grunt.task.run(['build', 'connect:dist:keepalive']);
-        }
-
-        grunt.task.run([
-            'clean:server',
-            'concurrent:server',
-            'autoprefixer',
-            'connect:livereload',
-            'watch'
-        ]);
-    });
-
-    grunt.registerTask('test', [
-        'clean:server',
-        'concurrent:test',
-        'autoprefixer',
-        'connect:test',
-        'mocha'
-    ]);
-
-    grunt.registerTask('build', [
-        'clean:dist',
-        'jshint',
-        'useminPrepare',
-        'concurrent:dist',
-        'autoprefixer',
-        'concat',
-        'cssmin',
-        'ngmin',
-        'usemin',
-        'uglify',
-        'copy:dist'
-    ]);
-
-    grunt.registerTask('default', [
-        'jshint',
-        'test',
-        'build'
-    ]);
-};

+ 0 - 202
mod/dashboard/LICENSE

@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 29
mod/dashboard/README.md

@@ -1,29 +0,0 @@
-# etcd Dashboard
-
-## Developing
-
-If you'd like to contribute to the etcd dashboard mod, follow these instructions. For contributing to the rest of etcd, see the contributing document in the root of the repository.
-
-### Install yeoman
-
-http://yeoman.io/
-
-### Install NPM locally
-
-```
-npm install
-```
-
-### Install Bower Components
-
-```
-bower install
-```
-
-### View in Browser
-
-run `export ETCD_DASHBOARD_DIR=/absolute/path/to/coreos/etcd/mod/dashboard/app`  
-
-Run etcd like you normally would and afterward browse to:
-
-http://localhost:4001/mod/dashboard/

+ 0 - 7
mod/dashboard/app/images/add.svg

@@ -1,7 +0,0 @@
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-  preserveAspectRatio="xMinYMin" viewBox="0 0 72.556 61" enable-background="new 0 0 72.556 61" xml:space="preserve">
-  <path d="M34.521,8v11.088v23v10.737c0,2.209,1.791,4,4,4c2.209,0,4-1.791,4-4V42.067V19.109V8c0-2.209-1.791-4-4-4
-  C36.312,4,34.521,5.791,34.521,8z"/>
-  <path d="M16.109,34.412h11.088h23h10.737c2.209,0,4-1.791,4-4c0-2.209-1.791-4-4-4H50.175H27.217H16.109c-2.209,0-4,1.791-4,4
-  C12.109,32.621,13.9,34.412,16.109,34.412z"/>
-</svg>

+ 0 - 6
mod/dashboard/app/images/back.svg

@@ -1,6 +0,0 @@
-<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-  preserveAspectRatio="xMinYMin" viewBox="0 0 73.356 61" enable-background="new 0 0 73.356 61" xml:space="preserve">
-  <path d="M5.27,33.226l22.428,22.428c1.562,1.562,4.095,1.562,5.657,0c1.562-1.562,1.562-4.095,0-5.657L17.77,34.413h48.514
-  c2.209,0,4-1.791,4-4s-1.791-4-4-4H17.749l15.604-15.582c1.563-1.561,1.565-4.094,0.004-5.657C32.576,4.391,31.552,4,30.527,4
-  c-1.023,0-2.046,0.39-2.827,1.169L5.272,27.567c-0.751,0.75-1.173,1.768-1.173,2.829C4.098,31.458,4.52,32.476,5.27,33.226z"/>
-</svg>

+ 0 - 7
mod/dashboard/app/images/delete.svg

@@ -1,7 +0,0 @@
-<svg version="1.1" fill="#f00" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
-  x="0px" y="0px" preserveAspectRatio="xMinYMin" viewBox="0 0 76.143 61" enable-background="new 0 0 76.143 61" xml:space="preserve">
-  <path d="M49.41,13.505l-6.035,6.035L27.112,35.803l-6.035,6.035c-1.562,1.562-1.562,4.095,0,5.657c1.562,1.562,4.095,1.562,5.657,0
-  l6.05-6.05l16.234-16.234l6.05-6.05c1.562-1.562,1.562-4.095,0-5.657C53.505,11.943,50.972,11.943,49.41,13.505z"/>
-  <path d="M21.077,19.162l6.035,6.035L43.375,41.46l6.035,6.035c1.562,1.562,4.095,1.562,5.657,0c1.562-1.562,1.562-4.095,0-5.657
-  l-6.05-6.05L32.783,19.555l-6.05-6.05c-1.562-1.562-4.095-1.562-5.657,0C19.515,15.067,19.515,17.6,21.077,19.162z"/>
-</svg>

+ 0 - 46
mod/dashboard/app/images/logo.svg

@@ -1,46 +0,0 @@
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-     preserveAspectRatio="xMinYMin" viewBox="0 0 792 306" enable-background="new 0 0 792 306" xml:space="preserve">
-  <g>
-    <g>
-      <path fill="#53A3DA" d="M136.168,45.527C76.898,45.527,28.689,93.739,28.689,153c0,59.265,48.209,107.474,107.479,107.474
-          c59.252,0,107.465-48.209,107.465-107.474C243.633,93.739,195.42,45.527,136.168,45.527z"/>
-      <path fill="#F1606D" d="M136.168,55.389c-17.283,0-31.941,27.645-37.235,66.069c-0.169,1.236-0.333,2.487-0.478,3.746
-          c-0.723,6.047-1.213,12.335-1.458,18.808c-0.117,2.962-0.175,5.956-0.175,8.988c0,3.029,0.058,6.029,0.175,8.985
-          c0.245,6.472,0.735,12.764,1.458,18.811c8.104,1.049,16.769,1.761,25.807,2.099c3.907,0.146,7.872,0.233,11.907,0.233
-          c4.023,0,8-0.088,11.895-0.233c9.049-0.338,17.708-1.05,25.819-2.099c0.892-0.114,1.77-0.239,2.659-0.368
-          c33.754-4.74,57.235-15.232,57.235-27.428C233.776,99.088,190.071,55.389,136.168,55.389z"/>
-      <path fill="#FFFFFF" d="M176.541,125.569c-0.979-1.428-2.029-2.796-3.148-4.11c-8.956-10.557-22.297-17.265-37.224-17.265
-          c-4.839,0-9.148,7.407-11.907,18.909c-1.096,4.586-1.947,9.819-2.495,15.498c-0.432,4.551-0.665,9.391-0.665,14.399
-          s0.233,9.849,0.665,14.396c4.554,0.432,9.387,0.664,14.402,0.664c5.009,0,9.842-0.232,14.396-0.664
-          c10.011-0.95,18.653-2.875,24.775-5.411c6.046-2.501,9.624-5.615,9.624-8.985C184.963,142.832,181.858,133.388,176.541,125.569z"
-          />
-    </g>
-    <g>
-      <path fill="#231F20" d="M344.891,100.053c12.585,0,22.816,6.138,29.262,13.062l-10.064,11.326
-          c-5.353-5.192-11.175-8.495-19.041-8.495c-16.839,0-28.953,14.16-28.953,37.291c0,23.448,11.169,37.608,28.32,37.608
-          c9.128,0,15.895-3.775,21.717-10.228l10.067,11.169c-8.335,9.598-19.038,14.95-32.099,14.95c-26.119,0-46.731-18.88-46.731-53.025
-          C297.37,120.036,318.454,100.053,344.891,100.053z"/>
-      <path fill="#231F20" d="M416.961,125.701c19.352,0,36.822,14.793,36.822,40.597c0,25.647-17.471,40.439-36.822,40.439
-          c-19.197,0-36.66-14.792-36.66-40.439C380.301,140.494,397.764,125.701,416.961,125.701z M416.961,191.945
-          c11.33,0,18.25-10.228,18.25-25.647c0-15.577-6.92-25.804-18.25-25.804s-18.094,10.227-18.094,25.804
-          C398.867,181.717,405.631,191.945,416.961,191.945z"/>
-      <path fill="#231F20" d="M459.771,127.589h14.943l1.26,13.688h0.629c5.506-10.07,13.691-15.577,21.871-15.577
-          c3.938,0,6.455,0.472,8.811,1.574l-3.148,15.734c-2.67-0.784-4.717-1.257-8.018-1.257c-6.139,0-13.539,4.245-18.256,15.893v47.203
-          h-18.092V127.589z"/>
-      <path fill="#231F20" d="M541.121,125.701c20.928,0,31.941,15.107,31.941,36.667c0,3.458-0.314,6.604-0.787,8.495h-49.09
-          c1.57,14.003,10.379,21.869,22.811,21.869c6.613,0,12.273-2.041,17.941-5.662l6.135,11.326
-          c-7.395,4.878-16.676,8.341-26.432,8.341c-21.404,0-38.08-14.95-38.08-40.439C505.561,141.12,523.023,125.701,541.121,125.701z
-           M557.326,159.376c0-12.277-5.189-19.671-15.732-19.671c-9.125,0-16.996,6.768-18.57,19.671H557.326z"/>
-      <path fill="#F1606D" d="M600.602,152.607c0-32.729,17.785-53.344,42.799-53.344c24.863,0,42.641,20.615,42.641,53.344
-          c0,32.889-17.777,54.13-42.641,54.13C618.387,206.737,600.602,185.496,600.602,152.607z M678.49,152.607
-          c0-28.639-14.158-46.731-35.09-46.731c-21.084,0-35.248,18.093-35.248,46.731c0,28.796,14.164,47.521,35.248,47.521
-          C664.332,200.128,678.49,181.403,678.49,152.607z"/>
-      <path fill="#53A4D9" d="M699.738,186.125c7.557,8.495,18.412,14.003,30.529,14.003c15.732,0,25.807-8.499,25.807-20.767
-          c0-12.904-8.494-17.154-18.723-21.717l-15.736-7.082c-8.969-3.936-20.934-10.385-20.934-25.808
-          c0-14.947,12.904-25.492,30.059-25.492c12.588,0,22.658,5.665,28.949,12.435l-4.244,4.878c-5.982-6.452-14.32-10.7-24.705-10.7
-          c-13.691,0-22.816,7.239-22.816,18.565c0,11.962,10.385,16.521,17.936,19.985l15.738,6.921
-          c11.486,5.195,21.713,11.647,21.713,27.539s-13.061,27.851-33.201,27.851c-15.107,0-26.75-6.451-34.932-15.576L699.738,186.125z"
-          />
-    </g>
-  </g>
-</svg>

+ 0 - 43
mod/dashboard/app/scripts/app.js

@@ -1,43 +0,0 @@
-'use strict';
-
-var app = angular.module('etcdControlPanel', [
-  'ngRoute',
-  'ngResource',
-  'etcd',
-  'etcdDirectives',
-  'timeRelative',
-  'underscore',
-  'jquery',
-  'moment',
-  'vg'
-]);
-
-app.constant('urlPrefix', '/mod/dashboard');
-app.constant('keyPrefix', '/v2/keys/');
-
-app.config(function($routeProvider, $locationProvider, urlPrefix) {
-
-  function prefixUrl(url) {
-    return urlPrefix + url;
-  }
-
-  $locationProvider.html5Mode(true);
-
-  $routeProvider
-    .when(prefixUrl('/'), {
-      controller: 'HomeCtrl',
-      templateUrl: prefixUrl('/views/home.html')
-    })
-    .when(prefixUrl('/stats'), {
-      controller: 'StatsCtrl',
-      templateUrl: prefixUrl('/views/stats.html')
-    })
-    .when(prefixUrl('/browser'), {
-      controller: 'BrowserCtrl',
-      templateUrl: prefixUrl('/views/browser.html')
-    })
-    .otherwise({
-      templateUrl: prefixUrl('/404.html')
-    });
-
-});

+ 0 - 16
mod/dashboard/app/scripts/common/directives/enter.js

@@ -1,16 +0,0 @@
-'use strict';
-
-angular.module('etcdControlPanel')
-.directive('ngEnter', function() {
-  return function(scope, element, attrs) {
-    element.bind('keydown keypress', function(event) {
-      if(event.which === 13) {
-        scope.$apply(function(){
-          scope.$eval(attrs.ngEnter);
-        });
-
-        event.preventDefault();
-      }
-    });
-  };
-});

+ 0 - 19
mod/dashboard/app/scripts/common/directives/highlight.js

@@ -1,19 +0,0 @@
-'use strict';
-
-angular.module('etcdControlPanel')
-.directive('highlight', function(keyPrefix) {
-  return {
-    restrict: 'E',
-    scope: {
-      highlightBase: '=',
-      highlightCurrent: '='
-    },
-    link: function(scope, element, attrs) {
-      var base = _.str.strRight(scope.highlightBase, keyPrefix),
-          current = _.str.trim(scope.highlightCurrent, '/');
-      if (base === current) {
-        element.parent().parent().addClass('etcd-selected');
-      }
-    }
-  };
-});

+ 0 - 103
mod/dashboard/app/scripts/common/services/etcd.js

@@ -1,103 +0,0 @@
-'use strict';
-
-angular.module('etcd', [])
-
-.factory('EtcdV2', ['$http', '$q', function($http, $q) {
-  var keyPrefix = '/v2/keys/'
-  var statsPrefix = '/v2/stats/'
-  var baseURL = '/v2/'
-  var leaderURL = ''
-
-  delete $http.defaults.headers.common['X-Requested-With'];
-
-  function cleanupPath(path) {
-    var parts = path.split('/');
-    if (parts.length === 0) {
-      return '';
-    }
-    parts = parts.filter(function(v){return v!=='';});
-    parts = parts.join('/');
-    return parts
-  }
-
-  function newKey(keyName) {
-    var self = {};
-    self.name = cleanupPath(keyName);
-
-    self.getParent = function() {
-      var parts = self.name.split('/');
-      if (parts.length === 0) {
-        return newKey('');
-      }
-      parts.pop();
-      return newKey(parts.join('/'));
-    };
-
-    self.path = function() {
-      var path = '/' + cleanupPath(keyPrefix + self.name);
-      if (path === keyPrefix.substring(0, keyPrefix.length - 1)) {
-        return keyPrefix
-      }
-      return path
-    };
-
-    self.get = function() {
-      return $http.get(self.path());
-    };
-
-    self.set = function(keyValue) {
-      return getLeader().then(function(leader) {
-        return $http({
-          url: leader + self.path(),
-          data: $.param({value: keyValue}),
-          method: 'PUT',
-          headers: {'Content-Type': 'application/x-www-form-urlencoded'}
-        });
-      });
-    };
-
-    self.deleteKey = function(keyValue) {
-      return getLeader().then(function(leader) {
-        return $http({
-          url: leader + self.path(),
-          method: 'DELETE',
-          headers: {'Content-Type': 'application/x-www-form-urlencoded'}
-        });
-      });
-    };
-
-    return self;
-  }
-
-  function newStat(statName) {
-    var self = {};
-    self.name = cleanupPath(statName);
-
-    self.path = function() {
-      return '/' + cleanupPath(statsPrefix + self.name);
-    };
-
-    self.get = function() {
-      return $http.get(self.path());
-    };
-
-    return self
-  }
-
-  function getLeader() {
-    return newStat('leader').get().then(function(response) {
-      return newKey('/_etcd/machines/' + response.data.leader).get().then(function(response) {
-        // TODO: do something better here p.s. I hate javascript
-        var data = decodeURIComponent(response.data.node.value);
-        data = data.replace(/&/g, "\",\"").replace(/=/g,"\":\"");
-        data = JSON.parse('{"' + data + '"}');
-        return data.etcd;
-      });
-    });
-  }
-
-  return {
-    getStat: newStat,
-    getKey: newKey,
-  }
-}]);

+ 0 - 10
mod/dashboard/app/scripts/common/services/prefix-url.js

@@ -1,10 +0,0 @@
-'use strict';
-
-angular.module('etcdControlPanel')
-.factory('prefixUrl', function(urlPrefix) {
-
-  return function(url) {
-    return urlPrefix + url;
-  }
-
-});

+ 0 - 156
mod/dashboard/app/scripts/controllers/browser.js

@@ -1,156 +0,0 @@
-'use strict';
-
-angular.module('etcdControlPanel')
-.controller('BrowserCtrl', function ($scope, $window, EtcdV2, keyPrefix, $, _, moment) {
-  $scope.save = 'etcd-save-hide';
-  $scope.preview = 'etcd-preview-hide';
-  $scope.enableBack = true;
-  $scope.writingNew = false;
-  $scope.key = null;
-  $scope.list = [];
-
-  // etcdPath is the path to the key that is currenly being looked at.
-  $scope.etcdPath = keyPrefix;
-  $scope.inputPath = keyPrefix;
-
-  $scope.resetInputPath = function() {
-    $scope.inputPath = $scope.etcdPath;
-  };
-
-  $scope.setActiveKey = function(key) {
-    $scope.etcdPath = keyPrefix + _.str.trim(key, '/');
-    $scope.resetInputPath();
-  };
-
-  $scope.stripPrefix = function(path) {
-    return _.str.strRight(path, keyPrefix);
-  };
-
-  $scope.onEnter = function() {
-    var path = $scope.stripPrefix($scope.inputPath);
-    if (path !== '') {
-      $scope.setActiveKey(path);
-    }
-  };
-
-  $scope.updateCurrentKey = function() {
-    function etcdPathKey() {
-      return pathKey($scope.etcdPath);
-    }
-
-    function pathKey(path) {
-      var parts = path.split(keyPrefix);
-      if (parts.length === 1) {
-        return '';
-      }
-      return parts[1];
-    }
-    // Notify everyone of the update
-    localStorage.setItem('etcdPath', $scope.etcdPath);
-    $scope.enableBack = true;
-    //disable back button if at root (/v2/keys/)
-    if ($scope.etcdPath === keyPrefix) {
-      $scope.enableBack = false;
-    }
-    $scope.key = EtcdV2.getKey(etcdPathKey($scope.etcdPath));
-  };
-
-  $scope.$watch('etcdPath', $scope.updateCurrentKey);
-
-  $scope.$watch('key', function() {
-    if ($scope.writingNew === true) {
-      return;
-    }
-    $scope.key.get().success(function (data, status, headers, config) {
-      //hide any errors
-      $('#etcd-browse-error').hide();
-      // Looking at a directory if we got an array
-      if (data.node.dir === true) {
-        $scope.list = data.node.nodes;
-        $scope.preview = 'etcd-preview-hide';
-      } else {
-        $scope.singleValue = data.node.value;
-        $scope.preview = 'etcd-preview-reveal';
-        $scope.key.getParent().get().success(function(data) {
-          $scope.list = data.node.nodes;
-        });
-      }
-      $scope.previewMessage = 'No key selected.';
-    }).error(function (data, status, headers, config) {
-      $scope.previewMessage = 'Key does not exist.';
-      $scope.showBrowseError(data.message);
-    });
-  });
-
-  //back button click
-  $scope.back = function() {
-    $scope.etcdPath = $scope.key.getParent().path();
-    $scope.resetInputPath();
-    $scope.preview = 'etcd-preview-hide';
-    $scope.writingNew = false;
-  };
-
-  $scope.showSave = function() {
-    $scope.save = 'etcd-save-reveal';
-  };
-
-  $scope.saveData = function() {
-    $scope.setActiveKey($scope.stripPrefix($scope.inputPath));
-    $scope.updateCurrentKey();
-    // TODO: fixup etcd to allow for empty values
-    $scope.key.set($scope.singleValue || ' ').then(function(response) {
-      $scope.save = 'etcd-save-hide';
-      $scope.preview = 'etcd-preview-hide';
-      $scope.back();
-      $scope.writingNew = false;
-    }, function (response) {
-      $scope.showSaveError(response.message);
-    });
-  };
-
-  $scope.deleteKey = function(key) {
-    $scope.setActiveKey(key);
-    $scope.updateCurrentKey();
-    $scope.key.deleteKey().then(function(response) {
-      //TODO: remove loader
-      $scope.save = 'etcd-save-hide';
-      $scope.preview = 'etcd-preview-hide';
-      $scope.back();
-    }, function (response) {
-      //TODO: remove loader
-      //show errors
-      $scope.showBrowseError('Could not delete the key');
-    });
-  };
-
-  $scope.add = function() {
-    $scope.save = 'etcd-save-reveal';
-    $scope.preview = 'etcd-preview-reveal';
-    $scope.singleValue = '';
-    $('.etcd-browser-path').find('input').focus();
-    $scope.writingNew = true;
-  };
-
-  $scope.showBrowseError = function(message) {
-    $('#etcd-browse-error').find('.etcd-popover-content').text('Error: ' + message);
-    $('#etcd-browse-error').addClass('etcd-popover-right').show();
-  };
-
-  $scope.showSaveError = function(message) {
-    $('#etcd-save-error').find('.etcd-popover-content').text('Error: ' + message);
-    $('#etcd-save-error').addClass('etcd-popover-left').show();
-  };
-
-  $scope.getHeight = function() {
-    return $($window).height();
-  };
-
-  //$scope.$watch($scope.getHeight, function() {
-    ////$('.etcd-container.etcd-browser etcd-body').css('height', $scope.getHeight()-45);
-  //});
-
-  $window.onresize = function(){
-    $scope.$apply();
-  };
-
-});

+ 0 - 3
mod/dashboard/app/scripts/controllers/home.js

@@ -1,3 +0,0 @@
-angular.module('etcdControlPanel')
-.controller('HomeCtrl', function($scope) {
-});

+ 0 - 9
mod/dashboard/app/scripts/controllers/root.js

@@ -1,9 +0,0 @@
-'use strict';
-
-angular.module('etcdControlPanel')
-.controller('RootCtrl', function($rootScope, prefixUrl) {
-
-  // Expose prefixUrl() function to all.
-  $rootScope.prefixUrl = prefixUrl;
-
-});

+ 0 - 210
mod/dashboard/app/scripts/controllers/stats.js

@@ -1,210 +0,0 @@
-'use strict';
-
-
-angular.module('etcdControlPanel')
-.controller('StatsCtrl', function ($scope, $rootScope, $interval, EtcdV2, statsVega, vg) {
-  $scope.graphContainer = '#latency';
-  $scope.graphVisibility = 'etcd-graph-show';
-  $scope.tableVisibility = 'etcd-table-hide';
-
-  //make requests
-  function readStats() {
-    EtcdV2.getStat('leader').get().success(function(data) {
-      $scope.leaderStats = data;
-      $scope.leaderName = data.leader;
-      $scope.peers = [];
-      //hardcode leader stats
-      $scope.peers.push({
-        latency: {
-          average: 0,
-          current: 0,
-          minimum: 0,
-          maximum: 0,
-          standardDeviation: 0
-        },
-        name: data.leader
-      });
-      $.each(data.followers, function(index, value) {
-        value.name = index;
-        $scope.peers.push(value);
-      });
-      //sort array so peers don't jump when output
-      $scope.peers.sort(function(a, b){
-          if(a.name < b.name) {
-            return -1;
-          }
-          if(a.name > b.name) {
-            return 1;
-          }
-          return 0;
-        });
-      drawGraph();
-    });
-  }
-
-  function drawGraph () {
-    //hardcoded padding from chart json
-    var vertPadding = 30;
-    var horzPadding = 15;
-    //fetch width and height of graph area
-    var width = $($scope.graphContainer).width() - horzPadding;
-    var height = $($scope.graphContainer).height() - vertPadding;
-
-    // parse a spec and create a visualization view
-    function parse(spec) {
-      vg.parse.spec(spec, function(chart) {
-        chart({
-          el: $scope.graphContainer,
-          data: {
-            'stats': $scope.peers
-          }
-        }).width(width).height(height).update();
-      });
-    }
-    parse(statsVega);
-  }
-
-  $scope.showTable = function() {
-    $scope.tableVisibility = 'etcd-table-reveal';
-  };
-
-  $scope.showGraph = function() {
-    $scope.tableVisibility = 'etcd-table-hide';
-  };
-
-  $scope.getHeight = function() {
-    return $(window).height();
-  };
-  $scope.getWidth = function() {
-    return $(window).width();
-  };
-  //$scope.$watch($scope.getHeight, function() {
-    ////$('.etcd-container.etcd-stats .etcd-body').css('height', $scope.getHeight()-5);
-    //readStats();
-  //});
-  $scope.$watch($scope.getWidth, function() {
-    readStats();
-  });
-  window.onresize = function(){
-    $scope.$apply();
-  };
-
-  $scope.pollPromise = null;
-
-  $scope.startPolling = function() {
-    // Update the graphs live
-    if ($scope.pollPromise) {
-      return;
-    }
-    $scope.pollPromise = $interval(function() {
-      readStats();
-    }, 500);
-  };
-
-  $scope.stopPolling = function() {
-    $interval.cancel($scope.pollPromise);
-    $scope.pollPromise = null;
-  };
-
-  // Stop polling when navigating away from a view with this controller.
-  $rootScope.$on('$routeChangeStart', function () {
-    $scope.stopPolling();
-  });
-
-  $scope.startPolling();
-
-})
-
-
-/* statsVega returns the vega configuration for the stats dashboard */
-.factory('statsVega', function () {
-  return {
-    'padding': {'top': 10, 'left': 5, 'bottom': 40, 'right': 10},
-    'data': [
-      {
-        'name': 'stats'
-      },
-      {
-        'name': 'thresholds',
-        'values': [50, 100]
-      }
-    ],
-    'scales': [
-      {
-        'name': 'y',
-        'type': 'ordinal',
-        'range': 'height',
-        'domain': {'data': 'stats', 'field': 'index'}
-      },
-      {
-        'name': 'x',
-        'range': 'width',
-        'domainMin': 0,
-        'domainMax': 100,
-        'nice': true,
-        'zero': true,
-        'domain': {'data': 'stats', 'field': 'data.latency.current'}
-      },
-      {
-        'name': 'color',
-        'type': 'linear',
-        'domain': [10, 50, 100, 1000000000],
-        'range': ['#00DB24', '#FFC000', '#c40022', '#c40022']
-      }
-    ],
-    'axes': [
-      {
-        'type': 'x',
-        'scale': 'x',
-        'ticks': 6,
-        'name': 'Latency (ms)'
-      },
-      {
-        'type': 'y',
-        'scale': 'y',
-        'properties': {
-          'ticks': {
-            'stroke': {'value': 'transparent'}
-          },
-          'majorTicks': {
-            'stroke': {'value': 'transparent'}
-          },
-          'labels': {
-            'fill': {'value': 'transparent'}
-          },
-          'axis': {
-            'stroke': {'value': '#333'},
-            'strokeWidth': {'value': 1}
-          }
-        }
-      }
-    ],
-    'marks': [
-      {
-        'type': 'rect',
-        'from': {'data': 'stats'},
-        'properties': {
-          'enter': {
-            'x': {'scale': 'x', 'value': 0},
-            'x2': {'scale': 'x', 'field': 'data.latency.current'},
-            'y': {'scale': 'y', 'field': 'index', 'offset': -1},
-            'height': {'value': 3},
-            'fill': {'scale':'color', 'field':'data.latency.current'}
-          }
-        }
-      },
-      {
-          'type': 'symbol',
-          'from': {'data': 'stats'},
-          'properties': {
-            'enter': {
-              'x': {'scale': 'x', 'field': 'data.latency.current'},
-              'y': {'scale': 'y', 'field': 'index'},
-              'size': {'value': 50},
-              'fill': {'value': '#000'}
-            }
-          }
-        }
-      ]
-    };
-});

+ 0 - 3
mod/dashboard/app/scripts/directives.js

@@ -1,3 +0,0 @@
-'use strict';
-
-angular.module('etcdDirectives', []);

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
mod/dashboard/app/scripts/ng-time-relative.min.js


+ 0 - 36
mod/dashboard/app/scripts/shims.js

@@ -1,36 +0,0 @@
-'use strict';
-
-angular.module('underscore', []).factory('_', function($window) {
-  return $window._;
-});
-
-angular.module('jquery', []).factory('$', function($window) {
-  return $window.$;
-});
-
-angular.module('vg', []).factory('vg', function($window) {
-  return $window.vg;
-});
-
-angular.module('moment', []).factory('moment', function($window) {
-
-  $window.moment.lang('en', {
-    relativeTime : {
-      future: 'Expires in %s',
-      past:   'Expired %s ago',
-      s:  'seconds',
-      m:  'a minute',
-      mm: '%d minutes',
-      h:  'an hour',
-      hh: '%d hours',
-      d:  'a day',
-      dd: '%d days',
-      M:  'a month',
-      MM: '%d months',
-      y:  'a year',
-      yy: '%d years'
-    }
-  });
-
-  return $window.moment;
-});

+ 0 - 6970
mod/dashboard/app/scripts/vega.js

@@ -1,6970 +0,0 @@
-vg = (function(d3, topojson) { // take d3 & topojson as imports
-  var vg = {
-    version:  "1.3.2", // semantic versioning
-    d3:       d3,      // stash d3 for use in property functions
-    topojson: topojson // stash topojson similarly
-  };
-// type checking functions
-var toString = Object.prototype.toString;
-
-vg.isObject = function(obj) {
-  return obj === Object(obj);
-};
-
-vg.isFunction = function(obj) {
-  return toString.call(obj) == '[object Function]';
-};
-
-vg.isString = function(obj) {
-  return toString.call(obj) == '[object String]';
-};
-  
-vg.isArray = Array.isArray || function(obj) {
-  return toString.call(obj) == '[object Array]';
-};
-
-vg.isNumber = function(obj) {
-  return toString.call(obj) == '[object Number]';
-};
-
-vg.isBoolean = function(obj) {
-  return toString.call(obj) == '[object Boolean]';
-};
-
-vg.isTree = function(obj) {
-  return vg.isArray(obj) && obj.__vgtree__;
-};
-
-vg.number = function(s) { return +s; };
-
-vg.boolean = function(s) { return !!s; };
-
-// utility functions
-
-vg.identity = function(x) { return x; };
-
-vg.extend = function(obj) {
-  for (var x, name, i=1, len=arguments.length; i<len; ++i) {
-    x = arguments[i];
-    for (name in x) { obj[name] = x[name]; }
-  }
-  return obj;
-};
-
-vg.duplicate = function(obj) {
-  return JSON.parse(JSON.stringify(obj));
-};
-
-vg.field = function(f) {
-  return f.split("\\.")
-    .map(function(d) { return d.split("."); })
-    .reduce(function(a, b) {
-      if (a.length) { a[a.length-1] += "." + b.shift(); }
-      a.push.apply(a, b);
-      return a;
-    }, []);
-};
-
-vg.accessor = function(f) {
-  var s;
-  return (vg.isFunction(f) || f==null)
-    ? f : vg.isString(f) && (s=vg.field(f)).length > 1
-    ? function(x) { return s.reduce(function(x,f) { return x[f]; }, x); }
-    : function(x) { return x[f]; };
-};
-
-vg.comparator = function(sort) {
-  var sign = [];
-  if (sort === undefined) sort = [];
-  sort = vg.array(sort).map(function(f) {
-    var s = 1;
-    if      (f[0] === "-") { s = -1; f = f.slice(1); }
-    else if (f[0] === "+") { s = +1; f = f.slice(1); }
-    sign.push(s);
-    return vg.accessor(f);
-  });
-  return function(a,b) {
-    var i, n, f, x, y;
-    for (i=0, n=sort.length; i<n; ++i) {
-      f = sort[i]; x = f(a); y = f(b);
-      if (x < y) return -1 * sign[i];
-      if (x > y) return sign[i];
-    }
-    return 0;
-  };
-};
-
-vg.cmp = function(a, b) { return a<b ? -1 : a>b ? 1 : 0; };
-
-vg.numcmp = function(a, b) { return a - b; };
-
-vg.array = function(x) {
-  return x != null ? (vg.isArray(x) ? x : [x]) : [];
-};
-
-vg.values = function(x) {
-  return (vg.isObject(x) && !vg.isArray(x) && x.values) ? x.values : x;
-};
-
-vg.str = function(x) {
-  return vg.isArray(x) ? "[" + x.map(vg.str) + "]"
-    : vg.isObject(x) ? JSON.stringify(x)
-    : vg.isString(x) ? ("'"+vg_escape_str(x)+"'") : x;
-};
-
-var escape_str_re = /(^|[^\\])'/g;
-
-function vg_escape_str(x) {
-  return x.replace(escape_str_re, "$1\\'");
-}
-
-vg.keys = function(x) {
-  var keys = [];
-  for (var key in x) keys.push(key);
-  return keys;
-};
-
-vg.unique = function(data, f, results) {
-  if (!vg.isArray(data) || data.length==0) return [];
-  f = f || vg.identity;
-  results = results || [];
-  for (var v, i=0, n=data.length; i<n; ++i) {
-    v = f(data[i]);
-    if (results.indexOf(v) < 0) results.push(v);
-  }
-  return results;
-};
-
-vg.minIndex = function(data, f) {
-  if (!vg.isArray(data) || data.length==0) return -1;
-  f = f || vg.identity;
-  var idx = 0, min = f(data[0]), v = min;
-  for (var i=1, n=data.length; i<n; ++i) {
-    v = f(data[i]);
-    if (v < min) { min = v; idx = i; }
-  }
-  return idx;
-};
-
-vg.maxIndex = function(data, f) {
-  if (!vg.isArray(data) || data.length==0) return -1;
-  f = f || vg.identity;
-  var idx = 0, max = f(data[0]), v = max;
-  for (var i=1, n=data.length; i<n; ++i) {
-    v = f(data[i]);
-    if (v > max) { max = v; idx = i; }
-  }
-  return idx;
-};
-
-vg.truncate = function(s, length, pos, word, ellipsis) {
-  var len = s.length;
-  if (len <= length) return s;
-  ellipsis = ellipsis || "...";
-  var l = Math.max(0, length - ellipsis.length);
-
-  switch (pos) {
-    case "left":
-      return ellipsis + (word ? vg_truncateOnWord(s,l,1) : s.slice(len-l));
-    case "middle":
-    case "center":
-      var l1 = Math.ceil(l/2), l2 = Math.floor(l/2);
-      return (word ? vg_truncateOnWord(s,l1) : s.slice(0,l1)) + ellipsis
-        + (word ? vg_truncateOnWord(s,l2,1) : s.slice(len-l2));
-    default:
-      return (word ? vg_truncateOnWord(s,l) : s.slice(0,l)) + ellipsis;
-  }
-}
-
-function vg_truncateOnWord(s, len, rev) {
-  var cnt = 0, tok = s.split(vg_truncate_word_re);
-  if (rev) {
-    s = (tok = tok.reverse())
-      .filter(function(w) { cnt += w.length; return cnt <= len; })
-      .reverse();
-  } else {
-    s = tok.filter(function(w) { cnt += w.length; return cnt <= len; });
-  }
-  return s.length ? s.join("").trim() : tok[0].slice(0, len);
-}
-
-var vg_truncate_word_re = /([\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u2028\u2029\u3000\uFEFF])/;
-
-// Logging
-
-function vg_write(msg) {
-  vg.config.isNode
-    ? process.stderr.write(msg + "\n")
-    : console.log(msg);
-}
-
-vg.log = function(msg) {
-  vg_write("[Vega Log] " + msg);
-};
-
-vg.error = function(msg) {
-  msg = "[Vega Err] " + msg;
-  vg_write(msg);
-  if (typeof alert !== "undefined") alert(msg);
-};vg.config = {};
-
-// are we running in node.js?
-// via timetler.com/2012/10/13/environment-detection-in-javascript/
-vg.config.isNode = typeof exports !== 'undefined' && this.exports !== exports;
-
-// base url for loading external data files
-// used only for server-side operation
-vg.config.baseURL = "";
-
-// version and namepsaces for exported svg
-vg.config.svgNamespace =
-  'version="1.1" xmlns="http://www.w3.org/2000/svg" ' +
-  'xmlns:xlink="http://www.w3.org/1999/xlink"';
-
-// inset padding for automatic padding calculation
-vg.config.autopadInset = 5;
-
-// extensible scale lookup table
-// all d3.scale.* instances also supported
-vg.config.scale = {
-  time: d3.time.scale,
-  utc:  d3.time.scale.utc
-};
-
-// default rendering settings
-vg.config.render = {
-  lineWidth: 1,
-  lineCap:   "butt",
-  font:      "sans-serif",
-  fontSize:  11
-};
-
-// default axis properties
-vg.config.axis = {
-  orient: "bottom",
-  ticks: 10,
-  padding: 3,
-  axisColor: "#000",
-  gridColor: "#d8d8d8",
-  tickColor: "#000",
-  tickLabelColor: "#000",
-  axisWidth: 1,
-  tickWidth: 1,
-  tickSize: 6,
-  tickLabelFontSize: 11,
-  tickLabelFont: "sans-serif",
-  titleColor: "#000",
-  titleFont: "sans-serif",
-  titleFontSize: 11,
-  titleFontWeight: "bold",
-  titleOffset: 35
-};
-
-// default legend properties
-vg.config.legend = {
-  orient: "right",
-  offset: 10,
-  padding: 3,
-  gradientStrokeColor: "#888",
-  gradientStrokeWidth: 1,
-  gradientHeight: 16,
-  gradientWidth: 100,
-  labelColor: "#000",
-  labelFontSize: 10,
-  labelFont: "sans-serif",
-  labelAlign: "left",
-  labelBaseline: "middle",
-  labelOffset: 8,
-  symbolShape: "circle",
-  symbolSize: 50,
-  symbolColor: "#888",
-  symbolStrokeWidth: 1,
-  titleColor: "#000",
-  titleFont: "sans-serif",
-  titleFontSize: 11,
-  titleFontWeight: "bold"
-};
-
-// default color values
-vg.config.color = {
-  rgb: [128, 128, 128],
-  lab: [50, 0, 0],
-  hcl: [0, 0, 50],
-  hsl: [0, 0, 0.5]
-};
-
-// default scale ranges
-vg.config.range = {
-  category10: [
-    "#1f77b4",
-    "#ff7f0e",
-    "#2ca02c",
-    "#d62728",
-    "#9467bd",
-    "#8c564b",
-    "#e377c2",
-    "#7f7f7f",
-    "#bcbd22",
-    "#17becf"
-  ],
-  category20: [
-    "#1f77b4",
-    "#aec7e8",
-    "#ff7f0e",
-    "#ffbb78",
-    "#2ca02c",
-    "#98df8a",
-    "#d62728",
-    "#ff9896",
-    "#9467bd",
-    "#c5b0d5",
-    "#8c564b",
-    "#c49c94",
-    "#e377c2",
-    "#f7b6d2",
-    "#7f7f7f",
-    "#c7c7c7",
-    "#bcbd22",
-    "#dbdb8d",
-    "#17becf",
-    "#9edae5"
-  ],
-  shapes: [
-    "circle",
-    "cross",
-    "diamond",
-    "square",
-    "triangle-down",
-    "triangle-up"
-  ]
-};vg.Bounds = (function() {
-  var bounds = function(b) {
-    this.clear();
-    if (b) this.union(b);
-  };
-  
-  var prototype = bounds.prototype;
-  
-  prototype.clear = function() {
-    this.x1 = +Number.MAX_VALUE;
-    this.y1 = +Number.MAX_VALUE;
-    this.x2 = -Number.MAX_VALUE;
-    this.y2 = -Number.MAX_VALUE;
-    return this;
-  };
-  
-  prototype.set = function(x1, y1, x2, y2) {
-    this.x1 = x1;
-    this.y1 = y1;
-    this.x2 = x2;
-    this.y2 = y2;
-    return this;
-  };
-
-  prototype.add = function(x, y) {
-    if (x < this.x1) this.x1 = x;
-    if (y < this.y1) this.y1 = y;
-    if (x > this.x2) this.x2 = x;
-    if (y > this.y2) this.y2 = y;
-    return this;
-  };
-
-  prototype.expand = function(d) {
-    this.x1 -= d;
-    this.y1 -= d;
-    this.x2 += d;
-    this.y2 += d;
-    return this;
-  };
-  
-  prototype.round = function() {
-    this.x1 = Math.floor(this.x1);
-    this.y1 = Math.floor(this.y1);
-    this.x2 = Math.ceil(this.x2);
-    this.y2 = Math.ceil(this.y2);
-    return this;
-  };
-
-  prototype.translate = function(dx, dy) {
-    this.x1 += dx;
-    this.x2 += dx;
-    this.y1 += dy;
-    this.y2 += dy;
-    return this;
-  };
-  
-  prototype.rotate = function(angle, x, y) {
-    var cos = Math.cos(angle),
-        sin = Math.sin(angle),
-        cx = x - x*cos + y*sin,
-        cy = y - x*sin - y*cos,
-        x1 = this.x1, x2 = this.x2,
-        y1 = this.y1, y2 = this.y2;
-
-    return this.clear()
-      .add(cos*x1 - sin*y1 + cx,  sin*x1 + cos*y1 + cy)
-      .add(cos*x1 - sin*y2 + cx,  sin*x1 + cos*y2 + cy)
-      .add(cos*x2 - sin*y1 + cx,  sin*x2 + cos*y1 + cy)
-      .add(cos*x2 - sin*y2 + cx,  sin*x2 + cos*y2 + cy);
-  }
-
-  prototype.union = function(b) {
-    if (b.x1 < this.x1) this.x1 = b.x1;
-    if (b.y1 < this.y1) this.y1 = b.y1;
-    if (b.x2 > this.x2) this.x2 = b.x2;
-    if (b.y2 > this.y2) this.y2 = b.y2;
-    return this;
-  };
-
-  prototype.encloses = function(b) {
-    return b && (
-      this.x1 <= b.x1 &&
-      this.x2 >= b.x2 &&
-      this.y1 <= b.y1 &&
-      this.y2 >= b.y2
-    );
-  };
-
-  prototype.intersects = function(b) {
-    return b && !(
-      this.x2 < b.x1 ||
-      this.x1 > b.x2 ||
-      this.y2 < b.y1 ||
-      this.y1 > b.y2
-    );
-  };
-
-  prototype.contains = function(x, y) {
-    return !(
-      x < this.x1 ||
-      x > this.x2 ||
-      y < this.y1 ||
-      y > this.y2
-    );
-  };
-
-  prototype.width = function() {
-    return this.x2 - this.x1;
-  };
-
-  prototype.height = function() {
-    return this.y2 - this.y1;
-  };
-
-  return bounds;
-})();vg.Gradient = (function() {
-
-  function gradient(type) {
-    this.id = "grad_" + (vg_gradient_id++);
-    this.type = type || "linear";
-    this.stops = [];
-    this.x1 = 0;
-    this.x2 = 1;
-    this.y1 = 0;
-    this.y2 = 0;
-  };
-
-  var prototype = gradient.prototype;
-
-  prototype.stop = function(offset, color) {
-    this.stops.push({
-      offset: offset,
-      color: color
-    });
-    return this;
-  };
-  
-  return gradient;
-})();
-
-var vg_gradient_id = 0;vg.canvas = {};vg.canvas.path = (function() {
-
-  // Path parsing and rendering code taken from fabric.js -- Thanks!
-  var cmdLength = { m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7 },
-      re = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\d)-/g, /\s|,|###/];
-
-  function parse(path) {
-    var result = [],
-        currentPath,
-        chunks,
-        parsed;
-
-    // First, break path into command sequence
-    path = path.slice().replace(re[0], '###$1').split(re[1]).slice(1);
-
-    // Next, parse each command in turn
-    for (var i=0, j, chunksParsed, len=path.length; i<len; i++) {
-      currentPath = path[i];
-      chunks = currentPath.slice(1).trim().replace(re[2],'$1###-').split(re[3]);
-      chunksParsed = [currentPath.charAt(0)];
-
-      for (var j = 0, jlen = chunks.length; j < jlen; j++) {
-        parsed = parseFloat(chunks[j]);
-        if (!isNaN(parsed)) {
-          chunksParsed.push(parsed);
-        }
-      }
-
-      var command = chunksParsed[0].toLowerCase(),
-          commandLength = cmdLength[command];
-
-      if (chunksParsed.length - 1 > commandLength) {
-        for (var k = 1, klen = chunksParsed.length; k < klen; k += commandLength) {
-          result.push([ chunksParsed[0] ].concat(chunksParsed.slice(k, k + commandLength)));
-        }
-      }
-      else {
-        result.push(chunksParsed);
-      }
-    }
-
-    return result;
-  }
-
-  function drawArc(g, x, y, coords, bounds, l, t) {
-    var rx = coords[0];
-    var ry = coords[1];
-    var rot = coords[2];
-    var large = coords[3];
-    var sweep = coords[4];
-    var ex = coords[5];
-    var ey = coords[6];
-    var segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
-    for (var i=0; i<segs.length; i++) {
-      var bez = segmentToBezier.apply(null, segs[i]);
-      g.bezierCurveTo.apply(g, bez);
-      bounds.add(bez[0]-l, bez[1]-t);
-      bounds.add(bez[2]-l, bez[3]-t);
-      bounds.add(bez[4]-l, bez[5]-t);
-    }
-  }
-
-  function boundArc(x, y, coords, bounds) {
-    var rx = coords[0];
-    var ry = coords[1];
-    var rot = coords[2];
-    var large = coords[3];
-    var sweep = coords[4];
-    var ex = coords[5];
-    var ey = coords[6];
-    var segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
-    for (var i=0; i<segs.length; i++) {
-      var bez = segmentToBezier.apply(null, segs[i]);
-      bounds.add(bez[0]-l, bez[1]-t);
-      bounds.add(bez[2]-l, bez[3]-t);
-      bounds.add(bez[4]-l, bez[5]-t);
-    }
-  }
-
-  var arcToSegmentsCache = { },
-      segmentToBezierCache = { },
-      join = Array.prototype.join,
-      argsStr;
-
-  // Copied from Inkscape svgtopdf, thanks!
-  function arcToSegments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
-    argsStr = join.call(arguments);
-    if (arcToSegmentsCache[argsStr]) {
-      return arcToSegmentsCache[argsStr];
-    }
-
-    var th = rotateX * (Math.PI/180);
-    var sin_th = Math.sin(th);
-    var cos_th = Math.cos(th);
-    rx = Math.abs(rx);
-    ry = Math.abs(ry);
-    var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5;
-    var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5;
-    var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry);
-    if (pl > 1) {
-      pl = Math.sqrt(pl);
-      rx *= pl;
-      ry *= pl;
-    }
-
-    var a00 = cos_th / rx;
-    var a01 = sin_th / rx;
-    var a10 = (-sin_th) / ry;
-    var a11 = (cos_th) / ry;
-    var x0 = a00 * ox + a01 * oy;
-    var y0 = a10 * ox + a11 * oy;
-    var x1 = a00 * x + a01 * y;
-    var y1 = a10 * x + a11 * y;
-
-    var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0);
-    var sfactor_sq = 1 / d - 0.25;
-    if (sfactor_sq < 0) sfactor_sq = 0;
-    var sfactor = Math.sqrt(sfactor_sq);
-    if (sweep == large) sfactor = -sfactor;
-    var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0);
-    var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0);
-
-    var th0 = Math.atan2(y0-yc, x0-xc);
-    var th1 = Math.atan2(y1-yc, x1-xc);
-
-    var th_arc = th1-th0;
-    if (th_arc < 0 && sweep == 1){
-      th_arc += 2*Math.PI;
-    } else if (th_arc > 0 && sweep == 0) {
-      th_arc -= 2 * Math.PI;
-    }
-
-    var segments = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001)));
-    var result = [];
-    for (var i=0; i<segments; i++) {
-      var th2 = th0 + i * th_arc / segments;
-      var th3 = th0 + (i+1) * th_arc / segments;
-      result[i] = [xc, yc, th2, th3, rx, ry, sin_th, cos_th];
-    }
-
-    return (arcToSegmentsCache[argsStr] = result);
-  }
-
-  function segmentToBezier(cx, cy, th0, th1, rx, ry, sin_th, cos_th) {
-    argsStr = join.call(arguments);
-    if (segmentToBezierCache[argsStr]) {
-      return segmentToBezierCache[argsStr];
-    }
-
-    var a00 = cos_th * rx;
-    var a01 = -sin_th * ry;
-    var a10 = sin_th * rx;
-    var a11 = cos_th * ry;
-
-    var cos_th0 = Math.cos(th0);
-    var sin_th0 = Math.sin(th0);
-    var cos_th1 = Math.cos(th1);
-    var sin_th1 = Math.sin(th1);
-
-    var th_half = 0.5 * (th1 - th0);
-    var sin_th_h2 = Math.sin(th_half * 0.5);
-    var t = (8/3) * sin_th_h2 * sin_th_h2 / Math.sin(th_half);
-    var x1 = cx + cos_th0 - t * sin_th0;
-    var y1 = cy + sin_th0 + t * cos_th0;
-    var x3 = cx + cos_th1;
-    var y3 = cy + sin_th1;
-    var x2 = x3 + t * sin_th1;
-    var y2 = y3 - t * cos_th1;
-
-    return (segmentToBezierCache[argsStr] = [
-      a00 * x1 + a01 * y1,  a10 * x1 + a11 * y1,
-      a00 * x2 + a01 * y2,  a10 * x2 + a11 * y2,
-      a00 * x3 + a01 * y3,  a10 * x3 + a11 * y3
-    ]);
-  }
-
-  function render(g, path, l, t) {
-    var current, // current instruction
-        previous = null,
-        x = 0, // current x
-        y = 0, // current y
-        controlX = 0, // current control point x
-        controlY = 0, // current control point y
-        tempX,
-        tempY,
-        tempControlX,
-        tempControlY,
-        bounds = new vg.Bounds();
-    if (l == undefined) l = 0;
-    if (t == undefined) t = 0;
-
-    g.beginPath();
-  
-    for (var i=0, len=path.length; i<len; ++i) {
-      current = path[i];
-
-      switch (current[0]) { // first letter
-
-        case 'l': // lineto, relative
-          x += current[1];
-          y += current[2];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'L': // lineto, absolute
-          x = current[1];
-          y = current[2];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'h': // horizontal lineto, relative
-          x += current[1];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'H': // horizontal lineto, absolute
-          x = current[1];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'v': // vertical lineto, relative
-          y += current[1];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'V': // verical lineto, absolute
-          y = current[1];
-          g.lineTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'm': // moveTo, relative
-          x += current[1];
-          y += current[2];
-          g.moveTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'M': // moveTo, absolute
-          x = current[1];
-          y = current[2];
-          g.moveTo(x + l, y + t);
-          bounds.add(x, y);
-          break;
-
-        case 'c': // bezierCurveTo, relative
-          tempX = x + current[5];
-          tempY = y + current[6];
-          controlX = x + current[3];
-          controlY = y + current[4];
-          g.bezierCurveTo(
-            x + current[1] + l, // x1
-            y + current[2] + t, // y1
-            controlX + l, // x2
-            controlY + t, // y2
-            tempX + l,
-            tempY + t
-          );
-          bounds.add(x + current[1], y + current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          x = tempX;
-          y = tempY;
-          break;
-
-        case 'C': // bezierCurveTo, absolute
-          x = current[5];
-          y = current[6];
-          controlX = current[3];
-          controlY = current[4];
-          g.bezierCurveTo(
-            current[1] + l,
-            current[2] + t,
-            controlX + l,
-            controlY + t,
-            x + l,
-            y + t
-          );
-          bounds.add(current[1], current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(x, y);
-          break;
-
-        case 's': // shorthand cubic bezierCurveTo, relative
-          // transform to absolute x,y
-          tempX = x + current[3];
-          tempY = y + current[4];
-          // calculate reflection of previous control points
-          controlX = 2 * x - controlX;
-          controlY = 2 * y - controlY;
-          g.bezierCurveTo(
-            controlX + l,
-            controlY + t,
-            x + current[1] + l,
-            y + current[2] + t,
-            tempX + l,
-            tempY + t
-          );
-          bounds.add(controlX, controlY);
-          bounds.add(x + current[1], y + current[2]);
-          bounds.add(tempX, tempY);
-
-          // set control point to 2nd one of this command
-          // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point."
-          controlX = x + current[1];
-          controlY = y + current[2];
-
-          x = tempX;
-          y = tempY;
-          break;
-
-        case 'S': // shorthand cubic bezierCurveTo, absolute
-          tempX = current[3];
-          tempY = current[4];
-          // calculate reflection of previous control points
-          controlX = 2*x - controlX;
-          controlY = 2*y - controlY;
-          g.bezierCurveTo(
-            controlX + l,
-            controlY + t,
-            current[1] + l,
-            current[2] + t,
-            tempX + l,
-            tempY + t
-          );
-          x = tempX;
-          y = tempY;
-          bounds.add(current[1], current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          // set control point to 2nd one of this command
-          // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point."
-          controlX = current[1];
-          controlY = current[2];
-
-          break;
-
-        case 'q': // quadraticCurveTo, relative
-          // transform to absolute x,y
-          tempX = x + current[3];
-          tempY = y + current[4];
-
-          controlX = x + current[1];
-          controlY = y + current[2];
-
-          g.quadraticCurveTo(
-            controlX + l,
-            controlY + t,
-            tempX + l,
-            tempY + t
-          );
-          x = tempX;
-          y = tempY;
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'Q': // quadraticCurveTo, absolute
-          tempX = current[3];
-          tempY = current[4];
-
-          g.quadraticCurveTo(
-            current[1] + l,
-            current[2] + t,
-            tempX + l,
-            tempY + t
-          );
-          x = tempX;
-          y = tempY;
-          controlX = current[1];
-          controlY = current[2];
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 't': // shorthand quadraticCurveTo, relative
-
-          // transform to absolute x,y
-          tempX = x + current[1];
-          tempY = y + current[2];
-
-          if (previous[0].match(/[QqTt]/) === null) {
-            // If there is no previous command or if the previous command was not a Q, q, T or t,
-            // assume the control point is coincident with the current point
-            controlX = x;
-            controlY = y;
-          }
-          else if (previous[0] === 't') {
-            // calculate reflection of previous control points for t
-            controlX = 2 * x - tempControlX;
-            controlY = 2 * y - tempControlY;
-          }
-          else if (previous[0] === 'q') {
-            // calculate reflection of previous control points for q
-            controlX = 2 * x - controlX;
-            controlY = 2 * y - controlY;
-          }
-
-          tempControlX = controlX;
-          tempControlY = controlY;
-
-          g.quadraticCurveTo(
-            controlX + l,
-            controlY + t,
-            tempX + l,
-            tempY + t
-          );
-          x = tempX;
-          y = tempY;
-          controlX = x + current[1];
-          controlY = y + current[2];
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'T':
-          tempX = current[1];
-          tempY = current[2];
-
-          // calculate reflection of previous control points
-          controlX = 2 * x - controlX;
-          controlY = 2 * y - controlY;
-          g.quadraticCurveTo(
-            controlX + l,
-            controlY + t,
-            tempX + l,
-            tempY + t
-          );
-          x = tempX;
-          y = tempY;
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'a':
-          drawArc(g, x + l, y + t, [
-            current[1],
-            current[2],
-            current[3],
-            current[4],
-            current[5],
-            current[6] + x + l,
-            current[7] + y + t
-          ], bounds, l, t);
-          x += current[6];
-          y += current[7];
-          break;
-
-        case 'A':
-          drawArc(g, x + l, y + t, [
-            current[1],
-            current[2],
-            current[3],
-            current[4],
-            current[5],
-            current[6] + l,
-            current[7] + t
-          ], bounds, l, t);
-          x = current[6];
-          y = current[7];
-          break;
-
-        case 'z':
-        case 'Z':
-          g.closePath();
-          break;
-      }
-      previous = current;
-    }
-    return bounds.translate(l, t);
-  }
-
-  function bounds(path, bounds) {
-    var current, // current instruction
-        previous = null,
-        x = 0, // current x
-        y = 0, // current y
-        controlX = 0, // current control point x
-        controlY = 0, // current control point y
-        tempX,
-        tempY,
-        tempControlX,
-        tempControlY;
-
-    for (var i=0, len=path.length; i<len; ++i) {
-      current = path[i];
-
-      switch (current[0]) { // first letter
-
-        case 'l': // lineto, relative
-          x += current[1];
-          y += current[2];
-          bounds.add(x, y);
-          break;
-
-        case 'L': // lineto, absolute
-          x = current[1];
-          y = current[2];
-          bounds.add(x, y);
-          break;
-
-        case 'h': // horizontal lineto, relative
-          x += current[1];
-          bounds.add(x, y);
-          break;
-
-        case 'H': // horizontal lineto, absolute
-          x = current[1];
-          bounds.add(x, y);
-          break;
-
-        case 'v': // vertical lineto, relative
-          y += current[1];
-          bounds.add(x, y);
-          break;
-
-        case 'V': // verical lineto, absolute
-          y = current[1];
-          bounds.add(x, y);
-          break;
-
-        case 'm': // moveTo, relative
-          x += current[1];
-          y += current[2];
-          bounds.add(x, y);
-          break;
-
-        case 'M': // moveTo, absolute
-          x = current[1];
-          y = current[2];
-          bounds.add(x, y);
-          break;
-
-        case 'c': // bezierCurveTo, relative
-          tempX = x + current[5];
-          tempY = y + current[6];
-          controlX = x + current[3];
-          controlY = y + current[4];
-          bounds.add(x + current[1], y + current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          x = tempX;
-          y = tempY;
-          break;
-
-        case 'C': // bezierCurveTo, absolute
-          x = current[5];
-          y = current[6];
-          controlX = current[3];
-          controlY = current[4];
-          bounds.add(current[1], current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(x, y);
-          break;
-
-        case 's': // shorthand cubic bezierCurveTo, relative
-          // transform to absolute x,y
-          tempX = x + current[3];
-          tempY = y + current[4];
-          // calculate reflection of previous control points
-          controlX = 2 * x - controlX;
-          controlY = 2 * y - controlY;
-          bounds.add(controlX, controlY);
-          bounds.add(x + current[1], y + current[2]);
-          bounds.add(tempX, tempY);
-
-          // set control point to 2nd one of this command
-          // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point."
-          controlX = x + current[1];
-          controlY = y + current[2];
-
-          x = tempX;
-          y = tempY;
-          break;
-
-        case 'S': // shorthand cubic bezierCurveTo, absolute
-          tempX = current[3];
-          tempY = current[4];
-          // calculate reflection of previous control points
-          controlX = 2*x - controlX;
-          controlY = 2*y - controlY;
-          x = tempX;
-          y = tempY;
-          bounds.add(current[1], current[2]);
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          // set control point to 2nd one of this command
-          // "... the first control point is assumed to be the reflection of the second control point on the previous command relative to the current point."
-          controlX = current[1];
-          controlY = current[2];
-
-          break;
-
-        case 'q': // quadraticCurveTo, relative
-          // transform to absolute x,y
-          tempX = x + current[3];
-          tempY = y + current[4];
-
-          controlX = x + current[1];
-          controlY = y + current[2];
-
-          x = tempX;
-          y = tempY;
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'Q': // quadraticCurveTo, absolute
-          tempX = current[3];
-          tempY = current[4];
-
-          x = tempX;
-          y = tempY;
-          controlX = current[1];
-          controlY = current[2];
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 't': // shorthand quadraticCurveTo, relative
-
-          // transform to absolute x,y
-          tempX = x + current[1];
-          tempY = y + current[2];
-
-          if (previous[0].match(/[QqTt]/) === null) {
-            // If there is no previous command or if the previous command was not a Q, q, T or t,
-            // assume the control point is coincident with the current point
-            controlX = x;
-            controlY = y;
-          }
-          else if (previous[0] === 't') {
-            // calculate reflection of previous control points for t
-            controlX = 2 * x - tempControlX;
-            controlY = 2 * y - tempControlY;
-          }
-          else if (previous[0] === 'q') {
-            // calculate reflection of previous control points for q
-            controlX = 2 * x - controlX;
-            controlY = 2 * y - controlY;
-          }
-
-          tempControlX = controlX;
-          tempControlY = controlY;
-
-          x = tempX;
-          y = tempY;
-          controlX = x + current[1];
-          controlY = y + current[2];
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'T':
-          tempX = current[1];
-          tempY = current[2];
-
-          // calculate reflection of previous control points
-          controlX = 2 * x - controlX;
-          controlY = 2 * y - controlY;
-
-          x = tempX;
-          y = tempY;
-          bounds.add(controlX, controlY);
-          bounds.add(tempX, tempY);
-          break;
-
-        case 'a':
-          boundArc(x, y, [
-            current[1],
-            current[2],
-            current[3],
-            current[4],
-            current[5],
-            current[6] + x,
-            current[7] + y
-          ], bounds);
-          x += current[6];
-          y += current[7];
-          break;
-
-        case 'A':
-          boundArc(x, y, [
-            current[1],
-            current[2],
-            current[3],
-            current[4],
-            current[5],
-            current[6],
-            current[7]
-          ], bounds);
-          x = current[6];
-          y = current[7];
-          break;
-
-        case 'z':
-        case 'Z':
-          break;
-      }
-      previous = current;
-    }
-    return bounds;
-  }
-  
-  function area(items) {
-    var o = items[0];
-    var area = d3.svg.area()
-      .x(function(d) { return d.x; })
-      .y1(function(d) { return d.y; })
-      .y0(function(d) { return d.y + d.height; });
-    if (o.interpolate) area.interpolate(o.interpolate);
-    if (o.tension != null) area.tension(o.tension);
-    return area(items);
-  }
-
-  function line(items) {
-    var o = items[0];
-    var line = d3.svg.line()
-     .x(function(d) { return d.x; })
-     .y(function(d) { return d.y; });
-    if (o.interpolate) line.interpolate(o.interpolate);
-    if (o.tension != null) line.tension(o.tension);
-    return line(items);
-  }
-  
-  return {
-    parse:  parse,
-    render: render,
-    bounds: bounds,
-    area:   area,
-    line:   line
-  };
-  
-})();vg.canvas.marks = (function() {
-
-  var parsePath = vg.canvas.path.parse,
-      renderPath = vg.canvas.path.render,
-      halfpi = Math.PI / 2,
-      sqrt3 = Math.sqrt(3),
-      tan30 = Math.tan(30 * Math.PI / 180),
-      tmpBounds = new vg.Bounds();
-
-  // path generators
-
-  function arcPath(g, o) {
-    var x = o.x || 0,
-        y = o.y || 0,
-        ir = o.innerRadius || 0,
-        or = o.outerRadius || 0,
-        sa = (o.startAngle || 0) - Math.PI/2,
-        ea = (o.endAngle || 0) - Math.PI/2;
-    g.beginPath();
-    if (ir === 0) g.moveTo(x, y);
-    else g.arc(x, y, ir, sa, ea, 0);
-    g.arc(x, y, or, ea, sa, 1);
-    g.closePath();
-  }
-
-  function pathPath(g, o) {
-    if (o.path == null) return;
-    if (!o["path:parsed"]) {
-      o["path:parsed"] = parsePath(o.path);
-    }
-    return renderPath(g, o["path:parsed"], o.x, o.y);
-  }
-
-  function symbolPath(g, o) {
-    g.beginPath();
-    var size = o.size != null ? o.size : 100,
-        x = o.x, y = o.y, r, t, rx, ry;
-
-    if (o.shape == null || o.shape === "circle") {
-      r = Math.sqrt(size/Math.PI);
-      g.arc(x, y, r, 0, 2*Math.PI, 0);
-      g.closePath();
-      return;
-    }
-
-    switch (o.shape) {
-      case "cross":
-        r = Math.sqrt(size / 5) / 2;
-        t = 3*r;
-        g.moveTo(x-t, y-r);
-        g.lineTo(x-r, y-r);
-        g.lineTo(x-r, y-t);
-        g.lineTo(x+r, y-t);
-        g.lineTo(x+r, y-r);
-        g.lineTo(x+t, y-r);
-        g.lineTo(x+t, y+r);
-        g.lineTo(x+r, y+r);
-        g.lineTo(x+r, y+t);
-        g.lineTo(x-r, y+t);
-        g.lineTo(x-r, y+r);
-        g.lineTo(x-t, y+r);
-        break;
-
-      case "diamond":
-        ry = Math.sqrt(size / (2 * tan30));
-        rx = ry * tan30;
-        g.moveTo(x, y-ry);
-        g.lineTo(x+rx, y);
-        g.lineTo(x, y+ry);
-        g.lineTo(x-rx, y);
-        break;
-
-      case "square":
-        t = Math.sqrt(size);
-        r = t / 2;
-        g.rect(x-r, y-r, t, t);
-        break;
-
-      case "triangle-down":
-        rx = Math.sqrt(size / sqrt3);
-        ry = rx * sqrt3 / 2;
-        g.moveTo(x, y+ry);
-        g.lineTo(x+rx, y-ry);
-        g.lineTo(x-rx, y-ry);
-        break;
-
-      case "triangle-up":
-        rx = Math.sqrt(size / sqrt3);
-        ry = rx * sqrt3 / 2;
-        g.moveTo(x, y-ry);
-        g.lineTo(x+rx, y+ry);
-        g.lineTo(x-rx, y+ry);
-    }
-    g.closePath();
-  }
-
-  function areaPath(g, items) {
-    var o = items[0],
-        p = o["path:parsed"] ||
-           (o["path:parsed"] = parsePath(vg.canvas.path.area(items)));
-    renderPath(g, p);
-  }
-
-  function linePath(g, items) {
-    var o = items[0],
-        p = o["path:parsed"] ||
-           (o["path:parsed"] = parsePath(vg.canvas.path.line(items)));
-    renderPath(g, p);
-  }
-
-  function lineStroke(g, items) {
-    var o = items[0],
-        lw = o.strokeWidth,
-        lc = o.strokeCap;
-    g.lineWidth = lw != null ? lw : vg.config.render.lineWidth;
-    g.lineCap   = lc != null ? lc : vg.config.render.lineCap;
-    linePath(g, items);
-  }
-
-  function ruleStroke(g, o) {
-    var x1 = o.x || 0,
-        y1 = o.y || 0,
-        x2 = o.x2 != null ? o.x2 : x1,
-        y2 = o.y2 != null ? o.y2 : y1,
-        lw = o.strokeWidth,
-        lc = o.strokeCap;
-
-    g.lineWidth = lw != null ? lw : vg.config.render.lineWidth;
-    g.lineCap   = lc != null ? lc : vg.config.render.lineCap;
-    g.beginPath();
-    g.moveTo(x1, y1);
-    g.lineTo(x2, y2);
-  }
-
-  // drawing functions
-
-  function drawPathOne(path, g, o, items) {
-    var fill = o.fill, stroke = o.stroke, opac, lc, lw;
-
-    path(g, items);
-
-    opac = o.opacity == null ? 1 : o.opacity;
-    if (opac == 0 || !fill && !stroke) return;
-
-    if (fill) {
-      g.globalAlpha = opac * (o.fillOpacity==null ? 1 : o.fillOpacity);
-      g.fillStyle = color(g, o, fill);
-      g.fill();
-    }
-
-    if (stroke) {
-      lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth;
-      if (lw > 0) {
-        g.globalAlpha = opac * (o.strokeOpacity==null ? 1 : o.strokeOpacity);
-        g.strokeStyle = color(g, o, stroke);
-        g.lineWidth = lw;
-        g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap;
-        g.vgLineDash(o.strokeDash || null);
-        g.vgLineDashOffset(o.strokeDashOffset || 0);
-        g.stroke();
-      }
-    }
-  }
-
-  function drawPathAll(path, g, scene, bounds) {
-    var i, len, item;
-    for (i=0, len=scene.items.length; i<len; ++i) {
-      item = scene.items[i];
-      if (bounds && !bounds.intersects(item.bounds))
-        continue; // bounds check
-      drawPathOne(path, g, item, item);
-    }
-  }
-
-  function drawRect(g, scene, bounds) {
-    if (!scene.items.length) return;
-    var items = scene.items,
-        o, fill, stroke, opac, lc, lw, x, y, w, h;
-
-    for (var i=0, len=items.length; i<len; ++i) {
-      o = items[i];
-      if (bounds && !bounds.intersects(o.bounds))
-        continue; // bounds check
-
-      x = o.x || 0;
-      y = o.y || 0;
-      w = o.width || 0;
-      h = o.height || 0;
-
-      opac = o.opacity == null ? 1 : o.opacity;
-      if (opac == 0) return;
-
-      if (fill = o.fill) {
-        g.globalAlpha = opac * (o.fillOpacity==null ? 1 : o.fillOpacity);
-        g.fillStyle = color(g, o, fill);
-        g.fillRect(x, y, w, h);
-      }
-
-      if (stroke = o.stroke) {
-        lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth;
-        if (lw > 0) {
-          g.globalAlpha = opac * (o.strokeOpacity==null ? 1 : o.strokeOpacity);
-          g.strokeStyle = color(g, o, stroke);
-          g.lineWidth = lw;
-          g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap;
-          g.vgLineDash(o.strokeDash || null);
-          g.vgLineDashOffset(o.strokeDashOffset || 0);
-          g.strokeRect(x, y, w, h);
-        }
-      }
-    }
-  }
-
-  function drawRule(g, scene, bounds) {
-    if (!scene.items.length) return;
-    var items = scene.items,
-        o, stroke, opac, lc, lw, x1, y1, x2, y2;
-
-    for (var i=0, len=items.length; i<len; ++i) {
-      o = items[i];
-      if (bounds && !bounds.intersects(o.bounds))
-        continue; // bounds check
-
-      x1 = o.x || 0;
-      y1 = o.y || 0;
-      x2 = o.x2 != null ? o.x2 : x1;
-      y2 = o.y2 != null ? o.y2 : y1;
-
-      opac = o.opacity == null ? 1 : o.opacity;
-      if (opac == 0) return;
-      
-      if (stroke = o.stroke) {
-        lw = (lw = o.strokeWidth) != null ? lw : vg.config.render.lineWidth;
-        if (lw > 0) {
-          g.globalAlpha = opac * (o.strokeOpacity==null ? 1 : o.strokeOpacity);
-          g.strokeStyle = color(g, o, stroke);
-          g.lineWidth = lw;
-          g.lineCap = (lc = o.strokeCap) != null ? lc : vg.config.render.lineCap;
-          g.vgLineDash(o.strokeDash || null);
-          g.vgLineDashOffset(o.strokeDashOffset || 0);
-          g.beginPath();
-          g.moveTo(x1, y1);
-          g.lineTo(x2, y2);
-          g.stroke();
-        }
-      }
-    }
-  }
-
-  function drawImage(g, scene, bounds) {
-    if (!scene.items.length) return;
-    var renderer = this,
-        items = scene.items, o;
-
-    for (var i=0, len=items.length; i<len; ++i) {
-      o = items[i];
-      if (bounds && !bounds.intersects(o.bounds))
-        continue; // bounds check
-
-      if (!(o.image && o.image.url === o.url)) {
-        o.image = renderer.loadImage(o.url);
-        o.image.url = o.url;
-      }
-
-      var x, y, w, h, opac;
-      w = o.width || (o.image && o.image.width) || 0;
-      h = o.height || (o.image && o.image.height) || 0;
-      x = (o.x||0) - (o.align === "center"
-        ? w/2 : (o.align === "right" ? w : 0));
-      y = (o.y||0) - (o.baseline === "middle"
-        ? h/2 : (o.baseline === "bottom" ? h : 0));
-
-      if (o.image.loaded) {
-        g.globalAlpha = (opac = o.opacity) != null ? opac : 1;
-        g.drawImage(o.image, x, y, w, h);
-      }
-    }
-  }
-
-  function drawText(g, scene, bounds) {
-    if (!scene.items.length) return;
-    var items = scene.items,
-        o, fill, stroke, opac, lw, text, ta, tb;
-
-    for (var i=0, len=items.length; i<len; ++i) {
-      o = items[i];
-      if (bounds && !bounds.intersects(o.bounds))
-        continue; // bounds check
-
-      g.font = vg.scene.fontString(o);
-      g.textAlign = o.align || "left";
-      g.textBaseline = o.baseline || "alphabetic";
-
-      opac = o.opacity == null ? 1 : o.opacity;
-      if (opac == 0) return;
-
-      if (o.angle) {
-        g.save();
-        g.translate(o.x || 0, o.y || 0);
-        g.rotate(o.angle * Math.PI/180);
-        x = o.dx || 0;
-        y = o.dy || 0;
-      } else {
-        x = (o.x || 0) + (o.dx || 0);
-        y = (o.y || 0) + (o.dy || 0);
-      }
-
-      if (fill = o.fill) {
-        g.globalAlpha = opac * (o.fillOpacity==null ? 1 : o.fillOpacity);
-        g.fillStyle = color(g, o, fill);
-        g.fillText(o.text, x, y);
-      }
-
-      if (stroke = o.stroke) {
-        lw = (lw = o.strokeWidth) != null ? lw : 1;
-        if (lw > 0) {
-          g.globalAlpha = opac * (o.strokeOpacity==null ? 1 : o.strokeOpacity);
-          g.strokeStyle = color(o, stroke);
-          g.lineWidth = lw;
-          g.strokeText(o.text, x, y);
-        }
-      }
-
-      if (o.angle) g.restore();
-    }
-  }
-
-  function drawAll(pathFunc) {
-    return function(g, scene, bounds) {
-      drawPathAll(pathFunc, g, scene, bounds);
-    }
-  }
-
-  function drawOne(pathFunc) {
-    return function(g, scene, bounds) {
-      if (!scene.items.length) return;
-      if (bounds && !bounds.intersects(scene.items[0].bounds))
-        return; // bounds check
-      drawPathOne(pathFunc, g, scene.items[0], scene.items);
-    }
-  }
-
-  function drawGroup(g, scene, bounds) {
-    if (!scene.items.length) return;
-    var items = scene.items, group, axes, legends,
-        renderer = this, gx, gy, gb, i, n, j, m;
-
-    drawRect(g, scene, bounds);
-
-    for (i=0, n=items.length; i<n; ++i) {
-      group = items[i];
-      axes = group.axisItems || [];
-      legends = group.legendItems || [];
-      gx = group.x || 0;
-      gy = group.y || 0;
-
-      // render group contents
-      g.save();
-      g.translate(gx, gy);
-      if (bounds) bounds.translate(-gx, -gy);
-      for (j=0, m=axes.length; j<m; ++j) {
-        if (axes[j].def.layer === "back") {
-          renderer.draw(g, axes[j], bounds);
-        }
-      }
-      for (j=0, m=group.items.length; j<m; ++j) {
-        renderer.draw(g, group.items[j], bounds);
-      }
-      for (j=0, m=axes.length; j<m; ++j) {
-        if (axes[j].def.layer !== "back") {
-          renderer.draw(g, axes[j], bounds);
-        }
-      }
-      for (j=0, m=legends.length; j<m; ++j) {
-        renderer.draw(g, legends[j], bounds);
-      }
-      if (bounds) bounds.translate(gx, gy);
-      g.restore();
-    }    
-  }
-
-  function color(g, o, value) {
-    return (value.id)
-      ? gradient(g, value, o.bounds)
-      : value;
-  }
-
-  function gradient(g, p, b) {
-    var w = b.width(),
-        h = b.height(),
-        x1 = b.x1 + p.x1 * w,
-        y1 = b.y1 + p.y1 * h,
-        x2 = b.x1 + p.x2 * w,
-        y2 = b.y1 + p.y2 * h,
-        grad = g.createLinearGradient(x1, y1, x2, y2),
-        stop = p.stops,
-        i, n;
-
-    for (i=0, n=stop.length; i<n; ++i) {
-      grad.addColorStop(stop[i].offset, stop[i].color);
-    }
-    return grad;
-  }
-
-  // hit testing
-
-  function pickGroup(g, scene, x, y, gx, gy) {
-    if (scene.items.length === 0 ||
-        scene.bounds && !scene.bounds.contains(gx, gy)) {
-      return false;
-    }
-    var items = scene.items, subscene, group, hit, dx, dy,
-        handler = this, i, j;
-
-    for (i=items.length; --i>=0;) {
-      group = items[i];
-      dx = group.x || 0;
-      dy = group.y || 0;
-
-      g.save();
-      g.translate(dx, dy);
-      for (j=group.items.length; --j >= 0;) {
-        subscene = group.items[j];
-        if (subscene.interactive === false) continue;
-        hit = handler.pick(subscene, x, y, gx-dx, gy-dy);
-        if (hit) {
-          g.restore();
-          return hit;
-        }
-      }
-      g.restore();
-    }
-
-    return scene.interactive
-      ? pickAll(hitTests.rect, g, scene, x, y, gx, gy)
-      : false;
-  }
-
-  function pickAll(test, g, scene, x, y, gx, gy) {
-    if (!scene.items.length) return false;
-    var o, b, i;
-
-    if (g._ratio !== 1) {
-      x *= g._ratio;
-      y *= g._ratio;
-    }
-
-    for (i=scene.items.length; --i >= 0;) {
-      o = scene.items[i]; b = o.bounds;
-      // first hit test against bounding box
-      if ((b && !b.contains(gx, gy)) || !b) continue;
-      // if in bounding box, perform more careful test
-      if (test(g, o, x, y, gx, gy)) return o;
-    }
-    return false;
-  }
-
-  function pickArea(g, scene, x, y, gx, gy) {
-    if (!scene.items.length) return false;
-    var items = scene.items,
-        o, b, i, di, dd, od, dx, dy;
-
-    b = items[0].bounds;
-    if (b && !b.contains(gx, gy)) return false;
-    if (g._ratio !== 1) {
-      x *= g._ratio;
-      y *= g._ratio;
-    }
-    if (!hitTests.area(g, items, x, y)) return false;
-    return items[0];
-  }
-
-  function pickLine(g, scene, x, y, gx, gy) {
-    if (!scene.items.length) return false;
-    var items = scene.items,
-        o, b, i, di, dd, od, dx, dy;
-
-    b = items[0].bounds;
-    if (b && !b.contains(gx, gy)) return false;
-    if (g._ratio !== 1) {
-      x *= g._ratio;
-      y *= g._ratio;
-    }
-    if (!hitTests.line(g, items, x, y)) return false;
-    return items[0];
-  }
-
-  function pick(test) {
-    return function (g, scene, x, y, gx, gy) {
-      return pickAll(test, g, scene, x, y, gx, gy);
-    };
-  }
-
-  function textHit(g, o, x, y, gx, gy) {
-    if (!o.fontSize) return false;
-    if (!o.angle) return true; // bounds sufficient if no rotation
-
-    var b = vg.scene.bounds.text(o, tmpBounds, true),
-        a = -o.angle * Math.PI / 180,
-        cos = Math.cos(a),
-        sin = Math.sin(a),
-        x = o.x,
-        y = o.y,
-        px = cos*gx - sin*gy + (x - x*cos + y*sin),
-        py = sin*gx + cos*gy + (y - x*sin - y*cos);
-
-    return b.contains(px, py);
-  }
-
-  var hitTests = {
-    text:   textHit,
-    rect:   function(g,o,x,y) { return true; }, // bounds test is sufficient
-    image:  function(g,o,x,y) { return true; }, // bounds test is sufficient
-    rule:   function(g,o,x,y) {
-              if (!g.isPointInStroke) return false;
-              ruleStroke(g,o); return g.isPointInStroke(x,y);
-            },
-    line:   function(g,s,x,y) {
-              if (!g.isPointInStroke) return false;
-              lineStroke(g,s); return g.isPointInStroke(x,y);
-            },
-    arc:    function(g,o,x,y) { arcPath(g,o);  return g.isPointInPath(x,y); },
-    area:   function(g,s,x,y) { areaPath(g,s); return g.isPointInPath(x,y); },
-    path:   function(g,o,x,y) { pathPath(g,o); return g.isPointInPath(x,y); },
-    symbol: function(g,o,x,y) { symbolPath(g,o); return g.isPointInPath(x,y); }
-  };
-
-  return {
-    draw: {
-      group:   drawGroup,
-      area:    drawOne(areaPath),
-      line:    drawOne(linePath),
-      arc:     drawAll(arcPath),
-      path:    drawAll(pathPath),
-      symbol:  drawAll(symbolPath),
-      rect:    drawRect,
-      rule:    drawRule,
-      text:    drawText,
-      image:   drawImage,
-      drawOne: drawOne, // expose for extensibility
-      drawAll: drawAll  // expose for extensibility
-    },
-    pick: {
-      group:   pickGroup,
-      area:    pickArea,
-      line:    pickLine,
-      arc:     pick(hitTests.arc),
-      path:    pick(hitTests.path),
-      symbol:  pick(hitTests.symbol),
-      rect:    pick(hitTests.rect),
-      rule:    pick(hitTests.rule),
-      text:    pick(hitTests.text),
-      image:   pick(hitTests.image),
-      pickAll: pickAll  // expose for extensibility
-    }
-  };
-
-})();vg.canvas.Renderer = (function() {  
-  var renderer = function() {
-    this._ctx = null;
-    this._el = null;
-    this._imgload = 0;
-  };
-  
-  var prototype = renderer.prototype;
-  
-  prototype.initialize = function(el, width, height, pad) {
-    this._el = el;
-    
-    if (!el) return this; // early exit if no DOM element
-
-    // select canvas element
-    var canvas = d3.select(el)
-      .selectAll("canvas.marks")
-      .data([1]);
-    
-    // create new canvas element if needed
-    canvas.enter()
-      .append("canvas")
-      .attr("class", "marks");
-    
-    // remove extraneous canvas if needed
-    canvas.exit().remove();
-    
-    return this.resize(width, height, pad);
-  };
-  
-  prototype.resize = function(width, height, pad) {
-    this._width = width;
-    this._height = height;
-    this._padding = pad;
-    
-    if (this._el) {
-      var canvas = d3.select(this._el).select("canvas.marks");
-
-      // initialize canvas attributes
-      canvas
-        .attr("width", width + pad.left + pad.right)
-        .attr("height", height + pad.top + pad.bottom);
-
-      // get the canvas graphics context
-      var s;
-      this._ctx = canvas.node().getContext("2d");
-      this._ctx._ratio = (s = scaleCanvas(canvas.node(), this._ctx) || 1);
-      this._ctx.setTransform(s, 0, 0, s, s*pad.left, s*pad.top);
-    }
-    
-    initializeLineDash(this._ctx);
-    return this;
-  };
-  
-  function scaleCanvas(canvas, ctx) {
-    // get canvas pixel data
-    var devicePixelRatio = window.devicePixelRatio || 1,
-        backingStoreRatio = (
-          ctx.webkitBackingStorePixelRatio ||
-          ctx.mozBackingStorePixelRatio ||
-          ctx.msBackingStorePixelRatio ||
-          ctx.oBackingStorePixelRatio ||
-          ctx.backingStorePixelRatio) || 1,
-        ratio = devicePixelRatio / backingStoreRatio;
-
-    if (devicePixelRatio !== backingStoreRatio) {
-      var w = canvas.width, h = canvas.height;
-      // set actual and visible canvas size
-      canvas.setAttribute("width", w * ratio);
-      canvas.setAttribute("height", h * ratio);
-      canvas.style.width = w + 'px';
-      canvas.style.height = h + 'px';
-    }
-    return ratio;
-  }
-
-  function initializeLineDash(ctx) {
-    if (ctx.vgLineDash) return; // already set
-
-    var NODASH = [];
-    if (ctx.setLineDash) {
-      ctx.vgLineDash = function(dash) { this.setLineDash(dash || NODASH); };
-      ctx.vgLineDashOffset = function(off) { this.lineDashOffset = off; };
-    } else if (ctx.webkitLineDash !== undefined) {
-    	ctx.vgLineDash = function(dash) { this.webkitLineDash = dash || NODASH; };
-      ctx.vgLineDashOffset = function(off) { this.webkitLineDashOffset = off; };
-    } else if (ctx.mozDash !== undefined) {
-      ctx.vgLineDash = function(dash) { this.mozDash = dash; };
-      ctx.vgLineDashOffset = function(off) { /* unsupported */ };
-    } else {
-      ctx.vgLineDash = function(dash) { /* unsupported */ };
-      ctx.vgLineDashOffset = function(off) { /* unsupported */ };
-    }
-  }
-  
-  prototype.context = function(ctx) {
-    if (ctx) { this._ctx = ctx; return this; }
-    else return this._ctx;
-  };
-  
-  prototype.element = function() {
-    return this._el;
-  };
-  
-  prototype.pendingImages = function() {
-    return this._imgload;
-  };
-
-  function translatedBounds(item, bounds) {
-    var b = new vg.Bounds(bounds);
-    while ((item = item.mark.group) != null) {
-      b.translate(item.x || 0, item.y || 0);
-    }
-    return b;
-  }
-    
-  function getBounds(items) {
-    return !items ? null :
-      vg.array(items).reduce(function(b, item) {
-        return b.union(translatedBounds(item, item.bounds))
-                .union(translatedBounds(item, item['bounds:prev']));
-      }, new vg.Bounds());  
-  }
-  
-  function setBounds(g, bounds) {
-    var bbox = null;
-    if (bounds) {
-      bbox = (new vg.Bounds(bounds)).round();
-      g.beginPath();
-      g.rect(bbox.x1, bbox.y1, bbox.width(), bbox.height());
-      g.clip();
-    }
-    return bbox;
-  }
-  
-  prototype.render = function(scene, items) {
-    var g = this._ctx,
-        pad = this._padding,
-        w = this._width + pad.left + pad.right,
-        h = this._height + pad.top + pad.bottom,
-        bb = null, bb2;
-
-    // setup
-    this._scene = scene;
-    g.save();
-    bb = setBounds(g, getBounds(items));
-    g.clearRect(-pad.left, -pad.top, w, h);
-
-    // render
-    this.draw(g, scene, bb);
-
-    // render again to handle possible bounds change
-    if (items) {
-      g.restore();
-      g.save();
-      bb2 = setBounds(g, getBounds(items));
-      if (!bb.encloses(bb2)) {
-        g.clearRect(-pad.left, -pad.top, w, h);
-        this.draw(g, scene, bb2);
-      }
-    }
-    
-    // takedown
-    g.restore();
-    this._scene = null;
-  };
-  
-  prototype.draw = function(ctx, scene, bounds) {
-    var marktype = scene.marktype,
-        renderer = vg.canvas.marks.draw[marktype];
-    renderer.call(this, ctx, scene, bounds);
-
-    // compute mark-level bounds
-    scene.bounds = scene.items.reduce(function(b, item) {
-      return item.bounds ? b.union(item.bounds) : b;
-    }, scene.bounds || new vg.Bounds());
-  };
-  
-  prototype.renderAsync = function(scene) {
-    // TODO make safe for multiple scene rendering?
-    var renderer = this;
-    if (renderer._async_id) {
-      clearTimeout(renderer._async_id);
-    }
-    renderer._async_id = setTimeout(function() {
-      renderer.render(scene);
-      delete renderer._async_id;
-    }, 50);
-  };
-  
-  prototype.loadImage = function(uri) {
-    var renderer = this,
-        scene = renderer._scene,
-        image = null, url;
-
-    renderer._imgload += 1;
-    if (vg.config.isNode) {
-      image = new (require("canvas").Image)();
-      vg.data.load(uri, function(err, data) {
-        if (err) { vg.error(err); return; }
-        image.src = data;
-        image.loaded = true;
-        renderer._imgload -= 1;
-      });
-    } else {
-      image = new Image();
-      url = vg.config.baseURL + uri;
-      image.onload = function() {
-        vg.log("LOAD IMAGE: "+url);
-        image.loaded = true;
-        renderer._imgload -= 1;
-        renderer.renderAsync(scene);
-      };
-      image.src = url;
-    }
-
-    return image;
-  };
-  
-  return renderer;
-})();vg.canvas.Handler = (function() {
-  var handler = function(el, model) {
-    this._active = null;
-    this._handlers = {};
-    if (el) this.initialize(el);
-    if (model) this.model(model);
-  };
-  
-  var prototype = handler.prototype;
-
-  prototype.initialize = function(el, pad, obj) {
-    this._el = d3.select(el).node();
-    this._canvas = d3.select(el).select("canvas.marks").node();
-    this._padding = pad;
-    this._obj = obj || null;
-    
-    // add event listeners
-    var canvas = this._canvas, that = this;
-    events.forEach(function(type) {
-      canvas.addEventListener(type, function(evt) {
-        prototype[type].call(that, evt);
-      });
-    });
-    
-    return this;
-  };
-  
-  prototype.padding = function(pad) {
-    this._padding = pad;
-    return this;
-  };
-  
-  prototype.model = function(model) {
-    if (!arguments.length) return this._model;
-    this._model = model;
-    return this;
-  };
-
-  prototype.handlers = function() {
-    var h = this._handlers;
-    return vg.keys(h).reduce(function(a, k) {
-      return h[k].reduce(function(a, x) { return (a.push(x), a); }, a);
-    }, []);
-  };
-
-  // setup events
-  var events = [
-    "mousedown",
-    "mouseup",
-    "click",
-    "dblclick",
-    "wheel",
-    "keydown",
-    "keypress",
-    "keyup",
-    "mousewheel"
-  ];
-  events.forEach(function(type) {
-    prototype[type] = function(evt) {
-      this.fire(type, evt);
-    };
-  });
-  events.push("mousemove");
-  events.push("mouseout");
-
-  function eventName(name) {
-    var i = name.indexOf(".");
-    return i < 0 ? name : name.slice(0,i);
-  }
-
-  prototype.mousemove = function(evt) {
-    var pad = this._padding,
-        b = evt.target.getBoundingClientRect(),
-        x = evt.clientX - b.left,
-        y = evt.clientY - b.top,
-        a = this._active,
-        p = this.pick(this._model.scene(), x, y, x-pad.left, y-pad.top);
-
-    if (p === a) {
-      this.fire("mousemove", evt);
-      return;
-    } else if (a) {
-      this.fire("mouseout", evt);
-    }
-    this._active = p;
-    if (p) {
-      this.fire("mouseover", evt);
-    }
-  };
-  
-  prototype.mouseout = function(evt) {
-    if (this._active) {
-      this.fire("mouseout", evt);
-    }
-    this._active = null;
-  };
-
-  // to keep firefox happy
-  prototype.DOMMouseScroll = function(evt) {
-    this.fire("mousewheel", evt);
-  };
-
-  // fire an event
-  prototype.fire = function(type, evt) {
-    var a = this._active,
-        h = this._handlers[type];
-    if (a && h) {
-      for (var i=0, len=h.length; i<len; ++i) {
-        h[i].handler.call(this._obj, evt, a);
-      }
-    }
-  };
-
-  // add an event handler
-  prototype.on = function(type, handler) {
-    var name = eventName(type),
-        h = this._handlers;
-    h = h[name] || (h[name] = []);
-    h.push({
-      type: type,
-      handler: handler
-    });
-    return this;
-  };
-
-  // remove an event handler
-  prototype.off = function(type, handler) {
-    var name = eventName(type),
-        h = this._handlers[name];
-    if (!h) return;
-    for (var i=h.length; --i>=0;) {
-      if (h[i].type !== type) continue;
-      if (!handler || h[i].handler === handler) h.splice(i, 1);
-    }
-    return this;
-  };
-  
-  // retrieve the current canvas context
-  prototype.context = function() {
-    return this._canvas.getContext("2d");
-  };
-  
-  // find the scenegraph item at the current mouse position
-  // returns an array of scenegraph items, from leaf node up to the root
-  // x, y -- the absolute x, y mouse coordinates on the canvas element
-  // gx, gy -- the relative coordinates within the current group
-  prototype.pick = function(scene, x, y, gx, gy) {
-    var g = this.context(),
-        marktype = scene.marktype,
-        picker = vg.canvas.marks.pick[marktype];
-    return picker.call(this, g, scene, x, y, gx, gy);
-  };
-
-  return handler;
-})();vg.svg = {};vg.svg.marks = (function() {
-
-  function x(o)     { return o.x || 0; }
-  function y(o)     { return o.y || 0; }
-  function yh(o)    { return o.y + o.height || 0; }
-  function key(o)   { return o.key; }
-  function size(o)  { return o.size==null ? 100 : o.size; }
-  function shape(o) { return o.shape || "circle"; }
-      
-  var arc_path    = d3.svg.arc(),
-      area_path   = d3.svg.area().x(x).y1(y).y0(yh),
-      line_path   = d3.svg.line().x(x).y(y),
-      symbol_path = d3.svg.symbol().type(shape).size(size);
-  
-  var mark_id = 0;
-  
-  var textAlign = {
-    "left":   "start",
-    "center": "middle",
-    "right":  "end"
-  };
-  
-  var styles = {
-    "fill":             "fill",
-    "fillOpacity":      "fill-opacity",
-    "stroke":           "stroke",
-    "strokeWidth":      "stroke-width",
-    "strokeOpacity":    "stroke-opacity",
-    "strokeCap":        "stroke-linecap",
-    "strokeDash":       "stroke-dasharray",
-    "strokeDashOffset": "stroke-dashoffset",
-    "opacity":          "opacity"
-  };
-  var styleProps = vg.keys(styles);
-
-  function style(d) {
-    var i, n, prop, name, value,
-        o = d.mark ? d : d.length ? d[0] : null;
-    if (o === null) return;
-
-    for (i=0, n=styleProps.length; i<n; ++i) {
-      prop = styleProps[i];
-      name = styles[prop];
-      value = o[prop];
-
-      if (value == null) {
-        if (name === "fill") this.style.setProperty(name, "none", null);
-        else this.style.removeProperty(name);
-      } else {
-        if (value.id) {
-          // ensure definition is included
-          vg.svg._cur._defs[value.id] = value;
-          value = "url(#" + value.id + ")";
-        }
-        this.style.setProperty(name, value+"", null);
-      }
-    }
-  }
-  
-  function arc(o) {
-    var x = o.x || 0,
-        y = o.y || 0;
-    this.setAttribute("transform", "translate("+x+","+y+")");
-    this.setAttribute("d", arc_path(o));
-  }
-  
-  function area(items) {
-    if (!items.length) return;
-    var o = items[0];
-    area_path
-      .interpolate(o.interpolate || "linear")
-      .tension(o.tension == null ? 0.7 : o.tension);
-    this.setAttribute("d", area_path(items));
-  }
-  
-  function line(items) {
-    if (!items.length) return;
-    var o = items[0];
-    line_path
-      .interpolate(o.interpolate || "linear")
-      .tension(o.tension == null ? 0.7 : o.tension);
-    this.setAttribute("d", line_path(items));
-  }
-  
-  function path(o) {
-    var x = o.x || 0,
-        y = o.y || 0;
-    this.setAttribute("transform", "translate("+x+","+y+")");
-    if (o.path != null) this.setAttribute("d", o.path);
-  }
-
-  function rect(o) {
-    this.setAttribute("x", o.x || 0);
-    this.setAttribute("y", o.y || 0);
-    this.setAttribute("width", o.width || 0);
-    this.setAttribute("height", o.height || 0);
-  }
-
-  function rule(o) {
-    var x1 = o.x || 0,
-        y1 = o.y || 0;
-    this.setAttribute("x1", x1);
-    this.setAttribute("y1", y1);
-    this.setAttribute("x2", o.x2 != null ? o.x2 : x1);
-    this.setAttribute("y2", o.y2 != null ? o.y2 : y1);
-  }
-  
-  function symbol(o) {
-    var x = o.x || 0,
-        y = o.y || 0;
-    this.setAttribute("transform", "translate("+x+","+y+")");
-    this.setAttribute("d", symbol_path(o));
-  }
-  
-  function image(o) {
-    var w = o.width || (o.image && o.image.width) || 0,
-        h = o.height || (o.image && o.image.height) || 0,
-        x = o.x - (o.align === "center"
-          ? w/2 : (o.align === "right" ? w : 0)),
-        y = o.y - (o.baseline === "middle"
-          ? h/2 : (o.baseline === "bottom" ? h : 0)),
-        url = vg.config.baseURL + o.url;
-    
-    this.setAttributeNS("http://www.w3.org/1999/xlink", "href", url);
-    this.setAttribute("x", x);
-    this.setAttribute("y", y);
-    this.setAttribute("width", w);
-    this.setAttribute("height", h);
-  }
-    
-  function fontString(o) {
-    return (o.fontStyle ? o.fontStyle + " " : "")
-      + (o.fontVariant ? o.fontVariant + " " : "")
-      + (o.fontWeight ? o.fontWeight + " " : "")
-      + (o.fontSize != null ? o.fontSize : vg.config.render.fontSize) + "px "
-      + (o.font || vg.config.render.font);
-  }
-  
-  function text(o) {
-    var x = o.x || 0,
-        y = o.y || 0,
-        dx = o.dx || 0,
-        dy = o.dy || 0,
-        a = o.angle || 0,
-        align = textAlign[o.align || "left"],
-        base = o.baseline==="top" ? ".9em"
-             : o.baseline==="middle" ? ".35em" : 0;
-  
-    this.setAttribute("x", x + dx);
-    this.setAttribute("y", y + dy);
-    this.setAttribute("dy", dy);
-    this.setAttribute("text-anchor", align);
-    
-    if (a) this.setAttribute("transform", "rotate("+a+" "+x+","+y+")");
-    else this.removeAttribute("transform");
-    
-    if (base) this.setAttribute("dy", base);
-    else this.removeAttribute("dy");
-    
-    this.textContent = o.text;
-    this.style.setProperty("font", fontString(o), null);
-  }
-  
-  function group(o) {
-    var x = o.x || 0,
-        y = o.y || 0;
-    this.setAttribute("transform", "translate("+x+","+y+")");
-  }
-
-  function group_bg(o) {
-    var w = o.width || 0,
-        h = o.height || 0;
-    this.setAttribute("width", w);
-    this.setAttribute("height", h);
-  }
-
-  function draw(tag, attr, nest) {
-    return function(g, scene, index) {
-      drawMark(g, scene, index, "mark_", tag, attr, nest);
-    };
-  }
-  
-  function drawMark(g, scene, index, prefix, tag, attr, nest) {
-    var data = nest ? [scene.items] : scene.items,
-        evts = scene.interactive===false ? "none" : null,
-        grps = g.node().childNodes,
-        notG = (tag !== "g"),
-        p = (p = grps[index+1]) // +1 to skip group background rect
-          ? d3.select(p)
-          : g.append("g").attr("id", "g"+(++mark_id));
-
-    var id = "#" + p.attr("id"),
-        s = id + " > " + tag,
-        m = p.selectAll(s).data(data),
-        e = m.enter().append(tag);
-
-    if (notG) {
-      p.style("pointer-events", evts);
-      e.each(function(d) {
-        if (d.mark) d._svg = this;
-        else if (d.length) d[0]._svg = this;
-      });
-    } else {
-      e.append("rect").attr("class","background").style("pointer-events",evts);
-    }
-    
-    m.exit().remove();
-    m.each(attr);
-    if (notG) m.each(style);
-    else p.selectAll(s+" > rect.background").each(group_bg).each(style);
-    
-    return p;
-  }
-
-  function drawGroup(g, scene, index, prefix) {    
-    var p = drawMark(g, scene, index, prefix || "group_", "g", group),
-        c = p.node().childNodes, n = c.length, i, j, m;
-    
-    for (i=0; i<n; ++i) {
-      var items = c[i].__data__.items,
-          legends = c[i].__data__.legendItems || [],
-          axes = c[i].__data__.axisItems || [],
-          sel = d3.select(c[i]),
-          idx = 0;
-
-      for (j=0, m=axes.length; j<m; ++j) {
-        if (axes[j].def.layer === "back") {
-          drawGroup.call(this, sel, axes[j], idx++, "axis_");
-        }
-      }
-      for (j=0, m=items.length; j<m; ++j) {
-        this.draw(sel, items[j], idx++);
-      }
-      for (j=0, m=axes.length; j<m; ++j) {
-        if (axes[j].def.layer !== "back") {
-          drawGroup.call(this, sel, axes[j], idx++, "axis_");
-        }
-      }
-      for (j=0, m=legends.length; j<m; ++j) {
-        drawGroup.call(this, sel, legends[j], idx++, "legend_");
-      }
-    }
-  }
-
-  return {
-    update: {
-      group:   rect,
-      area:    area,
-      line:    line,
-      arc:     arc,
-      path:    path,
-      symbol:  symbol,
-      rect:    rect,
-      rule:    rule,
-      text:    text,
-      image:   image
-    },
-    nested: {
-      "area": true,
-      "line": true
-    },
-    style: style,
-    draw: {
-      group:   drawGroup,
-      area:    draw("path", area, true),
-      line:    draw("path", line, true),
-      arc:     draw("path", arc),
-      path:    draw("path", path),
-      symbol:  draw("path", symbol),
-      rect:    draw("rect", rect),
-      rule:    draw("line", rule),
-      text:    draw("text", text),
-      image:   draw("image", image),
-      draw:    draw // expose for extensibility
-    }
-  };
-  
-})();vg.svg.Renderer = (function() {  
-  var renderer = function() {
-    this._svg = null;
-    this._ctx = null;
-    this._el = null;
-    this._defs = {};
-  };
-  
-  var prototype = renderer.prototype;
-  
-  prototype.initialize = function(el, width, height, pad) {
-    this._el = el;
-
-    // remove any existing svg element
-    d3.select(el).select("svg.marks").remove();
-
-    // create svg element and initialize attributes
-    this._svg = d3.select(el)
-      .append("svg")
-      .attr("class", "marks");
-    
-    // set the svg root group
-    this._ctx = this._svg.append("g");
-    
-    return this.resize(width, height, pad);
-  };
-  
-  prototype.resize = function(width, height, pad) {
-    this._width = width;
-    this._height = height;
-    this._padding = pad;
-    
-    this._svg
-      .attr("width", width + pad.left + pad.right)
-      .attr("height", height + pad.top + pad.bottom);
-      
-    this._ctx
-      .attr("transform", "translate("+pad.left+","+pad.top+")");
-
-    return this;
-  };
-  
-  prototype.context = function() {
-    return this._ctx;
-  };
-  
-  prototype.element = function() {
-    return this._el;
-  };
-
-  prototype.updateDefs = function() {
-    var svg = this._svg,
-        all = this._defs,
-        ids = vg.keys(all),
-        defs = svg.select("defs"), grds;
-  
-    // get or create svg defs block
-    if (ids.length===0) { defs.remove(); return; }
-    if (defs.empty()) defs = svg.insert("defs", ":first-child");
-    
-    grds = defs.selectAll("linearGradient").data(ids, vg.identity);
-    grds.enter().append("linearGradient").attr("id", vg.identity);
-    grds.exit().remove();
-    grds.each(function(id) {
-      var def = all[id],
-          grd = d3.select(this);
-  
-      // set gradient coordinates
-      grd.attr({x1: def.x1, x2: def.x2, y1: def.y1, y2: def.y2});
-  
-      // set gradient stops
-      stop = grd.selectAll("stop").data(def.stops);
-      stop.enter().append("stop");
-      stop.exit().remove();
-      stop.attr("offset", function(d) { return d.offset; })
-          .attr("stop-color", function(d) { return d.color; });
-    });
-  };
-  
-  prototype.render = function(scene, items) {
-    vg.svg._cur = this;
-
-    if (items) this.renderItems(vg.array(items));
-    else this.draw(this._ctx, scene, -1);
-    this.updateDefs();
-
-   delete vg.svg._cur;
-  };
-  
-  prototype.renderItems = function(items) {
-    var item, node, type, nest, i, n,
-        marks = vg.svg.marks;
-
-    for (i=0, n=items.length; i<n; ++i) {
-      item = items[i];
-      node = item._svg;
-      type = item.mark.marktype;
-
-      item = marks.nested[type] ? item.mark.items : item;
-      marks.update[type].call(node, item);
-      marks.style.call(node, item);
-    }
-  }
-  
-  prototype.draw = function(ctx, scene, index) {
-    var marktype = scene.marktype,
-        renderer = vg.svg.marks.draw[marktype];
-    renderer.call(this, ctx, scene, index);
-  };
-  
-  return renderer;
-})();vg.svg.Handler = (function() {
-  var handler = function(el, model) {
-    this._active = null;
-    this._handlers = {};
-    if (el) this.initialize(el);
-    if (model) this.model(model);
-  };
-  
-  function svgHandler(handler) {
-    var that = this;
-    return function(evt) {
-      var target = evt.target,
-          item = target.__data__;
-      if (item) {
-        item = item.mark ? item : item[0];
-        handler.call(that._obj, evt, item);
-      }
-    };
-  }
-  
-  function eventName(name) {
-    var i = name.indexOf(".");
-    return i < 0 ? name : name.slice(0,i);
-  }
-  
-  var prototype = handler.prototype;
-
-  prototype.initialize = function(el, pad, obj) {
-    this._el = d3.select(el).node();
-    this._svg = d3.select(el).select("svg.marks").node();
-    this._padding = pad;
-    this._obj = obj || null;
-    return this;
-  };
-  
-  prototype.padding = function(pad) {
-    this._padding = pad;
-    return this;
-  };
-  
-  prototype.model = function(model) {
-    if (!arguments.length) return this._model;
-    this._model = model;
-    return this;
-  };
-  
-  prototype.handlers = function() {
-    var h = this._handlers;
-    return vg.keys(h).reduce(function(a, k) {
-      return h[k].reduce(function(a, x) { return (a.push(x), a); }, a);
-    }, []);
-  };
-
-  // add an event handler
-  prototype.on = function(type, handler) {
-    var name = eventName(type),
-        h = this._handlers,
-        dom = d3.select(this._svg).node();
-        
-    var x = {
-      type: type,
-      handler: handler,
-      svg: svgHandler.call(this, handler)
-    };
-    h = h[name] || (h[name] = []);
-    h.push(x);
-
-    dom.addEventListener(name, x.svg);
-    return this;
-  };
-
-  // remove an event handler
-  prototype.off = function(type, handler) {
-    var name = eventName(type),
-        h = this._handlers[name],
-        dom = d3.select(this._svg).node();
-    if (!h) return;
-    for (var i=h.length; --i>=0;) {
-      if (h[i].type !== type) continue;
-      if (!handler || h[i].handler === handler) {
-        dom.removeEventListener(name, h[i].svg);
-        h.splice(i, 1);
-      }
-    }
-    return this;
-  };
-
-  return handler;
-})();vg.data = {};
-
-vg.data.ingestAll = function(data) {
-  return vg.isTree(data)
-    ? vg_make_tree(vg.data.ingestTree(data[0], data.children))
-    : data.map(vg.data.ingest);
-};
-
-vg.data.ingest = function(datum, index) {
-  return {
-    data: datum,
-    index: index
-  };
-};
-
-vg.data.ingestTree = function(node, children) {
-  var d = vg.data.ingest(node),
-      c = node[children], n, i;
-  if (c && (n = c.length)) {
-    d.values = Array(n);
-    for (i=0; i<n; ++i) {
-      d.values[i] = vg.data.ingestTree(c[i], children);
-    }
-  }
-  return d;
-};
-
-
-function vg_make_tree(d) {
-  d.__vgtree__ = true;
-  d.nodes = function() { return vg_tree_nodes(this, []); };
-  return d;
-}
-
-function vg_tree_nodes(root, nodes) {
-  var c = root.values,
-      n = c ? c.length : 0, i;
-  nodes.push(root);
-  for (i=0; i<n; ++i) { vg_tree_nodes(c[i], nodes); }
-  return nodes;
-}
-
-function vg_data_duplicate(d) {
-  var x=d, i, n;
-  if (vg.isArray(d)) {
-    x = [];
-    for (i=0, n=d.length; i<n; ++i) {
-      x.push(vg_data_duplicate(d[i]));
-    }
-  } else if (vg.isObject(d)) {
-    x = {};
-    for (i in d) {
-      x[i] = vg_data_duplicate(d[i]);
-    }
-  }
-  return x;
-}
-
-vg.data.mapper = function(func) {
-  return function(data) {
-    data.forEach(func);
-    return data;
-  }
-};
-
-vg.data.size = function(size, group) {
-  size = vg.isArray(size) ? size : [0, size];
-  size = size.map(function(d) {
-    return (typeof d === 'string') ? group[d] : d;
-  });
-  return size;
-};vg.data.load = function(uri, callback) {
-  var url = vg_load_hasProtocol(uri) ? uri : vg.config.baseURL + uri;
-  if (vg.config.isNode) {
-    // in node.js, consult url and select file or http
-    var get = vg_load_isFile(url) ? vg_load_file : vg_load_http;
-    get(url, callback);
-  } else {
-    // in browser, use xhr
-    vg_load_xhr(url, callback);
-  }  
-};
-
-var vg_load_protocolRE = /^[A-Za-z]+\:\/\//;
-var vg_load_fileProtocol = "file://";
-
-function vg_load_hasProtocol(url) {
-  return vg_load_protocolRE.test(url);
-}
-
-function vg_load_isFile(url) {
-  return url.indexOf(vg_load_fileProtocol) === 0;
-}
-
-function vg_load_xhr(url, callback) {
-  vg.log("LOAD: " + url);
-  d3.xhr(url, function(err, resp) {
-    if (resp) resp = resp.responseText;
-    callback(err, resp);
-  });
-}
-
-function vg_load_file(file, callback) {
-  vg.log("LOAD FILE: " + file);
-  var idx = file.indexOf(vg_load_fileProtocol);
-  if (idx >= 0) file = file.slice(vg_load_fileProtocol.length);
-  require("fs").readFile(file, callback);
-}
-
-function vg_load_http(url, callback) {
-  vg.log("LOAD HTTP: " + url);
-	var req = require("http").request(url, function(res) {
-    var pos=0, data = new Buffer(parseInt(res.headers['content-length'],10));
-		res.on("error", function(err) { callback(err, null); });
-		res.on("data", function(x) { x.copy(data, pos); pos += x.length; });
-		res.on("end", function() { callback(null, data); });
-	});
-	req.on("error", function(err) { callback(err); });
-	req.end();
-}vg.data.read = (function() {
-  var formats = {},
-      parsers = {
-        "number": vg.number,
-        "boolean": vg.boolean,
-        "date": Date.parse
-      };
-
-  function read(data, format) {
-    var type = (format && format.type) || "json";
-    data = formats[type](data, format);
-    if (format && format.parse) parseValues(data, format.parse);
-    return data;
-  }
-
-  formats.json = function(data, format) {
-    var d = JSON.parse(data);
-    if (format && format.property) {
-      d = vg.accessor(format.property)(d);
-    }
-    return d;
-  };
-
-  formats.csv = function(data, format) {
-    var d = d3.csv.parse(data);
-    return d;
-  };
-
-  formats.tsv = function(data, format) {
-    var d = d3.tsv.parse(data);
-    return d;
-  };
-  
-  formats.topojson = function(data, format) {
-    if (topojson == null) {
-      vg.error("TopoJSON library not loaded.");
-      return [];
-    }    
-    var t = JSON.parse(data), obj = [];
-
-    if (format && format.feature) {
-      obj = (obj = t.objects[format.feature])
-        ? topojson.feature(t, obj).features
-        : (vg.error("Invalid TopoJSON object: "+format.feature), []);
-    } else if (format && format.mesh) {
-      obj = (obj = t.objects[format.mesh])
-        ? [topojson.mesh(t, t.objects[format.mesh])]
-        : (vg.error("Invalid TopoJSON object: " + format.mesh), []);
-    }
-    else { vg.error("Missing TopoJSON feature or mesh parameter."); }
-
-    return obj;
-  };
-  
-  formats.treejson = function(data, format) {
-    var d = [JSON.parse(data)];
-    d.__vgtree__ = true;
-    d.children = format.children || "children";
-    return d;
-  };
-  
-  function parseValues(data, types) {
-    var cols = vg.keys(types),
-        p = cols.map(function(col) { return parsers[types[col]]; }),
-        tree = vg.isTree(data);
-    vg_parseArray(tree ? [data] : data, cols, p, tree);
-  }
-  
-  function vg_parseArray(data, cols, p, tree) {
-    var d, i, j, len, clen;
-    for (i=0, len=data.length; i<len; ++i) {
-      d = data[i];
-      for (j=0, clen=cols.length; j<clen; ++j) {
-        d[cols[j]] = p[j](d[cols[j]]);
-      }
-      if (tree && d.values) parseCollection(d, cols, p, true);
-    }
-  }
-
-  read.formats = formats;
-  read.parse = parseValues;
-  return read;
-})();vg.data.array = function() {
-  var fields = [];
-   
-  function array(data) {
-    return data.map(function(d) {      
-      var list = [];
-      for (var i=0, len=fields.length; i<len; ++i) {
-        list.push(fields[i](d));
-      }
-      return list;
-    });
-  }
-  
-  array.fields = function(fieldList) {
-    fields = vg.array(fieldList).map(vg.accessor);
-    return array;
-  };
-  
-  return array;
-};vg.data.copy = function() {
-  var from = vg.accessor("data"),
-      fields = [],
-      as = null;
-  
-  var copy = vg.data.mapper(function(d) {
-    var src = from(d), i, len,
-        source = fields,
-        target = as || fields;
-    for (i=0, len=fields.length; i<len; ++i) {
-      d[target[i]] = src[fields[i]];
-    }
-    return d;
-  });
-
-  copy.from = function(field) {
-    from = vg.accessor(field);
-    return copy;
-  };
-  
-  copy.fields = function(fieldList) {
-    fields = vg.array(fieldList);
-    return copy;
-  };
-  
-  copy.as = function(fieldList) {
-    as = vg.array(fieldList);
-    return copy;
-  };
-
-  return copy;
-};vg.data.cross = function() {
-  var other = null,
-      nodiag = false,
-      output = {left:"a", right:"b"};
-
-  function cross(data) {
-    var result = [],
-        data2 = other || data,
-        o, i, j, n = data.length;
-
-    for (i=0; i<n; ++i) {
-      for (j=0; j<n; ++j) {
-        if (nodiag && i===j) continue;
-        o = {};
-        o[output.left] = data[i];
-        o[output.right] = data2[j];
-        result.push(o);
-      }
-    }
-    return result;
-  }
-
-  cross["with"] = function(d) {
-    other = d;
-    return cross;
-  };
-  
-  cross.diagonal = function(x) {
-    nodiag = !x;
-    return cross;
-  };
-
-  cross.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) { output[k] = map[k]; }
-    });
-    return cross;
-  };
-
-  return cross;
-};
-vg.data.facet = function() {
-
-  var keys = [],
-      sort = null;
-
-  function facet(data) {    
-    var result = {
-          key: "",
-          keys: [],
-          values: []
-        },
-        map = {}, 
-        vals = result.values,
-        obj, klist, kstr, len, i, j, k, kv, cmp;
-
-    if (keys.length === 0) {
-      // if no keys, skip collation step
-      vals.push(obj = {
-        key: "", keys: [], index: 0,
-        values: sort ? data.slice() : data
-      });
-      if (sort) sort(obj.values);
-      return result;
-    }
-
-    for (i=0, len=data.length; i<len; ++i) {
-      for (k=0, klist=[], kstr=""; k<keys.length; ++k) {
-        kv = keys[k](data[i]);
-        klist.push(kv);
-        kstr += (k>0 ? "|" : "") + String(kv);
-      }
-      obj = map[kstr];
-      if (obj === undefined) {
-        vals.push(obj = map[kstr] = {
-          key: kstr,
-          keys: klist,
-          index: vals.length,
-          values: []
-        });
-      }
-      obj.values.push(data[i]);
-    }
-
-    if (sort) {
-      for (i=0, len=vals.length; i<len; ++i) {
-        sort(vals[i].values);
-      }
-    }
-
-    return result;
-  }
-  
-  facet.keys = function(k) {
-    keys = vg.array(k).map(vg.accessor);
-    return facet;
-  };
-  
-  facet.sort = function(s) {
-    sort = vg.data.sort().by(s);
-    return facet;
-  };
-
-  return facet;
-};vg.data.filter = function() {
-
-  var test = null;
-
-  function filter(data) {
-    return test ? data.filter(test) : data;
-  }
-  
-  filter.test = function(func) {
-    test = vg.isFunction(func) ? func : vg.parse.expr(func);
-    return filter;
-  };
-
-  return filter;
-};vg.data.flatten = function() {
-    
-  function flatten(data) {
-    return flat(data, []);
-  }
-  
-  function flat(data, list) {
-    if (data.values) {
-      for (var i=0, n=data.values.length; i<n; ++i) {
-        flat(data.values[i], list);
-      }
-    } else {
-      list.push(data);
-    }
-    return list;
-  }
-  
-  return flatten;
-};vg.data.fold = function() {
-  var fields = [],
-      accessors = [],
-      output = {
-        key: "key",
-        value: "value"
-      };
-
-  function fold(data) {
-    var values = [],
-        item, i, j, n, m = fields.length;
-
-    for (i=0, n=data.length; i<n; ++i) {
-      item = data[i];
-      for (j=0; j<m; ++j) {
-        var o = {
-          index: values.length,
-          data: item.data
-        };
-        o[output.key] = fields[j];
-        o[output.value] = accessors[j](item);
-        values.push(o);
-      }
-    }
-
-    return values;
-  }  
-
-  fold.fields = function(f) {
-    fields = vg.array(f);
-    accessors = fields.map(vg.accessor);
-    return fold;
-  };
-
-  fold.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return fold;
-  };
-
-  return fold;
-};vg.data.force = function() {
-  var layout = d3.layout.force(),
-      links = null,
-      linkDistance = 20,
-      linkStrength = 1,
-      charge = -30,
-      iterations = 500,
-      size = ["width", "height"],
-      params = [
-        "friction",
-        "theta",
-        "gravity",
-        "alpha"
-      ];
-
-  function force(data, db, group) {    
-    layout
-      .size(vg.data.size(size, group))
-      .nodes(data);
-      
-    if (links && db[links]) {
-      layout.links(db[links]);
-    }
-
-    layout.start();      
-    for (var i=0; i<iterations; ++i) {
-      layout.tick();
-    }
-    layout.stop();
-    
-    return data;
-  }
-
-  force.links = function(dataSetName) {
-    links = dataSetName;
-    return force;
-  };
-  
-  force.size = function(sz) {
-    size = sz;
-    return force;
-  };
-       
-  force.linkDistance = function(field) {
-    linkDistance = typeof field === 'number'
-      ? field
-      : vg.accessor(field);
-    layout.linkDistance(linkDistance);
-    return force;
-  };
-
-  force.linkStrength = function(field) {
-    linkStrength = typeof field === 'number'
-      ? field
-      : vg.accessor(field);
-    layout.linkStrength(linkStrength);
-    return force;
-  };
-  
-  force.charge = function(field) {
-    charge = typeof field === 'number'
-      ? field
-      : vg.accessor(field);
-    layout.charge(charge);
-    return force;
-  };
-  
-  force.iterations = function(iter) {
-    iterations = iter;
-    return force;
-  };
-
-  params.forEach(function(name) {
-    force[name] = function(x) {
-      layout[name](x);
-      return force;
-    }
-  });
-
-  return force;
-};vg.data.formula = (function() {
-  
-  return function() {
-    var field = null,
-        expr = vg.identity;
-  
-    var formula = vg.data.mapper(function(d, i, list) {
-      if (field) d[field] = expr.call(null, d, i, list);
-      return d;
-    });
-
-    formula.field = function(name) {
-      field = name;
-      return formula;
-    };
-  
-    formula.expr = function(func) {
-      expr = vg.isFunction(func) ? func : vg.parse.expr(func);
-      return formula;
-    };
-
-    return formula;
-  };
-})();vg.data.geo = (function() {
-  var params = [
-    "center",
-    "scale",
-    "translate",
-    "rotate",
-    "precision",
-    "clipAngle"
-  ];
-
-  function geo() {
-    var opt = {},
-        projection = "mercator",
-        func = d3.geo[projection](),
-        lat = vg.identity,
-        lon = vg.identity,
-        output = {
-          "x": "x",
-          "y": "y"
-        };
-    
-    var map = vg.data.mapper(function(d) {
-      var ll = [lon(d), lat(d)],
-          xy = func(ll);
-      d[output.x] = xy[0];
-      d[output.y] = xy[1];
-      return d;
-    });
-
-    map.func = function() {
-      return func;
-    };
-        
-    map.projection = function(p) {
-      if (projection !== p) {
-        projection = p;
-        func = d3.geo[projection]();
-        for (var name in opt) {
-          func[name](opt[name]);
-        }
-      }
-      return map;
-    };
-
-    params.forEach(function(name) {
-      map[name] = function(x) {
-        opt[name] = x;
-        func[name](x);
-        return map;
-      }
-    });
-    
-    map.lon = function(field) {
-      lon = vg.accessor(field);
-      return map;
-    };
-
-    map.lat = function(field) {
-      lat = vg.accessor(field);
-      return map;
-    };
-    
-    map.output = function(map) {
-      vg.keys(output).forEach(function(k) {
-        if (map[k] !== undefined) {
-          output[k] = map[k];
-        }
-      });
-      return map;
-    };
-    
-    
-    return map;
-  };
-  
-  geo.params = params;
-  return geo;
-})();vg.data.geopath = function() {
-  var geopath = d3.geo.path().projection(d3.geo.mercator()),
-      projection = "mercator",
-      geojson = vg.identity,
-      opt = {},
-      output = {"path": "path"};
-
-  var map = vg.data.mapper(function(d) {
-    d[output.path] = geopath(geojson(d));
-    return d;
-  });
-  
-  map.projection = function(proj) {
-    if (projection !== proj) {
-      projection = proj;
-      var p = d3.geo[projection]();
-      for (var name in opt) {
-        p[name](opt[name]);
-      }
-      geopath.projection(p);
-    }
-    return map;
-  };
-  
-  vg.data.geo.params.forEach(function(name) {
-    map[name] = function(x) {
-      opt[name] = x;
-      (geopath.projection())[name](x);
-      return map;
-    }
-  });
-   
-  map.value = function(field) {
-    geojson = vg.accessor(field);
-    return map;
-  };
-
-  map.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return map;
-  };
-
-  return map;
-};vg.data.link = function() {
-  var shape = "line",
-      source = vg.accessor("source"),
-      target = vg.accessor("target"),
-      tension = 0.2,
-      output = {"path": "path"};
-  
-  function line(d) {
-    var s = source(d),
-        t = target(d);
-    return "M" + s.x + "," + s.y 
-         + "L" + t.x + "," + t.y;
-  }
-
-  function curve(d) {
-    var s = source(d),
-        t = target(d),
-        dx = t.x - s.x,
-        dy = t.y - s.y,
-        ix = tension * (dx + dy),
-        iy = tension * (dy - dx);
-    return "M" + s.x + "," + s.y
-         + "C" + (s.x+ix) + "," + (s.y+iy)
-         + " " + (t.x+iy) + "," + (t.y-ix)
-         + " " + t.x + "," + t.y;
-  }
-  
-  function diagonalX(d) {
-    var s = source(d),
-        t = target(d),
-        m = (s.x + t.x) / 2;
-    return "M" + s.x + "," + s.y
-         + "C" + m   + "," + s.y
-         + " " + m   + "," + t.y
-         + " " + t.x + "," + t.y;
-  }
-
-  function diagonalY(d) {
-    var s = source(d),
-        t = target(d),
-        m = (s.y + t.y) / 2;
-    return "M" + s.x + "," + s.y
-         + "C" + s.x + "," + m
-         + " " + t.x + "," + m
-         + " " + t.x + "," + t.y;
-  }
-
-  var shapes = {
-    line:      line,
-    curve:     curve,
-    diagonal:  diagonalX,
-    diagonalX: diagonalX,
-    diagonalY: diagonalY
-  };
-  
-  function link(data) {
-    var path = shapes[shape];
-        
-    data.forEach(function(d) {
-      d[output.path] = path(d);
-    });
-    
-    return data;
-  }
-
-  link.shape = function(val) {
-    shape = val;
-    return link;
-  };
-
-  link.tension = function(val) {
-    tension = val;
-    return link;
-  };
-  
-  link.source = function(field) {
-    source = vg.accessor(field);
-    return link;
-  };
-  
-  link.target = function(field) {
-    target = vg.accessor(field);
-    return link;
-  };
-  
-  link.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return link;
-  };
-  
-  return link;
-};vg.data.pie = function() {
-  var one = function() { return 1; },
-      value = one,
-      start = 0,
-      end = 2 * Math.PI,
-      sort = false,
-      output = {
-        "startAngle": "startAngle",
-        "endAngle": "endAngle"
-      };
-
-  function pie(data) {
-    var values = data.map(function(d, i) { return +value(d); }),
-        a = start,
-        k = (end - start) / d3.sum(values),
-        index = d3.range(data.length);
-    
-    if (sort) {
-      index.sort(function(a, b) {
-        return values[a] - values[b];
-      });
-    }
-    
-    index.forEach(function(i) {
-      var d;
-      data[i].value = (d = values[i]);
-      data[i][output.startAngle] = a;
-      data[i][output.endAngle] = (a += d * k);
-    });
-    
-    return data;
-  }
-
-  pie.sort = function(b) {
-    sort = b;
-    return pie;
-  };
-       
-  pie.value = function(field) {
-    value = field ? vg.accessor(field) : one;
-    return pie;
-  };
-  
-  pie.startAngle = function(startAngle) {
-    start = Math.PI * startAngle / 180;
-    return pie;
-  };
-  
-  pie.endAngle = function(endAngle) {
-    end = Math.PI * endAngle / 180;
-    return pie;
-  };
-
-  pie.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return pie;
-  };
-
-  return pie;
-};vg.data.slice = function() {
-  var by = null,
-      field = vg.accessor("data");
-
-  function slice(data) {
-    data = vg.values(data);
-    
-    if (by === "min") {
-      data = [data[vg.minIndex(data, field)]];
-    } else if (by === "max") {
-      data = [data[vg.maxIndex(data, field)]];
-    } else if (by === "median") {
-      var list = data.slice().sort(function(a,b) {
-        a = field(a); b = field(b);
-        return a < b ? -1 : a > b ? 1 : 0;
-      });
-      data = [data[~~(list.length/2)]];
-    } else {
-      var idx = vg.array(by);
-      data = data.slice(idx[0], idx[1]);
-    }
-    return data;
-  }
-  
-  slice.by = function(x) {
-    by = x;
-    return slice;
-  };
-  
-  slice.field = function(f) {
-    field = vg.accessor(f);
-    return slice;
-  };
-
-  return slice;
-};vg.data.sort = function() {
-  var by = null;
-
-  function sort(data) {
-    data = (vg.isArray(data) ? data : data.values || []);
-    data.sort(by);
-    for (var i=0, n=data.length; i<n; ++i) data[i].index = i; // re-index
-    return data;
-  }
-  
-  sort.by = function(s) {
-    by = vg.comparator(s);
-    return sort;
-  };
-
-  return sort;
-};vg.data.stack = function() {
-  var layout = d3.layout.stack(),
-      point = vg.accessor("index"),
-      height = vg.accessor("data"),
-      params = ["offset", "order"],
-      output = {
-        "y0": "y2",
-        "y1": "y",
-        "cy": "cy"
-      };
-
-  function stack(data) {
-    var out_y0 = output["y0"],
-        out_y1 = output["y1"],
-        out_cy = output["cy"];
-    
-    var series = stacks(data);
-    if (series.length === 0) return data;
-    
-    layout.out(function(d, y0, y) {
-      if (d.datum) {
-        d.datum[out_y0] = y0;
-        d.datum[out_y1] = y + y0;
-        d.datum[out_cy] = y0 + y/2;
-      }
-    })(series);
-    
-    return data;
-  }
-  
-  function stacks(data) {
-    var values = vg.values(data),
-        points = [], series = [],
-        a, i, n, j, m, k, p, v, x;
-
-    // exit early if no data
-    if (values.length === 0) return series;
-
-    // collect and sort data points
-    for (i=0, n=values.length; i<n; ++i) {
-      a = vg.values(values[i]);
-      for (j=0, m=a.length; j<m; ++j) {
-        points.push({x:point(a[j]), y:height(a[j]), z:i, datum:a[j]});
-      }
-      series.push([]);
-    }
-    points.sort(function(a,b) {
-      return a.x<b.x ? -1 : a.x>b.x ? 1 : (a.z<b.z ? -1 : a.z>b.z ? 1 : 0);
-    });
-
-    // emit data series for stack layout
-    for (x=points[0].x, i=0, j=0, k=0, n=points.length; k<n; ++k) {
-      p = points[k];    
-      if (p.x !== x) {
-        while (i < series.length) series[i++].push({x:j, y:0});
-        x = p.x; i = 0; j += 1;
-      }
-      while (p.z > i) series[i++].push({x:j, y:0});
-      p.x = j;
-      series[i++].push(p);
-    }
-    while (i < series.length) series[i++].push({x:j, y:0});
-
-    return series;
-  }
-       
-  stack.point = function(field) {
-    point = vg.accessor(field);
-    return stack;
-  };
-  
-  stack.height = function(field) {
-    height = vg.accessor(field);
-    return stack;
-  };
-
-  params.forEach(function(name) {
-    stack[name] = function(x) {
-      layout[name](x);
-      return stack;
-    }
-  });
-
-  stack.output = function(map) {
-    d3.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return stack;
-  };
-
-  return stack;
-};vg.data.stats = function() {
-  var value = vg.accessor("data"),
-      assign = false,
-      median = false,
-      output = {
-        "count":    "count",
-        "min":      "min",
-        "max":      "max",
-        "sum":      "sum",
-        "mean":     "mean",
-        "variance": "variance",
-        "stdev":    "stdev",
-        "median":   "median"
-      };
-  
-  function reduce(data) {
-    var min = +Infinity,
-        max = -Infinity,
-        sum = 0,
-        mean = 0,
-        M2 = 0,
-        i, len, v, delta;
-
-    var list = (vg.isArray(data) ? data : data.values || []).map(value);
-    
-    // compute aggregates
-    for (i=0, len=list.length; i<len; ++i) {
-      v = list[i];
-      if (v < min) min = v;
-      if (v > max) max = v;
-      sum += v;
-      delta = v - mean;
-      mean = mean + delta / (i+1);
-      M2 = M2 + delta * (v - mean);
-    }
-    M2 = M2 / (len - 1);
-    
-    var o = vg.isArray(data) ? {} : data;
-    if (median) {
-      list.sort(vg.numcmp);
-      i = list.length >> 1;
-      o[output.median] = list.length % 2
-        ? list[i]
-        : (list[i-1] + list[i])/2;
-    }
-    o[output.count] = len;
-    o[output.min] = min;
-    o[output.max] = max;
-    o[output.sum] = sum;
-    o[output.mean] = mean;
-    o[output.variance] = M2;
-    o[output.stdev] = Math.sqrt(M2);
-    
-    if (assign) {
-      list = (vg.isArray(data) ? data : data.values);
-      v = {};
-      v[output.count] = len;
-      v[output.min] = min;
-      v[output.max] = max;
-      v[output.sum] = sum;
-      v[output.mean] = mean;
-      v[output.variance] = M2;
-      v[output.stdev] = Math.sqrt(M2);
-      if (median) v[output.median] = o[output.median];
-      for (i=0, len=list.length; i<len; ++i) {
-        list[i].stats = v;
-      }
-    }
-    
-    return o;
-  }
-  
-  function stats(data) {
-    return (vg.isArray(data) ? [data] : data.values || [])
-      .map(reduce); // no pun intended
-  }
-  
-  stats.median = function(bool) {
-    median = bool || false;
-    return stats;
-  };
-  
-  stats.value = function(field) {
-    value = vg.accessor(field);
-    return stats;
-  };
-
-  stats.assign = function(b) {
-    assign = b;
-    return stats;
-  };
-  
-  stats.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return stats;
-  };
-  
-  return stats;
-};vg.data.treemap = function() {
-  var layout = d3.layout.treemap()
-                 .children(function(d) { return d.values; }),
-      value = vg.accessor("data"),
-      size = ["width", "height"],
-      params = ["round", "sticky", "ratio", "padding"],
-      output = {
-        "x": "x",
-        "y": "y",
-        "dx": "width",
-        "dy": "height"
-      };
-
-  function treemap(data, db, group) {
-    data = layout
-      .size(vg.data.size(size, group))
-      .value(value)
-      .nodes(vg.isTree(data) ? data.nodes() : data);
-    
-    var keys = vg.keys(output),
-        len = keys.length;
-    data.forEach(function(d) {
-      var key, val;
-      for (var i=0; i<len; ++i) {
-        key = keys[i];
-        if (key !== output[key]) {
-          val = d[key];
-          delete d[key];
-          d[output[key]] = val;
-        }
-      }
-    });
-    
-    return data;
-  }
-
-  treemap.size = function(sz) {
-    size = sz;
-    return treemap;
-  };
-
-  treemap.value = function(field) {
-    value = vg.accessor(field);
-    return treemap;
-  };
-
-  params.forEach(function(name) {
-    treemap[name] = function(x) {
-      layout[name](x);
-      return treemap;
-    }
-  });
-
-  treemap.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return treemap;
-  };
-
-  return treemap;
-};vg.data.truncate = function() {
-  var value = vg.accessor("data"),
-      as = "truncate",
-      position = "right",
-      ellipsis = "...",
-      wordBreak = true,
-      limit = 100;
-  
-  var truncate = vg.data.mapper(function(d) {
-    var text = vg.truncate(value(d), limit, position, wordBreak, ellipsis);
-    return (d[as] = text, d);
-  });
-
-  truncate.value = function(field) {
-    value = vg.accessor(field);
-    return truncate;
-  };
-  
-  truncate.output = function(field) {
-    as = field;
-    return truncate;
-  };
-
-  truncate.limit = function(len) {
-    limit = +len;
-    return truncate;
-  };
-  
-  truncate.position = function(pos) {
-    position = pos;
-    return truncate;
-  };
-
-  truncate.ellipsis = function(str) {
-    ellipsis = str+"";
-    return truncate;
-  };
-
-  truncate.wordbreak = function(b) {
-    wordBreak = !!b;
-    return truncate;
-  };
-
-  return truncate;
-};vg.data.unique = function() {
-
-  var field = null,
-      as = "field";
-
-  function unique(data) {
-    return vg.unique(data, field)
-      .map(function(x) {
-        var o = {};
-        o[as] = x;
-        return o;
-      });
-  }
-  
-  unique.field = function(f) {
-    field = vg.accessor(f);
-    return unique;
-  };
-  
-  unique.as = function(x) {
-    as = x;
-    return unique;
-  };
-
-  return unique;
-};vg.data.window = function() {
-
-  var size = 2,
-      step = 1;
-  
-  function win(data) {
-    data = vg.isArray(data) ? data : data.values || [];
-    var runs = [], i, j, n=data.length-size, curr;
-    for (i=0; i<=n; i+=step) {
-      for (j=0, curr=[]; j<size; ++j) curr.push(data[i+j]);
-      runs.push({key: i, values: curr});
-    }
-    return {values: runs};
-  }
-  
-  win.size = function(n) {
-    size = n;
-    return win;
-  };
-  
-  win.step = function(n) {
-    step = n;
-    return win;
-  };
-
-  return win;
-};vg.data.wordcloud = function() {
-  var layout = d3.layout.cloud().size([900, 500]),
-      text = vg.accessor("data"),
-      size = ["width", "height"],
-      fontSize = function() { return 14; },
-      rotate = function() { return 0; },
-      params = ["font", "fontStyle", "fontWeight", "padding"];
-  
-  var output = {
-    "x": "x",
-    "y": "y",
-    "size": "fontSize",
-    "font": "font",
-    "rotate": "angle"
-  };
-  
-  function cloud(data, db, group) {
-    function finish(tags, bounds) {
-      var size = layout.size(),
-          dx = size[0] / 2,
-          dy = size[1] / 2,
-          keys = vg.keys(output),
-          key, d, i, n, k, m = keys.length;
-
-      // sort data to match wordcloud order
-      data.sort(function(a,b) {
-        return fontSize(b) - fontSize(a);
-      });
-
-      for (i=0, n=tags.length; i<n; ++i) {
-        d = data[i];
-        for (k=0; k<m; ++k) {
-          key = keys[k];
-          d[output[key]] = tags[i][key];
-          if (key === "x") d[output.x] += dx;
-          if (key === "y") d[output.y] += dy;
-        }
-      }
-    }
-    
-    layout
-      .size(vg.data.size(size, group))
-      .text(text)
-      .fontSize(fontSize)
-      .rotate(rotate)
-      .words(data)
-      .on("end", finish)
-      .start();
-    return data;
-  }
-
-  cloud.text = function(field) {
-    text = vg.accessor(field);
-    return cloud;
-  };
-  
-  cloud.size = function(sz) {
-    size = sz;
-    return cloud;
-  };
-         
-  cloud.fontSize = function(field) {
-    fontSize = vg.accessor(field);
-    return cloud;
-  };
-  
-  cloud.rotate = function(x) {
-    var v;
-    if (vg.isObject(x) && !Array.isArray(x)) {
-      if (x.random !== undefined) {
-        v = (v = x.random) ? vg.array(v) : [0];
-        rotate = function() {
-          return v[~~(Math.random()*v.length-0.00001)];
-        };
-      } else if (x.alternate !== undefined) {
-        v = (v = x.alternate) ? vg.array(v) : [0];
-        rotate = function(d, i) {
-          return v[i % v.length];
-        };
-      }
-    } else {
-      rotate = vg.accessor(field);
-    }
-    return cloud;
-  };
-
-  params.forEach(function(name) {
-    cloud[name] = function(x) {
-      layout[name](x);
-      return cloud;
-    }
-  });
-
-  cloud.output = function(map) {
-    vg.keys(output).forEach(function(k) {
-      if (map[k] !== undefined) {
-        output[k] = map[k];
-      }
-    });
-    return cloud;
-  };
-  
-  return cloud;
-};vg.data.zip = function() {
-  var z = null,
-      as = "zip",
-      key = vg.accessor("data"),
-      defaultValue = undefined,
-      withKey = null;
-
-  function zip(data, db) {
-    var zdata = db[z], zlen = zdata.length, v, d, i, len, map;
-    
-    if (withKey) {
-      map = {};
-      zdata.forEach(function(s) { map[withKey(s)] = s; });
-    }
-    
-    for (i=0, len=data.length; i<len; ++i) {
-      d = data[i];
-      d[as] = map
-        ? ((v=map[key(d)]) != null ? v : defaultValue)
-        : zdata[i % zlen];
-    }
-    
-    return data;
-  }
-
-  zip["with"] = function(d) {
-    z = d;
-    return zip;
-  };
-  
-  zip["default"] = function(d) {
-    defaultValue = d;
-    return zip;
-  };
-
-  zip.as = function(name) {
-    as = name;
-    return zip;
-  };
-
-  zip.key = function(k) {
-    key = vg.accessor(k);
-    return zip;
-  };
-
-  zip.withKey = function(k) {
-    withKey = vg.accessor(k);
-    return zip;
-  };
-
-  return zip;
-};vg.parse = {};vg.parse.axes = (function() {
-  var ORIENT = {
-    "x":      "bottom",
-    "y":      "left",
-    "top":    "top",
-    "bottom": "bottom",
-    "left":   "left",
-    "right":  "right"
-  };
-
-  function axes(spec, axes, scales) {
-    (spec || []).forEach(function(def, index) {
-      axes[index] = axes[index] || vg.scene.axis();
-      axis(def, index, axes[index], scales);
-    });
-  };
-
-  function axis(def, index, axis, scales) {
-    // axis scale
-    if (def.scale !== undefined) {
-      axis.scale(scales[def.scale]);
-    }
-
-    // axis orientation
-    axis.orient(def.orient || ORIENT[def.type]);
-    // axis offset
-    axis.offset(def.offset || 0);
-    // axis layer
-    axis.layer(def.layer || "front");
-    // axis grid lines
-    axis.grid(def.grid || false);
-    // axis title
-    axis.title(def.title || null);
-    // axis title offset
-    axis.titleOffset(def.titleOffset != null
-      ? def.titleOffset : vg.config.axis.titleOffset);
-    // axis values
-    axis.tickValues(def.values || null);
-    // axis label formatting
-    axis.tickFormat(def.format ? d3.format(def.format) : null);
-    // axis tick subdivision
-    axis.tickSubdivide(def.subdivide || 0);
-    // axis tick padding
-    axis.tickPadding(def.tickPadding || vg.config.axis.padding);
-
-    // axis tick size(s)
-    var size = [];
-    if (def.tickSize !== undefined) {
-      for (var i=0; i<3; ++i) size.push(def.tickSize);
-    } else {
-      var ts = vg.config.axis.tickSize;
-      size = [ts, ts, ts];
-    }
-    if (def.tickSizeMajor != null) size[0] = def.tickSizeMajor;
-    if (def.tickSizeMinor != null) size[1] = def.tickSizeMinor;
-    if (def.tickSizeEnd   != null) size[2] = def.tickSizeEnd;
-    if (size.length) {
-      axis.tickSize.apply(axis, size);
-    }
-
-    // tick arguments
-    if (def.ticks != null) {
-      var ticks = vg.isArray(def.ticks) ? def.ticks : [def.ticks];
-      axis.ticks.apply(axis, ticks);
-    } else {
-      axis.ticks(vg.config.axis.ticks);
-    }
-    
-    // style properties
-    var p = def.properties;
-    if (p && p.ticks) {
-      axis.majorTickProperties(p.majorTicks
-        ? vg.extend({}, p.ticks, p.majorTicks) : p.ticks);
-      axis.minorTickProperties(p.minorTicks
-        ? vg.extend({}, p.ticks, p.minorTicks) : p.ticks);
-    } else {
-      axis.majorTickProperties(p && p.majorTicks || {});
-      axis.minorTickProperties(p && p.minorTicks || {});
-    }
-    axis.tickLabelProperties(p && p.labels || {});
-    axis.titleProperties(p && p.title || {});
-    axis.gridLineProperties(p && p.grid || {});
-    axis.domainProperties(p && p.axis || {});
-  }
-  
-  return axes;
-})();vg.parse.data = function(spec, callback) {
-  var model = {
-    defs: spec,
-    load: {},
-    flow: {},
-    source: {}
-  };
-
-  var count = 0;
-  
-  function load(d) {
-    return function(error, data) {
-      if (error) {
-        vg.error("LOADING FAILED: " + d.url);
-      } else {
-        model.load[d.name] = vg.data.read(data.toString(), d.format);
-      }
-      if (--count === 0) callback();
-    }
-  }
-  
-  (spec || []).forEach(function(d) {
-    if (d.url) {
-      count += 1;
-      vg.data.load(d.url, load(d)); 
-    }
-     
-    if (d.values) {
-      if (d.format && d.format.parse) {
-        // run specified value parsers
-        vg.data.read.parse(d.values, d.format.parse);
-      }
-      model.load[d.name] = d.values;
-    }
-    
-    if (d.source) {
-      var list = model.source[d.source] || (model.source[d.source] = []);
-      list.push(d.name);
-    }
-    
-    if (d.transform) {
-      model.flow[d.name] = vg.parse.dataflow(d);
-    }
-  });
-  
-  if (count === 0) setTimeout(callback, 1);
-  return model;
-};vg.parse.dataflow = function(def) {
-  var tx = (def.transform || []).map(vg.parse.transform);
-  return !tx.length ? vg.identity :
-    function(data, db, group) {
-      return tx.reduce(function(d,t) { return t(d, db, group); }, data);
-    };
-};vg.parse.expr = (function() {
-  
-  var CONSTANT = {
-  	"E":       "Math.E",
-  	"LN2":     "Math.LN2",
-  	"LN10":    "Math.LN10",
-  	"LOG2E":   "Math.LOG2E",
-  	"LOG10E":  "Math.LOG10E",
-  	"PI":      "Math.PI",
-  	"SQRT1_2": "Math.SQRT1_2",
-  	"SQRT2":   "Math.SQRT2"
-  };
-
-  var FUNCTION = {
-  	"abs":    "Math.abs",
-  	"acos":   "Math.acos",
-  	"asin":   "Math.asin",
-  	"atan":   "Math.atan",
-  	"atan2":  "Math.atan2",
-  	"ceil":   "Math.ceil",
-  	"cos":    "Math.cos",
-  	"exp":    "Math.exp",
-  	"floor":  "Math.floor",
-  	"log":    "Math.log",
-  	"max":    "Math.max",
-  	"min":    "Math.min",
-  	"pow":    "Math.pow",
-  	"random": "Math.random",
-  	"round":  "Math.round",
-  	"sin":    "Math.sin",
-  	"sqrt":   "Math.sqrt",
-  	"tan":    "Math.tan"
-  };
-  
-  var lexer = /([\"\']|[\=\<\>\~\&\|\?\:\+\-\/\*\%\!\^\,\;\[\]\{\}\(\) ]+)/;
-      
-  return function(x) {
-    var tokens = x.split(lexer),
-        t, v, i, n, sq, dq;
-
-    for (sq=0, dq=0, i=0, n=tokens.length; i<n; ++i) {
-      var t = tokens[i];
-      if (t==="'") { if (!dq) sq = !sq; continue; }
-      if (t==='"') { if (!sq) dq = !dq; continue; }
-      if (dq || sq) continue;
-      if (CONSTANT[t]) {
-        tokens[i] = CONSTANT[t];
-      }
-      if (FUNCTION[t] && (v=tokens[i+1]) && v[0]==="(") {
-        tokens[i] = FUNCTION[t];
-      }
-    }
-    
-    return Function("d", "index", "data", "return ("+tokens.join("")+");");
-  };
-  
-})();vg.parse.legends = (function() {
-
-  function legends(spec, legends, scales) {
-    (spec || []).forEach(function(def, index) {
-      legends[index] = legends[index] || vg.scene.legend();
-      legend(def, index, legends[index], scales);
-    });
-  };
-
-  function legend(def, index, legend, scales) {
-    // legend scales
-    legend.size  (def.size   ? scales[def.size]   : null);
-    legend.shape (def.shape  ? scales[def.shape]  : null);
-    legend.fill  (def.fill   ? scales[def.fill]   : null);
-    legend.stroke(def.stroke ? scales[def.stroke] : null);
-
-    // legend orientation
-    if (def.orient) legend.orient(def.orient);
-
-    // legend offset
-    if (def.offset != null) legend.offset(def.offset);
-
-    // legend title
-    legend.title(def.title || null);
-
-    // legend values
-    legend.values(def.values || null);
-
-    // legend label formatting
-    legend.format(def.format !== undefined ? d3.format(def.format) : null);
-
-    // style properties
-    var p = def.properties;
-    legend.titleProperties(p && p.title || {});
-    legend.labelProperties(p && p.labels || {});
-    legend.legendProperties(p && p.legend || {});
-    legend.symbolProperties(p && p.symbols || {});
-    legend.gradientProperties(p && p.gradient || {});
-  }
-  
-  return legends;
-})();vg.parse.mark = function(mark) {
-  var props = mark.properties,
-      group = mark.marks;
-  
-  // parse mark property definitions
-  vg.keys(props).forEach(function(k) {
-    props[k] = vg.parse.properties(mark.type, props[k]);
-  });
-  // parse delay function
-  if (mark.delay) {
-    mark.delay = vg.parse.properties(mark.type, {delay: mark.delay});
-  }
-      
-  // parse mark data definition
-  if (mark.from) {
-    var name = mark.from.data,
-        tx = vg.parse.dataflow(mark.from);
-    mark.from = function(db, group, parentData) {
-      var data = vg.scene.data(name ? db[name] : null, parentData);
-      return tx(data, db, group);
-    };
-  }
-  
-  // recurse if group type
-  if (group) {
-    mark.marks = group.map(vg.parse.mark);
-  }
-      
-  return mark;
-};vg.parse.marks = function(spec, width, height) {
-  return {
-    type: "group",
-    width: width,
-    height: height,
-    scales: spec.scales || [],
-    axes: spec.axes || [],
-    legends: spec.legends || [],
-    marks: (spec.marks || []).map(vg.parse.mark)
-  };
-};vg.parse.padding = function(pad) {
-  if (pad == null) return "auto";
-  else if (vg.isString(pad)) return pad==="strict" ? "strict" : "auto";
-  else if (vg.isObject(pad)) return pad;
-  var p = vg.isNumber(pad) ? pad : 20;
-  return {top:p, left:p, right:p, bottom:p};
-};
-vg.parse.properties = (function() {
-  function compile(mark, spec) {
-    var code = "",
-        names = vg.keys(spec),
-        i, len, name, ref, vars = {};
-        
-    code += "var o = trans ? {} : item;\n"
-    
-    for (i=0, len=names.length; i<len; ++i) {
-      ref = spec[name = names[i]];
-      code += (i > 0) ? "\n  " : "  ";
-      code += "o."+name+" = "+valueRef(name, ref)+";";
-      vars[name] = true;
-    }
-    
-    if (vars.x2) {
-      if (vars.x) {
-        code += "\n  if (o.x > o.x2) { "
-              + "var t = o.x; o.x = o.x2; o.x2 = t; };";
-        code += "\n  o.width = (o.x2 - o.x);";
-      } else if (vars.width && !vars.x1) {
-        code += "\n  o.x = (o.x2 - o.width);";
-      } 
-    }
-
-    if (vars.y2) {
-      if (vars.y) {
-        code += "\n  if (o.y > o.y2) { "
-              + "var t = o.y; o.y = o.y2; o.y2 = t; };";
-        code += "\n  o.height = (o.y2 - o.y);";
-      } else if (vars.height && !vars.y1) {
-        code += "\n  o.y = (o.y2 - o.height);";
-      }
-    }
-    
-    if (hasPath(mark, vars)) {
-      code += "\n  if (o['path:parsed']) o['path:parsed'] = null;"
-    }
-    code += "\n  if (trans) trans.interpolate(item, o);";
-
-    try {
-      return Function("item", "group", "trans", code);
-    } catch (e) {
-      vg.error(e);
-      vg.log(code);
-    }
-  }
-  
-  function hasPath(mark, vars) {
-    return vars.path ||
-      ((mark==="area" || mark==="line") &&
-        (vars.x || vars.x2 || vars.width ||
-         vars.y || vars.y2 || vars.height ||
-         vars.tension || vars.interpolate));
-  }
-  
-  var GROUP_VARS = {
-    "width": 1,
-    "height": 1,
-    "mark.group.width": 1,
-    "mark.group.height": 1
-  };
-
-  function valueRef(name, ref) {
-    if (ref == null) return null;
-    var isColor = name==="fill" || name==="stroke";
-
-    if (isColor) {
-      if (ref.c) {
-        return colorRef("hcl", ref.h, ref.c, ref.l);
-      } else if (ref.h || ref.s) {
-        return colorRef("hsl", ref.h, ref.s, ref.l);
-      } else if (ref.l || ref.a) {
-        return colorRef("lab", ref.l, ref.a, ref.b);
-      } else if (ref.r || ref.g || ref.b) {
-        return colorRef("rgb", ref.r, ref.g, ref.b);
-      }
-    }
-
-    // initialize value
-    var val = "item.datum.data";
-    if (ref.value !== undefined) {
-      val = vg.str(ref.value);
-    }
-
-    // get field reference for enclosing group
-    if (ref.group != null) {
-      var grp = "";
-      if (vg.isString(ref.group)) {
-        grp = GROUP_VARS[ref.group]
-          ? "group." + ref.group
-          : "group.datum["+vg.field(ref.group).map(vg.str).join("][")+"]";
-      }
-    }
-
-    // get data field value
-    if (ref.field != null) {
-      if (vg.isString(ref.field)) {
-        val = "item.datum["+vg.field(ref.field).map(vg.str).join("][")+"]";
-        if (ref.group != null) { val = grp+"["+val+"]"; }
-      } else {
-        val = "this.accessor(group.datum["
-            + vg.field(ref.field.group).map(vg.str).join("][")
-            + "])(item.datum.data)";
-      }
-    } else if (ref.group != null) {
-      val = grp;
-    }
-
-    // run through scale function
-    if (ref.scale != null) {
-      var scale = vg.isString(ref.scale)
-        ? vg.str(ref.scale)
-        : (ref.scale.group ? "group" : "item")
-          + ".datum[" + vg.str(ref.scale.group || ref.scale.field) + "]";
-      scale = "group.scales[" + scale + "]";
-      val = scale + (ref.band ? ".rangeBand()" : "("+val+")");
-    }
-    
-    // multiply, offset, return value
-    val = "(" + (ref.mult?(vg.number(ref.mult)+" * "):"") + val + ")"
-      + (ref.offset ? " + " + vg.number(ref.offset) : "");
-    if (isColor) val = '('+val+')+""';
-    return val;
-  }
-  
-  function colorRef(type, x, y, z) {
-    var xx = x ? valueRef("", x) : vg.config.color[type][0],
-        yy = y ? valueRef("", y) : vg.config.color[type][1],
-        zz = z ? valueRef("", z) : vg.config.color[type][2];
-    return "(this.d3." + type + "(" + [xx,yy,zz].join(",") + ') + "")';
-  }
-  
-  return compile;
-})();vg.parse.scales = (function() {
-  var LINEAR = "linear",
-      ORDINAL = "ordinal",
-      LOG = "log",
-      POWER = "pow",
-      TIME = "time",
-      GROUP_PROPERTY = {width: 1, height: 1};
-
-  function scales(spec, scales, db, group) {
-    return (spec || []).reduce(function(o, def) {
-      var name = def.name, prev = name + ":prev";
-      o[name] = scale(def, o[name], db, group);
-      o[prev] = o[prev] || o[name];
-      return o;
-    }, scales || {});
-  }
-
-  function scale(def, scale, db, group) {
-    var s = instance(def, scale),
-        m = s.type===ORDINAL ? ordinal : quantitative,
-        rng = range(def, group),
-        data = vg.values(group.datum);
-
-    m(def, s, rng, db, data);
-    return s;
-  }
-
-  function instance(def, scale) {
-    var type = def.type || LINEAR;
-    if (!scale || type !== scale.type) {
-      var ctor = vg.config.scale[type] || d3.scale[type];
-      if (!ctor) vg.error("Unrecognized scale type: " + type);
-      (scale = ctor()).type = scale.type || type;
-      scale.scaleName = def.name;
-    }
-    return scale;
-  }
-
-  function ordinal(def, scale, rng, db, data) {
-    var domain, refs, values, str;
-    
-    // domain
-    domain = def.domain;
-    if (vg.isArray(domain)) {
-      scale.domain(domain);
-    } else if (vg.isObject(domain)) {
-      refs = def.domain.fields || vg.array(def.domain);
-      values = refs.reduce(function(values, r) {        
-        var dat = vg.values(db[r.data] || data),
-            get = vg.accessor(vg.isString(r.field)
-              ? r.field : "data." + vg.accessor(r.field.group)(data));
-        return vg.unique(dat, get, values);
-      }, []);
-      if (def.sort) values.sort(vg.cmp);
-      scale.domain(values);
-    }
-
-    // range
-    str = typeof rng[0] === 'string';
-    if (str || rng.length > 2) {
-      scale.range(rng); // color or shape values
-    } else if (def.points) {
-      scale.rangePoints(rng, def.padding||0);
-    } else if (def.round || def.round===undefined) {
-      scale.rangeRoundBands(rng, def.padding||0);
-    } else {
-      scale.rangeBands(rng, def.padding||0);
-    }
-  }
-
-  function quantitative(def, scale, rng, db, data) {
-    var domain, refs, interval, z;
-
-    // domain
-    domain = [null, null];
-    function extract(ref, min, max, z) {
-      var dat = vg.values(db[ref.data] || data);
-      var fields = vg.array(ref.field).map(function(f) {
-        return vg.isString(f) ? f
-          : "data." + vg.accessor(f.group)(data);
-      });
-      
-      fields.forEach(function(f,i) {
-        f = vg.accessor(f);
-        if (min) domain[0] = d3.min([domain[0], d3.min(dat, f)]);
-        if (max) domain[z] = d3.max([domain[z], d3.max(dat, f)]);
-      });
-    }
-    if (def.domain !== undefined) {
-      if (vg.isArray(def.domain)) {
-        domain = def.domain.slice();
-      } else if (vg.isObject(def.domain)) {
-        refs = def.domain.fields || vg.array(def.domain);
-        refs.forEach(function(r) { extract(r,1,1,1); });
-      } else {
-        domain = def.domain;
-      }
-    }
-    z = domain.length - 1;
-    if (def.domainMin !== undefined) {
-      if (vg.isObject(def.domainMin)) {
-        domain[0] = null;
-        refs = def.domainMin.fields || vg.array(def.domainMin);
-        refs.forEach(function(r) { extract(r,1,0,z); });
-      } else {
-        domain[0] = def.domainMin;
-      }
-    }
-    if (def.domainMax !== undefined) {
-      if (vg.isObject(def.domainMax)) {
-        domain[z] = null;
-        refs = def.domainMax.fields || vg.array(def.domainMax);
-        refs.forEach(function(r) { extract(r,0,1,z); });
-      } else {
-        domain[z] = def.domainMax;
-      }
-    }
-    if (def.type !== LOG && def.type !== TIME && (def.zero || def.zero===undefined)) {
-      domain[0] = Math.min(0, domain[0]);
-      domain[z] = Math.max(0, domain[z]);
-    }
-    scale.domain(domain);
-
-    // range
-    // vertical scales should flip by default, so use XOR here
-    if (def.range === "height") rng = rng.reverse();
-    scale[def.round && scale.rangeRound ? "rangeRound" : "range"](rng);
-
-    if (def.exponent && def.type===POWER) scale.exponent(def.exponent);
-    if (def.clamp) scale.clamp(true);
-    if (def.nice) {
-      if (def.type === TIME) {
-        interval = d3.time[def.nice];
-        if (!interval) vg.error("Unrecognized interval: " + interval);
-        scale.nice(interval);
-      } else {
-        scale.nice();
-      }
-    }
-  }
-
-  function range(def, group) {
-    var rng = [null, null];
-
-    if (def.range !== undefined) {
-      if (typeof def.range === 'string') {
-        if (GROUP_PROPERTY[def.range]) {
-          rng = [0, group[def.range]];
-        } else if (vg.config.range[def.range]) {
-          rng = vg.config.range[def.range];
-        } else {
-          vg.error("Unrecogized range: "+def.range);
-          return rng;
-        }
-      } else if (vg.isArray(def.range)) {
-        rng = def.range;
-      } else {
-        rng = [0, def.range];
-      }
-    }
-    if (def.rangeMin !== undefined) {
-      rng[0] = def.rangeMin;
-    }
-    if (def.rangeMax !== undefined) {
-      rng[rng.length-1] = def.rangeMax;
-    }
-    
-    if (def.reverse !== undefined) {
-      var rev = def.reverse;
-      if (vg.isObject(rev)) {
-        rev = vg.accessor(rev.field)(group.datum);
-      }
-      if (rev) rng = rng.reverse();
-    }
-    
-    return rng;
-  }
-
-  return scales;
-})();
-vg.parse.spec = function(spec, callback, viewFactory) {
-  
-  viewFactory = viewFactory || vg.ViewFactory;
-  
-  function parse(spec) {
-    // protect against subsequent spec modification
-    spec = vg.duplicate(spec);
-    
-    var width = spec.width || 500,
-        height = spec.height || 500,
-        viewport = spec.viewport || null;
-    
-    var defs = {
-      width: width,
-      height: height,
-      viewport: viewport,
-      padding: vg.parse.padding(spec.padding),
-      marks: vg.parse.marks(spec, width, height),
-      data: vg.parse.data(spec.data, function() { callback(viewConstructor); })
-    };
-    
-    var viewConstructor = viewFactory(defs);
-  }
-  
-  vg.isObject(spec) ? parse(spec) :
-    d3.json(spec, function(error, json) {
-      error ? vg.error(error) : parse(json);
-    });
-};vg.parse.transform = function(def) {
-  var tx = vg.data[def.type]();
-      
-  vg.keys(def).forEach(function(k) {
-    if (k === 'type') return;
-    (tx[k])(def[k]);
-  });
-  
-  return tx;
-};vg.scene = {};
-
-vg.scene.GROUP  = "group",
-vg.scene.ENTER  = 0,
-vg.scene.UPDATE = 1,
-vg.scene.EXIT   = 2;
-
-vg.scene.DEFAULT_DATA = {"sentinel":1}
-
-vg.scene.data = function(data, parentData) {
-  var DEFAULT = vg.scene.DEFAULT_DATA;
-
-  // if data is undefined, inherit or use default
-  data = vg.values(data || parentData || [DEFAULT]);
-
-  // if inheriting default data, ensure its in an array
-  if (data === DEFAULT) data = [DEFAULT];
-  
-  return data;
-};
-
-vg.scene.fontString = function(o) {
-  return (o.fontStyle ? o.fontStyle + " " : "")
-    + (o.fontVariant ? o.fontVariant + " " : "")
-    + (o.fontWeight ? o.fontWeight + " " : "")
-    + (o.fontSize != null ? o.fontSize : vg.config.render.fontSize) + "px "
-    + (o.font || vg.config.render.font);
-};vg.scene.Item = (function() {
-  function item(mark) {
-    this.mark = mark;
-  }
-  
-  var prototype = item.prototype;
-
-  prototype.hasPropertySet = function(name) {
-    var props = this.mark.def.properties;
-    return props && props[name] != null;
-  };
-
-  prototype.cousin = function(offset, index) {
-    if (offset === 0) return this;
-    offset = offset || -1;
-    var mark = this.mark,
-        group = mark.group,
-        iidx = index==null ? mark.items.indexOf(this) : index,
-        midx = group.items.indexOf(mark) + offset;
-    return group.items[midx].items[iidx];
-  };
-  
-  prototype.sibling = function(offset) {
-    if (offset === 0) return this;
-    offset = offset || -1;
-    var mark = this.mark,
-        iidx = mark.items.indexOf(this) + offset;
-    return mark.items[iidx];
-  };
-  
-  prototype.remove = function() {
-    var item = this,
-        list = item.mark.items,
-        i = list.indexOf(item);
-    if (i >= 0) (i===list.length-1) ? list.pop() : list.splice(i, 1);
-    return item;
-  };
-  
-  return item;
-})();
-
-vg.scene.item = function(mark) {
-  return new vg.scene.Item(mark);
-};vg.scene.visit = function(node, func) {
-  var i, n, items;
-  if (func(node)) return true;
-  if (items = node.items) {
-    for (i=0, n=items.length; i<n; ++i) {
-      if (vg.scene.visit(items[i], func)) return true;
-    }
-  }
-};vg.scene.build = (function() {
-  var GROUP  = vg.scene.GROUP,
-      ENTER  = vg.scene.ENTER,
-      UPDATE = vg.scene.UPDATE,
-      EXIT   = vg.scene.EXIT,
-      DEFAULT= {"sentinel":1};
-  
-  function build(def, db, node, parentData) {
-    var data = vg.scene.data(
-      def.from ? def.from(db, node, parentData) : null,
-      parentData);
-    
-    // build node and items
-    node = buildNode(def, node);
-    node.items = buildItems(def, data, node);
-    buildTrans(def, node);
-    
-    // recurse if group
-    if (def.type === GROUP) {
-      buildGroup(def, db, node);
-    }
-    
-    return node;
-  };
-  
-  function buildNode(def, node) {
-    node = node || {};
-    node.def = def;
-    node.marktype = def.type;
-    node.interactive = !(def.interactive === false);
-    return node;
-  }
-  
-  function buildItems(def, data, node) {
-    var keyf = keyFunction(def.key),
-        prev = node.items || [],
-        next = [],
-        map = {},
-        i, key, len, item, datum, enter;
-
-    for (i=0, len=prev.length; i<len; ++i) {
-      item = prev[i];
-      item.status = EXIT;
-      if (keyf) map[item.key] = item;
-    }
-    
-    for (i=0, len=data.length; i<len; ++i) {
-      datum = data[i];
-      key = i;
-      item = keyf ? map[key = keyf(datum)] : prev[i];
-      enter = item ? false : (item = vg.scene.item(node), true);
-      item.status = enter ? ENTER : UPDATE;
-      item.datum = datum;
-      item.key = key;
-      next.push(item);
-    }
-
-    for (i=0, len=prev.length; i<len; ++i) {
-      item = prev[i];
-      if (item.status === EXIT) {
-        item.key = keyf ? item.key : next.length;
-        next.push(item);
-      }
-    }
-    
-    return next;
-  }
-  
-  function buildGroup(def, db, node) {
-    var groups = node.items,
-        marks = def.marks,
-        i, len, m, mlen, name, group;
-
-    for (i=0, len=groups.length; i<len; ++i) {
-      group = groups[i];
-      
-      // update scales
-      if (group.scales) for (name in group.scales) {
-        if (name.indexOf(":prev") < 0) {
-          group.scales[name+":prev"] = group.scales[name].copy();
-        }
-      }
-
-      // build items
-      group.items = group.items || [];
-      for (m=0, mlen=marks.length; m<mlen; ++m) {
-        group.items[m] = build(marks[m], db, group.items[m], group.datum);
-        group.items[m].group = group;
-      }
-    }
-  }
-
-  function buildTrans(def, node) {
-    if (def.duration) node.duration = def.duration;
-    if (def.ease) node.ease = d3.ease(def.ease)
-    if (def.delay) {
-      var items = node.items, group = node.group, n = items.length, i;
-      for (i=0; i<n; ++i) def.delay.call(this, items[i], group);
-    }
-  }
-  
-  function keyFunction(key) {
-    if (key == null) return null;
-    var f = vg.array(key).map(vg.accessor);
-    return function(d) {
-      for (var s="", i=0, n=f.length; i<n; ++i) {
-        if (i>0) s += "|";
-        s += String(f[i](d));
-      }
-      return s;
-    }
-  }
-  
-  return build;
-})();vg.scene.bounds = (function() {
-
-  var parse = vg.canvas.path.parse,
-      boundPath = vg.canvas.path.bounds,
-      areaPath = vg.canvas.path.area,
-      linePath = vg.canvas.path.line,
-      halfpi = Math.PI / 2,
-      sqrt3 = Math.sqrt(3),
-      tan30 = Math.tan(30 * Math.PI / 180),
-      gfx = null;
-
-  function context() {
-    return gfx || (gfx = (vg.config.isNode
-      ? new (require("canvas"))(1,1)
-      : d3.select("body").append("canvas")
-          .attr("class", "vega_hidden")
-          .attr("width", 1)
-          .attr("height", 1)
-          .style("display", "none")
-          .node())
-      .getContext("2d"));
-  }
-
-  function pathBounds(o, path, bounds) {
-    if (path == null) {
-      bounds.set(0, 0, 0, 0);
-    } else {
-      boundPath(path, bounds);
-      if (o.stroke && o.opacity !== 0 && o.strokeWidth > 0) {
-        bounds.expand(o.strokeWidth);
-      }
-    }
-    return bounds;
-  }
-
-  function path(o, bounds) {
-    var p = o.path
-      ? o["path:parsed"] || (o["path:parsed"] = parse(o.path))
-      : null;
-    return pathBounds(o, p, bounds);
-  }
-  
-  function area(o, bounds) {
-    var items = o.mark.items, o = items[0];
-    var p = o["path:parsed"] || (o["path:parsed"]=parse(areaPath(items)));
-    return pathBounds(items[0], p, bounds);
-  }
-
-  function line(o, bounds) {
-    var items = o.mark.items, o = items[0];
-    var p = o["path:parsed"] || (o["path:parsed"]=parse(linePath(items)));
-    return pathBounds(items[0], p, bounds);
-  }
-
-  function rect(o, bounds) {
-    var x = o.x || 0,
-        y = o.y || 0,
-        w = (x + o.width) || 0,
-        h = (y + o.height) || 0;
-    bounds.set(x, y, w, h);
-    if (o.stroke && o.opacity !== 0 && o.strokeWidth > 0) {
-      bounds.expand(o.strokeWidth);
-    }
-    return bounds;
-  }
-
-  function image(o, bounds) {
-    var w = o.width || 0,
-        h = o.height || 0,
-        x = (o.x||0) - (o.align === "center"
-            ? w/2 : (o.align === "right" ? w : 0)),
-        y = (o.y||0) - (o.baseline === "middle"
-            ? h/2 : (o.baseline === "bottom" ? h : 0));
-    return bounds.set(x, y, x+w, y+h);
-  }
-
-  function rule(o, bounds) {
-    var x1, y1;
-    bounds.set(
-      x1 = o.x || 0,
-      y1 = o.y || 0,
-      o.x2 != null ? o.x2 : x1,
-      o.y2 != null ? o.y2 : y1
-    );
-    if (o.stroke && o.opacity !== 0 && o.strokeWidth > 0) {
-      bounds.expand(o.strokeWidth);
-    }
-    return bounds;
-  }
-  
-  function arc(o, bounds) {
-    var cx = o.x || 0,
-        cy = o.y || 0,
-        ir = o.innerRadius || 0,
-        or = o.outerRadius || 0,
-        sa = (o.startAngle || 0) - halfpi,
-        ea = (o.endAngle || 0) - halfpi,
-        xmin = Infinity, xmax = -Infinity,
-        ymin = Infinity, ymax = -Infinity,
-        a, i, n, x, y, ix, iy, ox, oy;
-
-    var angles = [sa, ea],
-        s = sa - (sa%halfpi);
-    for (i=0; i<4 && s<ea; ++i, s+=halfpi) {
-      angles.push(s);
-    }
-
-    for (i=0, n=angles.length; i<n; ++i) {
-      a = angles[i];
-      x = Math.cos(a); ix = ir*x; ox = or*x;
-      y = Math.sin(a); iy = ir*y; oy = or*y;
-      xmin = Math.min(xmin, ix, ox);
-      xmax = Math.max(xmax, ix, ox);
-      ymin = Math.min(ymin, iy, oy);
-      ymax = Math.max(ymax, iy, oy);
-    }
-
-    bounds.set(cx+xmin, cy+ymin, cx+xmax, cy+ymax);
-    if (o.stroke && o.opacity !== 0 && o.strokeWidth > 0) {
-      bounds.expand(o.strokeWidth);
-    }
-    return bounds;
-  }
-
-  function symbol(o, bounds) {
-    var size = o.size != null ? o.size : 100,
-        x = o.x || 0,
-        y = o.y || 0,
-        r, t, rx, ry;
-
-    switch (o.shape) {
-      case "cross":
-        r = Math.sqrt(size / 5) / 2;
-        t = 3*r;
-        bounds.set(x-t, y-t, x+y, y+t);
-        break;
-
-      case "diamond":
-        ry = Math.sqrt(size / (2 * tan30));
-        rx = ry * tan30;
-        bounds.set(x-rx, y-ry, x+rx, y+ry);
-        break;
-
-      case "square":
-        t = Math.sqrt(size);
-        r = t / 2;
-        bounds.set(x-r, y-r, x+r, y+r);
-        break;
-
-      case "triangle-down":
-        rx = Math.sqrt(size / sqrt3);
-        ry = rx * sqrt3 / 2;
-        bounds.set(x-rx, y-ry, x+rx, y+ry);
-        break;
-
-      case "triangle-up":
-        rx = Math.sqrt(size / sqrt3);
-        ry = rx * sqrt3 / 2;
-        bounds.set(x-rx, y-ry, x+rx, y+ry);
-        break;
-
-      default:
-        r = Math.sqrt(size/Math.PI);
-        bounds.set(x-r, y-r, x+r, y+r);
-    }
-    if (o.stroke && o.opacity !== 0 && o.strokeWidth > 0) {
-      bounds.expand(o.strokeWidth);
-    }
-    return bounds;
-  }
-
-  function text(o, bounds, noRotate) {
-    var x = (o.x || 0) + (o.dx || 0),
-        y = (o.y || 0) + (o.dy || 0),
-        h = o.fontSize || vg.config.render.fontSize,
-        a = o.align,
-        b = o.baseline,
-        g = context(), w;
-
-    g.font = vg.scene.fontString(o);
-    g.textAlign = a || "left";
-    g.textBaseline = b || "alphabetic";
-    w = g.measureText(o.text || "").width;
-
-    // horizontal
-    if (a === "center") {
-      x = x - (w / 2);
-    } else if (a === "right") {
-      x = x - w;
-    } else {
-      // left by default, do nothing
-    }
-
-    /// TODO find a robust solution for heights.
-    /// These offsets work for some but not all fonts.
-
-    // vertical
-    if (b === "top") {
-      y = y + (h/5);
-    } else if (b === "bottom") {
-      y = y - h;
-    } else if (b === "middle") {
-      y = y - (h/2) + (h/10);
-    } else {
-      y = y - 4*h/5; // alphabetic by default
-    }
-    
-    bounds.set(x, y, x+w, y+h);
-    if (o.angle && !noRotate) {
-      bounds.rotate(o.angle*Math.PI/180, o.x||0, o.y||0);
-    }
-    return bounds.expand(noRotate ? 0 : 1);
-  }
-
-  function group(g, bounds, includeLegends) {
-    var axes = g.axisItems || [],
-        legends = g.legendItems || [], j, m;
-
-    for (j=0, m=axes.length; j<m; ++j) {
-      bounds.union(axes[j].bounds);
-    }
-    for (j=0, m=g.items.length; j<m; ++j) {
-      bounds.union(g.items[j].bounds);
-    }
-    if (includeLegends) {
-      for (j=0, m=legends.length; j<m; ++j) {
-        bounds.union(legends[j].bounds);
-      }
-      if (g.width != null && g.height != null) {
-        bounds.add(g.width, g.height);
-      }
-      if (g.x != null && g.y != null) {
-        bounds.add(0, 0);
-      }
-    }
-    bounds.translate(g.x||0, g.y||0);
-    return bounds;
-  }
-
-  var methods = {
-    group:  group,
-    symbol: symbol,
-    image:  image,
-    rect:   rect,
-    rule:   rule,
-    arc:    arc,
-    text:   text,
-    path:   path,
-    area:   area,
-    line:   line
-  };
-
-  function itemBounds(item, func, opt) {
-    func = func || methods[item.mark.marktype];
-    if (!item.bounds_prev) item['bounds:prev'] = new vg.Bounds();
-    var b = item.bounds, pb = item['bounds:prev'];
-    if (b) pb.clear().union(b);
-    item.bounds = func(item, b ? b.clear() : new vg.Bounds(), opt);
-    if (!b) pb.clear().union(item.bounds);
-    return item.bounds;
-  }
-
-  function markBounds(mark, bounds, opt) {
-    bounds = bounds || mark.bounds && mark.bounds.clear() || new vg.Bounds();
-    var type  = mark.marktype,
-        func  = methods[type],
-        items = mark.items,
-        item, i, len;
-        
-    if (type==="area" || type==="line") {
-      items[0].bounds = func(items[0], bounds);
-    } else {
-      for (i=0, len=items.length; i<len; ++i) {
-        bounds.union(itemBounds(items[i], func, opt));
-      }
-    }
-    mark.bounds = bounds;
-  }
-  
-  return {
-    mark:  markBounds,
-    item:  itemBounds,
-    text:  text,
-    group: group
-  };
-
-})();vg.scene.encode = (function() {
-  var GROUP  = vg.scene.GROUP,
-      ENTER  = vg.scene.ENTER,
-      UPDATE = vg.scene.UPDATE,
-      EXIT   = vg.scene.EXIT,
-      EMPTY  = {};
-
-  function main(scene, def, trans, request, items) {
-    (request && items)
-      ? update.call(this, scene, def, trans, request, items)
-      : encode.call(this, scene, scene, def, trans, request);
-    return scene;
-  }
-  
-  function update(scene, def, trans, request, items) {
-    items = vg.array(items);
-    var i, len, item, group, props, prop;
-    for (i=0, len=items.length; i<len; ++i) {
-      item = items[i];
-      group = item.mark.group || null;
-      props = item.mark.def.properties;
-      prop = props && props[request];
-      if (prop) {
-        prop.call(vg, item, group, trans);
-        vg.scene.bounds.item(item);
-      }
-    }
-  }
-  
-  function encode(group, scene, def, trans, request) {
-    encodeItems.call(this, group, scene.items, def, trans, request);
-    if (scene.marktype === GROUP) {
-      encodeGroup.call(this, scene, def, group, trans, request);
-    } else {
-      vg.scene.bounds.mark(scene);
-    }
-  }
-  
-  function encodeLegend(group, scene, def, trans, request) {
-    encodeGroup.call(this, scene, def, group, trans, request);
-    encodeItems.call(this, group, scene.items, def, trans, request);
-    vg.scene.bounds.mark(scene, null, true);
-  }
-  
-  function encodeGroup(scene, def, parent, trans, request) {
-    var i, len, m, mlen, group, scales,
-        axes, axisItems, axisDef, leg, legItems, legDef;
-
-    for (i=0, len=scene.items.length; i<len; ++i) {
-      group = scene.items[i];
-
-      // cascade scales recursively
-      // use parent scales if there are no group-level scale defs
-      scales = group.scales || (group.scales =
-        def.scales ? vg.extend({}, parent.scales) : parent.scales);
-      
-      // update group-level scales
-      if (def.scales) {
-        vg.parse.scales(def.scales, scales, this._data, group);
-      }
-      
-      // update group-level axes
-      if (def.axes) {
-        axes = group.axes || (group.axes = []);
-        axisItems = group.axisItems || (group.axisItems = []);
-        vg.parse.axes(def.axes, axes, group.scales);
-        axes.forEach(function(a, i) {
-          axisDef = a.def();
-          axisItems[i] = vg.scene.build(axisDef, this._data, axisItems[i]);
-          axisItems[i].group = group;
-          encode.call(this, group, group.axisItems[i], axisDef, trans);
-        });
-      }
-      
-      // encode children marks
-      for (m=0, mlen=group.items.length; m<mlen; ++m) {
-        encode.call(this, group, group.items[m], def.marks[m], trans, request);
-      }
-    }
-    
-    // compute bounds (without legend)
-    vg.scene.bounds.mark(scene, null, !def.legends);
-    
-    // update legends
-    if (def.legends) {
-      for (i=0, len=scene.items.length; i<len; ++i) {
-        group = scene.items[i];
-        leg = group.legends || (group.legends = []);
-        legItems = group.legendItems || (group.legendItems = []);
-        vg.parse.legends(def.legends, leg, group.scales);
-        leg.forEach(function(l, i) {
-          legDef = l.def();
-          legItems[i] = vg.scene.build(legDef, this._data, legItems[i]);
-          legItems[i].group = group;
-          encodeLegend.call(this, group, group.legendItems[i], legDef, trans);
-        });
-      }
-      vg.scene.bounds.mark(scene, null, true);
-    }
-  }
-  
-  function encodeItems(group, items, def, trans, request) {    
-    var props  = def.properties || EMPTY,
-        enter  = props.enter,
-        update = props.update,
-        exit   = props.exit,
-        i, len, item, prop;
-
-    if (request) {
-      if (prop = props[request]) {
-        for (i=0, len=items.length; i<len; ++i) {
-          prop.call(vg, items[i], group, trans);
-        }
-      }
-      return; // exit early if given request
-    }
-
-    for (i=0; i<items.length; ++i) {
-      item = items[i];
-
-      // enter set
-      if (item.status === ENTER) {
-        if (enter) enter.call(vg, item, group);
-        item.status = UPDATE;
-      }
-
-      // update set      
-      if (item.status !== EXIT && update) {
-        update.call(vg, item, group, trans);
-      }
-      
-      // exit set
-      if (item.status === EXIT) {
-        if (exit) exit.call(vg, item, group, trans);
-        if (trans && !exit) trans.interpolate(item, EMPTY);
-        else if (!trans) items[i--].remove();
-      }
-    }
-  }
-  
-  return main;
-})();vg.scene.Transition = (function() {
-  function trans(duration, ease) {
-    this.duration = duration || 500;
-    this.ease = ease && d3.ease(ease) || d3.ease("cubic-in-out");
-    this.updates = {next: null};
-  }
-  
-  var prototype = trans.prototype;
-  
-  prototype.interpolate = function(item, values) {
-    var key, curr, next, interp, list = null;
-
-    for (key in values) {
-      curr = item[key];
-      next = values[key];      
-      if (curr !== next) {
-        if (key === "text") {
-          // skip interpolation for text labels
-          item[key] = next;
-        } else {
-          // otherwise lookup interpolator
-          interp = d3.interpolate(curr, next);
-          interp.property = key;
-          (list || (list=[])).push(interp);
-        }
-      }
-    }
-
-    if (list === null && item.status === vg.scene.EXIT) {
-      list = []; // ensure exiting items are included
-    }
-
-    if (list != null) {
-      list.item = item;
-      list.ease = item.mark.ease || this.ease;
-      list.next = this.updates.next;
-      this.updates.next = list;
-    }
-    return this;
-  };
-  
-  prototype.start = function(callback) {
-    var t = this, prev = t.updates, curr = prev.next;
-    for (; curr!=null; prev=curr, curr=prev.next) {
-      if (curr.item.status === vg.scene.EXIT) curr.remove = true;
-    }
-    t.callback = callback;
-    d3.timer(function(elapsed) { return step.call(t, elapsed); });
-  };
-
-  function step(elapsed) {
-    var list = this.updates, prev = list, curr = prev.next,
-        duration = this.duration,
-        item, delay, f, e, i, n, stop = true;
-
-    for (; curr!=null; prev=curr, curr=prev.next) {
-      item = curr.item;
-      delay = item.delay || 0;
-
-      f = (elapsed - delay) / duration;
-      if (f < 0) { stop = false; continue; }
-      if (f > 1) f = 1;
-      e = curr.ease(f);
-
-      for (i=0, n=curr.length; i<n; ++i) {
-        item[curr[i].property] = curr[i](e);
-        vg.scene.bounds.item(item);
-      }
-
-      if (f === 1) {
-        if (curr.remove) item.remove();
-        prev.next = curr.next;
-        curr = prev;
-      } else {
-        stop = false;
-      }
-    }
-
-    this.callback();
-    return stop;
-  };
-  
-  return trans;
-  
-})();
-
-vg.scene.transition = function(dur, ease) {
-  return new vg.scene.Transition(dur, ease);
-};vg.scene.axis = function() {
-  var scale,
-      orient = vg.config.axis.orient,
-      offset = 0,
-      titleOffset = vg.config.axis.titleOffset,
-      axisDef = null,
-      layer = "front",
-      grid = false,
-      title = null,
-      tickMajorSize = vg.config.axis.tickSize,
-      tickMinorSize = vg.config.axis.tickSize,
-      tickEndSize = vg.config.axis.tickSize,
-      tickPadding = vg.config.axis.padding,
-      tickValues = null,
-      tickFormat = null,
-      tickSubdivide = 0,
-      tickArguments = [vg.config.axis.ticks],
-      gridLineStyle = {},
-      tickLabelStyle = {},
-      majorTickStyle = {},
-      minorTickStyle = {},
-      titleStyle = {},
-      domainStyle = {};
-
-  var axis = {};
-
-  function reset() { axisDef = null; }
-
-  axis.def = function() {
-    var def = axisDef ? axisDef : (axisDef = axis_def(scale));
-    
-    // generate data
-    var major = tickValues == null
-      ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain())
-      : tickValues;
-    var minor = vg_axisSubdivide(scale, major, tickSubdivide).map(vg.data.ingest);
-    major = major.map(vg.data.ingest);
-    var fmt = tickFormat==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : tickFormat;
-    major.forEach(function(d) { d.label = fmt(d.data); });
-    var tdata = title ? [title].map(vg.data.ingest) : [];
-    
-    // update axis def
-    def.marks[0].from = function() { return grid ? major : []; };
-    def.marks[1].from = function() { return major; };
-    def.marks[2].from = function() { return minor; };
-    def.marks[3].from = def.marks[1].from;
-    def.marks[4].from = function() { return [1]; };
-    def.marks[5].from = function() { return tdata; };
-    def.offset = offset;
-    def.orient = orient;
-    def.layer = layer;
-    return def;
-  };
-
-  function axis_def(scale) {
-    // setup scale mapping
-    var newScale, oldScale, range;
-    if (scale.type === "ordinal") {
-      newScale = {scale: scale.scaleName, offset: 0.5 + scale.rangeBand()/2};
-      oldScale = newScale;
-    } else {
-      newScale = {scale: scale.scaleName, offset: 0.5};
-      oldScale = {scale: scale.scaleName+":prev", offset: 0.5};
-    }
-    range = vg_axisScaleRange(scale);
-
-    // setup axis marks
-    var gridLines = vg_axisTicks();
-    var majorTicks = vg_axisTicks();
-    var minorTicks = vg_axisTicks();
-    var tickLabels = vg_axisTickLabels();
-    var domain = vg_axisDomain();
-    var title = vg_axisTitle();
-    gridLines.properties.enter.stroke = {value: vg.config.axis.gridColor};
-
-    // extend axis marks based on axis orientation
-    vg_axisTicksExtend(orient, gridLines, oldScale, newScale, Infinity);
-    vg_axisTicksExtend(orient, majorTicks, oldScale, newScale, tickMajorSize);
-    vg_axisTicksExtend(orient, minorTicks, oldScale, newScale, tickMinorSize);
-    vg_axisLabelExtend(orient, tickLabels, oldScale, newScale, tickMajorSize, tickPadding);
-
-    vg_axisDomainExtend(orient, domain, range, tickEndSize);
-    vg_axisTitleExtend(orient, title, range, titleOffset); // TODO get offset
-    
-    // add / override custom style properties
-    vg.extend(gridLines.properties.update, gridLineStyle);
-    vg.extend(majorTicks.properties.update, majorTickStyle);
-    vg.extend(minorTicks.properties.update, minorTickStyle);
-    vg.extend(tickLabels.properties.update, tickLabelStyle);
-    vg.extend(domain.properties.update, domainStyle);
-    vg.extend(title.properties.update, titleStyle);
-
-    var marks = [gridLines, majorTicks, minorTicks, tickLabels, domain, title];
-    return {
-      type: "group",
-      interactive: false,
-      properties: { enter: vg_axisUpdate, update: vg_axisUpdate },
-      marks: marks.map(vg.parse.mark)
-    };
-  }
-
-  axis.scale = function(x) {
-    if (!arguments.length) return scale;
-    if (scale !== x) { scale = x; reset(); }
-    return axis;
-  };
-
-  axis.orient = function(x) {
-    if (!arguments.length) return orient;
-    if (orient !== x) {
-      orient = x in vg_axisOrients ? x + "" : vg.config.axis.orient;
-      reset();
-    }
-    return axis;
-  };
-
-  axis.title = function(x) {
-    if (!arguments.length) return title;
-    if (title !== x) { title = x; reset(); }
-    return axis;
-  };
-
-  axis.ticks = function() {
-    if (!arguments.length) return tickArguments;
-    tickArguments = arguments;
-    return axis;
-  };
-
-  axis.tickValues = function(x) {
-    if (!arguments.length) return tickValues;
-    tickValues = x;
-    return axis;
-  };
-
-  axis.tickFormat = function(x) {
-    if (!arguments.length) return tickFormat;
-    tickFormat = x;
-    return axis;
-  };
-  
-  axis.tickSize = function(x, y) {
-    if (!arguments.length) return tickMajorSize;
-    var n = arguments.length - 1,
-        major = +x,
-        minor = n > 1 ? +y : tickMajorSize,
-        end   = n > 0 ? +arguments[n] : tickMajorSize;
-
-    if (tickMajorSize !== major ||
-        tickMinorSize !== minor ||
-        tickEndSize !== end) {
-      reset();
-    }
-
-    tickMajorSize = major;
-    tickMinorSize = minor;
-    tickEndSize = end;
-    return axis;
-  };
-
-  axis.tickSubdivide = function(x) {
-    if (!arguments.length) return tickSubdivide;
-    tickSubdivide = +x;
-    return axis;
-  };
-  
-  axis.offset = function(x) {
-    if (!arguments.length) return offset;
-    offset = vg.isObject(x) ? x : +x;
-    return axis;
-  };
-
-  axis.tickPadding = function(x) {
-    if (!arguments.length) return tickPadding;
-    if (tickPadding !== +x) { tickPadding = +x; reset(); }
-    return axis;
-  };
-
-  axis.titleOffset = function(x) {
-    if (!arguments.length) return titleOffset;
-    if (titleOffset !== +x) { titleOffset = +x; reset(); }
-    return axis;
-  };
-
-  axis.layer = function(x) {
-    if (!arguments.length) return layer;
-    if (layer !== x) { layer = x; reset(); }
-    return axis;
-  };
-
-  axis.grid = function(x) {
-    if (!arguments.length) return grid;
-    if (grid !== x) { grid = x; reset(); }
-    return axis;
-  };
-
-  axis.gridLineProperties = function(x) {
-    if (!arguments.length) return gridLineStyle;
-    if (gridLineStyle !== x) { gridLineStyle = x; }
-    return axis;
-  };
-
-  axis.majorTickProperties = function(x) {
-    if (!arguments.length) return majorTickStyle;
-    if (majorTickStyle !== x) { majorTickStyle = x; }
-    return axis;
-  };
-
-  axis.minorTickProperties = function(x) {
-    if (!arguments.length) return minorTickStyle;
-    if (minorTickStyle !== x) { minorTickStyle = x; }
-    return axis;
-  };
-
-  axis.tickLabelProperties = function(x) {
-    if (!arguments.length) return tickLabelStyle;
-    if (tickLabelStyle !== x) { tickLabelStyle = x; }
-    return axis;
-  };
-
-  axis.titleProperties = function(x) {
-    if (!arguments.length) return titleStyle;
-    if (titleStyle !== x) { titleStyle = x; }
-    return axis;
-  };
-
-  axis.domainProperties = function(x) {
-    if (!arguments.length) return domainStyle;
-    if (domainStyle !== x) { domainStyle = x; }
-    return axis;
-  };
-  
-  axis.reset = function() { reset(); };
-
-  return axis;
-};
-
-var vg_axisOrients = {top: 1, right: 1, bottom: 1, left: 1};
-
-function vg_axisSubdivide(scale, ticks, m) {
-  subticks = [];
-  if (m && ticks.length > 1) {
-    var extent = vg_axisScaleExtent(scale.domain()),
-        subticks,
-        i = -1,
-        n = ticks.length,
-        d = (ticks[1] - ticks[0]) / ++m,
-        j,
-        v;
-    while (++i < n) {
-      for (j = m; --j > 0;) {
-        if ((v = +ticks[i] - j * d) >= extent[0]) {
-          subticks.push(v);
-        }
-      }
-    }
-    for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
-      subticks.push(v);
-    }
-  }
-  return subticks;
-}
-
-function vg_axisScaleExtent(domain) {
-  var start = domain[0], stop = domain[domain.length - 1];
-  return start < stop ? [start, stop] : [stop, start];
-}
-
-function vg_axisScaleRange(scale) {
-  return scale.rangeExtent
-    ? scale.rangeExtent()
-    : vg_axisScaleExtent(scale.range());
-}
-
-var vg_axisAlign = {
-  bottom: "center",
-  top: "center",
-  left: "right",
-  right: "left"
-};
-
-var vg_axisBaseline = {
-  bottom: "top",
-  top: "bottom",
-  left: "middle",
-  right: "middle"
-};
-
-function vg_axisLabelExtend(orient, labels, oldScale, newScale, size, pad) {
-  size = Math.max(size, 0) + pad;
-  if (orient === "left" || orient === "top") {
-    size *= -1;
-  }  
-  if (orient === "top" || orient === "bottom") {
-    vg.extend(labels.properties.enter, {
-      x: oldScale,
-      y: {value: size},
-    });
-    vg.extend(labels.properties.update, {
-      x: newScale,
-      y: {value: size},
-      align: {value: "center"},
-      baseline: {value: vg_axisBaseline[orient]}
-    });
-  } else {
-    vg.extend(labels.properties.enter, {
-      x: {value: size},
-      y: oldScale,
-    });
-    vg.extend(labels.properties.update, {
-      x: {value: size},
-      y: newScale,
-      align: {value: vg_axisAlign[orient]},
-      baseline: {value: "middle"}
-    });
-  }
-}
-
-function vg_axisTicksExtend(orient, ticks, oldScale, newScale, size) {
-  var sign = (orient === "left" || orient === "top") ? -1 : 1;
-  if (size === Infinity) {
-    size = (orient === "top" || orient === "bottom")
-      ? {group: "mark.group.height", mult: -sign}
-      : {group: "mark.group.width", mult: -sign};
-  } else {
-    size = {value: sign * size};
-  }
-  if (orient === "top" || orient === "bottom") {
-    vg.extend(ticks.properties.enter, {
-      x:  oldScale,
-      y:  {value: 0},
-      y2: size
-    });
-    vg.extend(ticks.properties.update, {
-      x:  newScale,
-      y:  {value: 0},
-      y2: size
-    });
-    vg.extend(ticks.properties.exit, {
-      x:  newScale,
-    });        
-  } else {
-    vg.extend(ticks.properties.enter, {
-      x:  {value: 0},
-      x2: size,
-      y:  oldScale
-    });
-    vg.extend(ticks.properties.update, {
-      x:  {value: 0},
-      x2: size,
-      y:  newScale
-    });
-    vg.extend(ticks.properties.exit, {
-      y:  newScale,
-    });
-  }
-}
-
-function vg_axisTitleExtend(orient, title, range, offset) {
-  var mid = ~~((range[1] - range[0]) / 2),
-      sign = (orient === "top" || orient === "left") ? -1 : 1;
-  
-  if (orient === "bottom" || orient === "top") {
-    vg.extend(title.properties.update, {
-      x: {value: mid},
-      y: {value: sign*offset},
-      angle: {value: 0}
-    });
-  } else {
-    vg.extend(title.properties.update, {
-      x: {value: sign*offset},
-      y: {value: mid},
-      angle: {value: -90}
-    });
-  }
-}
-
-function vg_axisDomainExtend(orient, domain, range, size) {
-  var path;
-  if (orient === "top" || orient === "left") {
-    size = -1 * size;
-  }
-  if (orient === "bottom" || orient === "top") {
-    path = "M" + range[0] + "," + size + "V0H" + range[1] + "V" + size;
-  } else {
-    path = "M" + size + "," + range[0] + "H0V" + range[1] + "H" + size;
-  }
-  domain.properties.update.path = {value: path};
-}
-
-function vg_axisUpdate(item, group, trans) {
-  var o = trans ? {} : item,
-      offset = item.mark.def.offset,
-      orient = item.mark.def.orient,
-      width  = group.width,
-      height = group.height; // TODO fallback to global w,h?
-
-  if (vg.isObject(offset)) {
-    offset = -group.scales[offset.scale](offset.value);
-  }
-
-  switch (orient) {
-    case "left":   { o.x = -offset; o.y = 0; break; }
-    case "right":  { o.x = width + offset; o.y = 0; break; }
-    case "bottom": { o.x = 0; o.y = height + offset; break; }
-    case "top":    { o.x = 0; o.y = -offset; break; }
-    default:       { o.x = 0; o.y = 0; }
-  }
-
-  if (trans) trans.interpolate(item, o);
-}
-
-function vg_axisTicks() {
-  return {
-    type: "rule",
-    interactive: false,
-    key: "data",
-    properties: {
-      enter: {
-        stroke: {value: vg.config.axis.tickColor},
-        strokeWidth: {value: vg.config.axis.tickWidth},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_axisTickLabels() {
-  return {
-    type: "text",
-    interactive: true,
-    key: "data",
-    properties: {
-      enter: {
-        fill: {value: vg.config.axis.tickLabelColor},
-        font: {value: vg.config.axis.tickLabelFont},
-        fontSize: {value: vg.config.axis.tickLabelFontSize},
-        opacity: {value: 1e-6},
-        text: {field: "label"}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_axisTitle() {
-  return {
-    type: "text",
-    interactive: true,
-    properties: {
-      enter: {
-        font: {value: vg.config.axis.titleFont},
-        fontSize: {value: vg.config.axis.titleFontSize},
-        fontWeight: {value: vg.config.axis.titleFontWeight},
-        fill: {value: vg.config.axis.titleColor},
-        align: {value: "center"},
-        baseline: {value: "middle"},
-        text: {field: "data"}
-      },
-      update: {}
-    }
-  };
-}
-
-function vg_axisDomain() {
-  return {
-    type: "path",
-    interactive: false,
-    properties: {
-      enter: {
-        x: {value: 0.5},
-        y: {value: 0.5},
-        stroke: {value: vg.config.axis.axisColor},
-        strokeWidth: {value: vg.config.axis.axisWidth}
-      },
-      update: {}
-    }
-  };
-}
-vg.scene.legend = function() {
-  var size = null,
-      shape = null,
-      fill = null,
-      stroke = null,
-      spacing = null,
-      values = null,
-      format = null,
-      title = undefined,
-      orient = "right",
-      offset = vg.config.legend.offset,
-      padding = vg.config.legend.padding,
-      legendDef,
-      tickArguments = [5],
-      legendStyle = {},
-      symbolStyle = {},
-      gradientStyle = {},
-      titleStyle = {},
-      labelStyle = {};
-
-  var legend = {},
-      legendDef = null;
-
-  function reset() { legendDef = null; }
-
-  legend.def = function() {
-    var scale = size || shape || fill || stroke; 
-    if (!legendDef) {
-      legendDef = (scale===fill || scale===stroke) && !discrete(scale.type)
-        ? quantDef(scale)
-        : ordinalDef(scale);      
-    }
-    legendDef.orient = orient;
-    legendDef.offset = offset;
-    legendDef.padding = padding;
-    return legendDef;
-  };
-
-  function discrete(type) {
-    return type==="ordinal" || type==="quantize"
-      || type==="quantile" || type==="threshold";
-  }
-
-  function ordinalDef(scale) {
-    var def = o_legend_def(size, shape, fill, stroke);
-
-    // generate data
-    var data = (values == null
-      ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain())
-      : values).map(vg.data.ingest);
-    var fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format;
-    
-    // determine spacing between legend entries
-    var fs, range, offset, pad=5, domain = d3.range(data.length);
-    if (size) {
-      range = data.map(function(x) { return Math.sqrt(size(x.data)); });
-      offset = d3.max(range);
-      range = range.reduce(function(a,b,i,z) {
-          if (i > 0) a[i] = a[i-1] + z[i-1]/2 + pad;
-          return (a[i] += b/2, a); }, [0]).map(Math.round);
-    } else {
-      offset = Math.round(Math.sqrt(vg.config.legend.symbolSize));
-      range = spacing
-        || (fs = labelStyle.fontSize) && (fs.value + pad)
-        || (vg.config.legend.labelFontSize + pad);
-      range = domain.map(function(d,i) {
-        return Math.round(offset/2 + i*range);
-      });
-    }
-
-    // account for padding and title size
-    var sz = padding, ts;
-    if (title) {
-      ts = titleStyle.fontSize;
-      sz += 5 + ((ts && ts.value) || vg.config.legend.titleFontSize);
-    }
-    for (var i=0, n=range.length; i<n; ++i) range[i] += sz;
-    
-    // build scale for label layout
-    var scale = {
-      name: "legend",
-      type: "ordinal",
-      points: true,
-      domain: domain,
-      range: range
-    };
-    
-    // update legend def
-    var tdata = (title ? [title] : []).map(vg.data.ingest);
-    data.forEach(function(d) {
-      d.label = fmt(d.data);
-      d.offset = offset;
-    });
-    def.scales = [ scale ];
-    def.marks[0].from = function() { return tdata; };
-    def.marks[1].from = function() { return data; };
-    def.marks[2].from = def.marks[1].from;
-    return def;
-  }
-
-  function o_legend_def(size, shape, fill, stroke) {
-    // setup legend marks
-    var titles = vg_legendTitle(),
-        symbols = vg_legendSymbols(),
-        labels = vg_vLegendLabels();
-
-    // extend legend marks
-    vg_legendSymbolExtend(symbols, size, shape, fill, stroke);
-    
-    // add / override custom style properties
-    vg.extend(titles.properties.update, titleStyle);
-    vg.extend(symbols.properties.update, symbolStyle);
-    vg.extend(labels.properties.update, labelStyle);
-
-    // padding from legend border
-    titles.properties.enter.x.value += padding;
-    titles.properties.enter.y.value += padding;
-    labels.properties.enter.x.offset += padding + 1;
-    symbols.properties.enter.x.offset = padding + 1;
-
-    return {
-      type: "group",
-      interactive: false,
-      properties: {
-        enter: vg.parse.properties("group", legendStyle),
-        update: vg_legendUpdate
-      },
-      marks: [titles, symbols, labels].map(vg.parse.mark)
-    };
-  }
-
-  function quantDef(scale) {
-    var def = q_legend_def(scale),
-        dom = scale.domain(),
-        data = dom.map(vg.data.ingest),
-        width = (gradientStyle.width && gradientStyle.width.value) || vg.config.legend.gradientWidth,
-        fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format;
-
-    // build scale for label layout
-    var layout = {
-      name: "legend",
-      type: scale.type,
-      round: true,
-      zero: false,
-      domain: [dom[0], dom[dom.length-1]],
-      range: [padding, width+padding]
-    };
-    if (scale.type==="pow") layout.exponent = scale.exponent();
-    
-    // update legend def
-    var tdata = (title ? [title] : []).map(vg.data.ingest);
-    data.forEach(function(d,i) {
-      d.label = fmt(d.data);
-      d.align = i==(data.length-1) ? "right" : i==0 ? "left" : "center";
-    });
-    def.scales = [ layout ];
-    def.marks[0].from = function() { return tdata; };
-    def.marks[1].from = function() { return [1]; };
-    def.marks[2].from = function() { return data; };
-    return def;
-  }
-  
-  function q_legend_def(scale) {
-    // setup legend marks
-    var titles = vg_legendTitle(),
-        gradient = vg_legendGradient(),
-        labels = vg_hLegendLabels(),
-        grad = new vg.Gradient();
-
-    // setup color gradient
-    var dom = scale.domain(),
-        min = dom[0],
-        max = dom[dom.length-1],
-        f = scale.copy().domain([min, max]).range([0,1]);
-        
-    var stops = (scale.type !== "linear" && scale.ticks)
-      ? scale.ticks.call(scale, 15) : dom;
-    if (min !== stops[0]) stops.unshift(min);
-    if (max !== stops[stops.length-1]) stops.push(max);
-
-    for (var i=0, n=stops.length; i<n; ++i) {
-      grad.stop(f(stops[i]), scale(stops[i]));
-    }
-    gradient.properties.enter.fill = {value: grad};
-
-    // add / override custom style properties
-    vg.extend(titles.properties.update, titleStyle);
-    vg.extend(gradient.properties.update, gradientStyle);
-    vg.extend(labels.properties.update, labelStyle);
-
-    // account for gradient size
-    var gp = gradient.properties, gh = gradientStyle.height,
-        hh = (gh && gh.value) || gp.enter.height.value;
-    labels.properties.enter.y.value = hh;
-
-    // account for title size as needed
-    if (title) {
-      var tp = titles.properties, fs = titleStyle.fontSize,
-          sz = 4 + ((fs && fs.value) || tp.enter.fontSize.value);
-      gradient.properties.enter.y.value += sz;
-      labels.properties.enter.y.value += sz;
-    }
-    
-    // padding from legend border
-    titles.properties.enter.x.value += padding;
-    titles.properties.enter.y.value += padding;
-    gradient.properties.enter.x.value += padding;
-    gradient.properties.enter.y.value += padding;
-    labels.properties.enter.y.value += padding;
-
-    return {
-      type: "group",
-      interactive: false,
-      properties: {
-        enter: vg.parse.properties("group", legendStyle),
-        update: vg_legendUpdate
-      },
-      marks: [titles, gradient, labels].map(vg.parse.mark)
-    };
-  }
-
-  legend.size = function(x) {
-    if (!arguments.length) return size;
-    if (size !== x) { size = x; reset(); }
-    return legend;
-  };
-
-  legend.shape = function(x) {
-    if (!arguments.length) return shape;
-    if (shape !== x) { shape = x; reset(); }
-    return legend;
-  };
-
-  legend.fill = function(x) {
-    if (!arguments.length) return fill;
-    if (fill !== x) { fill = x; reset(); }
-    return legend;
-  };
-  
-  legend.stroke = function(x) {
-    if (!arguments.length) return stroke;
-    if (stroke !== x) { stroke = x; reset(); }
-    return legend;
-  };
-
-  legend.title = function(x) {
-    if (!arguments.length) return title;
-    if (title !== x) { title = x; reset(); }
-    return legend;
-  };
-
-  legend.format = function(x) {
-    if (!arguments.length) return format;
-    if (format !== x) { format = x; reset(); }
-    return legend;
-  };
-
-  legend.spacing = function(x) {
-    if (!arguments.length) return spacing;
-    if (spacing !== +x) { spacing = +x; reset(); }
-    return legend;
-  };
-
-  legend.orient = function(x) {
-    if (!arguments.length) return orient;
-    orient = x in vg_legendOrients ? x + "" : vg.config.legend.orient;
-    return legend;
-  };
-
-  legend.offset = function(x) {
-    if (!arguments.length) return offset;
-    offset = +x;
-    return legend;
-  };
-
-  legend.values = function(x) {
-    if (!arguments.length) return values;
-    values = x;
-    return legend;
-  };
-
-  legend.legendProperties = function(x) {
-    if (!arguments.length) return legendStyle;
-    legendStyle = x;
-    return legend;
-  };
-
-  legend.symbolProperties = function(x) {
-    if (!arguments.length) return symbolStyle;
-    symbolStyle = x;
-    return legend;
-  };
-
-  legend.gradientProperties = function(x) {
-    if (!arguments.length) return gradientStyle;
-    gradientStyle = x;
-    return legend;
-  };
-
-  legend.labelProperties = function(x) {
-    if (!arguments.length) return labelStyle;
-    labelStyle = x;
-    return legend;
-  };
-  
-  legend.titleProperties = function(x) {
-    if (!arguments.length) return titleStyle;
-    titleStyle = x;
-    return legend;
-  };
-
-  legend.reset = function() { reset(); };
-
-  return legend;
-};
-
-var vg_legendOrients = {right: 1, left: 1};
-
-function vg_legendUpdate(item, group, trans) {
-  var o = trans ? {} : item,
-      offset = item.mark.def.offset,
-      orient = item.mark.def.orient,
-      pad    = item.mark.def.padding * 2,
-      gx1    = group.bounds ? group.bounds.x1 : 0,
-      gx2    = group.bounds ? group.bounds.x2 : group.width,
-      lw     = ~~item.bounds.width() + (o.width ? 0 : pad),
-      lh     = ~~item.bounds.height() + (o.height ? 0 : pad);
-
-  o.x = 0.5;
-  o.y = 0.5;
-  o.width = lw;
-  o.height = lh;
-
-  switch (orient) {
-    case "left":  { o.x += gx1 - offset - lw; break; };
-    case "right": { o.x += gx2 + offset; break; };
-  }
-  
-  item.mark.def.properties.enter(item, group, trans);
-}
-
-function vg_legendSymbolExtend(mark, size, shape, fill, stroke) {
-  var props = mark.properties.enter;
-  if (size)   props.size   = {scale: size.scaleName,   field: "data"};
-  if (shape)  props.shape  = {scale: shape.scaleName,  field: "data"};
-  if (fill)   props.fill   = {scale: fill.scaleName,   field: "data"};
-  if (stroke) props.stroke = {scale: stroke.scaleName, field: "data"};
-}
-
-function vg_legendTitle() {
-  var cfg = vg.config.legend;
-  return {
-    type: "text",
-    interactive: false,
-    key: "data",
-    properties: {
-      enter: {
-        x: {value: 0},
-        y: {value: 0},
-        fill: {value: cfg.titleColor},
-        font: {value: cfg.titleFont},
-        fontSize: {value: cfg.titleFontSize},
-        fontWeight: {value: cfg.titleFontWeight},
-        baseline: {value: "top"},
-        text: {field: "data"},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_legendSymbols() {
-  var cfg = vg.config.legend;
-  return {
-    type: "symbol",
-    interactive: false,
-    key: "data",
-    properties: {
-      enter: {
-        x: {field: "offset", mult: 0.5},
-        y: {scale: "legend", field: "index"},
-        shape: {value: cfg.symbolShape},
-        size: {value: cfg.symbolSize},
-        stroke: {value: cfg.symbolColor},
-        strokeWidth: {value: cfg.symbolStrokeWidth},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_vLegendLabels() {
-  var cfg = vg.config.legend;
-  return {
-    type: "text",
-    interactive: false,
-    key: "data",
-    properties: {
-      enter: {
-        x: {field: "offset", offset: 5},
-        y: {scale: "legend", field: "index"},
-        fill: {value: cfg.labelColor},
-        font: {value: cfg.labelFont},
-        fontSize: {value: cfg.labelFontSize},
-        align: {value: cfg.labelAlign},
-        baseline: {value: cfg.labelBaseline},
-        text: {field: "label"},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_legendGradient() {
-  var cfg = vg.config.legend;
-  return {
-    type: "rect",
-    interactive: false,
-    properties: {
-      enter: {
-        x: {value: 0},
-        y: {value: 0},
-        width: {value: cfg.gradientWidth},
-        height: {value: cfg.gradientHeight},
-        stroke: {value: cfg.gradientStrokeColor},
-        strokeWidth: {value: cfg.gradientStrokeWidth},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}
-
-function vg_hLegendLabels() {
-  var cfg = vg.config.legend;
-  return {
-    type: "text",
-    interactive: false,
-    key: "data",
-    properties: {
-      enter: {
-        x: {scale: "legend", field: "data"},
-        y: {value: 20},
-        dy: {value: 2},
-        fill: {value: cfg.labelColor},
-        font: {value: cfg.labelFont},
-        fontSize: {value: cfg.labelFontSize},
-        align: {field: "align"},
-        baseline: {value: "top"},
-        text: {field: "label"},
-        opacity: {value: 1e-6}
-      },
-      exit: { opacity: {value: 1e-6} },
-      update: { opacity: {value: 1} }
-    }
-  };
-}vg.Model = (function() {
-  function model() {
-    this._defs = null;
-    this._data = {};
-    this._scene = null;
-    this._reset = false;
-  }
-  
-  var prototype = model.prototype;
-  
-  prototype.defs = function(defs) {
-    if (!arguments.length) return this._defs;
-    this._defs = defs;
-    return this;
-  };
-  
-  prototype.data = function(data) {
-    if (!arguments.length) return this._data;
-
-    var tx = this._defs.data.flow || {},
-        keys = this._defs.data.defs.map(vg.accessor("name")),
-        len = keys.length, i, k;
-
-    for (i=0; i<len; ++i) {
-      if (!data[k=keys[i]]) continue;
-      this.ingest(k, tx, data[k]);
-    }
-
-    return this;
-  };
-  
-  prototype.ingest = function(name, tx, input) {
-    this._data[name] = tx[name]
-      ? tx[name](input, this._data, this._defs.marks)
-      : input;
-    this.dependencies(name, tx);
-  };
-  
-  prototype.dependencies = function(name, tx) {
-    var source = this._defs.data.source[name],
-        data = this._data[name],
-        n = source ? source.length : 0, i, x;
-    for (i=0; i<n; ++i) {
-      x = vg_data_duplicate(data);
-      if (vg.isTree(data)) vg_make_tree(x);
-      this.ingest(source[i], tx, x);
-    }
-  };
-  
-  prototype.width = function(width) {
-    if (this._defs) this._defs.width = width;
-    if (this._defs && this._defs.marks) this._defs.marks.width = width;
-    if (this._scene) this._scene.items[0].width = width;
-    this._reset = true;
-    return this;
-  };
-  
-  prototype.height = function(height) {
-    if (this._defs) this._defs.height = height;
-    if (this._defs && this._defs.marks) this._defs.marks.height = height;
-    if (this._scene) this._scene.items[0].height = height;
-    this._reset = true;
-    return this;
-  };
-  
-  prototype.scene = function(node) {
-    if (!arguments.length) return this._scene;
-    this._scene = node;
-    return this;
-  };
-  
-  prototype.build = function() {
-    var m = this, data = m._data, marks = m._defs.marks;
-    m._scene = vg.scene.build.call(m, marks, data, m._scene);
-    m._scene.items[0].width = marks.width;
-    m._scene.items[0].height = marks.height;
-    m._scene.interactive = false;
-    return this;
-  };
-  
-  prototype.encode = function(trans, request, item) {
-    if (this._reset) { this.reset(); this._reset = false; }
-    var m = this, scene = m._scene, defs = m._defs;
-    vg.scene.encode.call(m, scene, defs.marks, trans, request, item);
-    return this;
-  };
-
-  prototype.reset = function() {
-    if (this._scene) {
-      vg.scene.visit(this._scene, function(item) {
-        if (item.axes) item.axes.forEach(function(axis) { axis.reset(); });
-      });
-    }
-    return this;
-  };
-
-  return model;
-})();vg.View = (function() {
-  var view = function(el, width, height) {
-    this._el = null;
-    this._build = false;
-    this._model = new vg.Model();
-    this._width = this.__width = width || 500;
-    this._height = this.__height = height || 500;
-    this._autopad = 1;
-    this._padding = {top:0, left:0, bottom:0, right:0};
-    this._viewport = null;
-    this._renderer = null;
-    this._handler = null;
-    this._io = vg.canvas;
-    if (el) this.initialize(el);
-  };
-  
-  var prototype = view.prototype;
-  
-  prototype.width = function(width) {
-    if (!arguments.length) return this.__width;
-    if (this.__width !== width) {
-      this._width = this.__width = width;
-      if (this._el) this.initialize(this._el.parentNode);
-      this._model.width(width);
-      if (this._strict) this._autopad = 1;
-    }
-    return this;
-  };
-
-  prototype.height = function(height) {
-    if (!arguments.length) return this.__height;
-    if (this.__height !== height) {
-      this._height = this.__height = height;
-      if (this._el) this.initialize(this._el.parentNode);
-      this._model.height(this._height);
-      if (this._strict) this._autopad = 1;
-    }
-    return this;
-  };
-
-  prototype.padding = function(pad) {
-    if (!arguments.length) return this._padding;
-    if (this._padding !== pad) {
-      if (vg.isString(pad)) {
-        this._autopad = 1;
-        this._padding = {top:0, left:0, bottom:0, right:0};
-        this._strict = (pad === "strict");
-      } else {
-        this._autopad = 0;
-        this._padding = pad;
-        this._strict = false;
-      }
-      if (this._el) {
-        this._renderer.resize(this._width, this._height, pad);
-        this._handler.padding(pad);
-      }
-    }
-    return this;
-  };
-  
-  prototype.autopad = function(opt) {
-    if (this._autopad < 1) return this;
-    else this._autopad = 0;
-
-    var pad = this._padding,
-        b = this.model().scene().bounds,
-        inset = vg.config.autopadInset,
-        l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0,
-        t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0,
-        r = b.x2 > this._width  ? Math.ceil(+b.x2 - this._width) + inset : 0,
-        b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0;
-    pad = {left:l, top:t, right:r, bottom:b};
-
-    if (this._strict) {
-      this._autopad = 0;
-      this._padding = pad;
-      this._width = Math.max(0, this.__width - (l+r));
-      this._height = Math.max(0, this.__height - (t+b));
-      this._model.width(this._width);
-      this._model.height(this._height);
-      if (this._el) this.initialize(this._el.parentNode);
-      this.update({props:"enter"}).update({props:"update"});
-    } else {
-      this.padding(pad).update(opt);
-    }
-    return this;
-  };
-
-  prototype.viewport = function(size) {
-    if (!arguments.length) return this._viewport;
-    if (this._viewport !== size) {
-      this._viewport = size;
-      if (this._el) this.initialize(this._el.parentNode);
-    }
-    return this;
-  };
-  
-  prototype.renderer = function(type) {
-    if (!arguments.length) return this._io;
-    if (type === "canvas") type = vg.canvas;
-    if (type === "svg") type = vg.svg;
-    if (this._io !== type) {
-      this._io = type;
-      this._renderer = null;
-      if (this._el) this.initialize(this._el.parentNode);
-      if (this._build) this.render();
-    }
-    return this;
-  };
-
-  prototype.defs = function(defs) {
-    if (!arguments.length) return this._model.defs();
-    this._model.defs(defs);
-    return this;
-  };
-
-  prototype.data = function(data) {
-    if (!arguments.length) return this._model.data();
-    var ingest = vg.keys(data).reduce(function(d, k) {
-      return (d[k] = vg.data.ingestAll(data[k]), d);
-    }, {});
-    this._model.data(ingest);
-    this._build = false;
-    return this;
-  };
-
-  prototype.model = function(model) {
-    if (!arguments.length) return this._model;
-    if (this._model !== model) {
-      this._model = model;
-      if (this._handler) this._handler.model(model);
-    }
-    return this;
-  };
-
-  prototype.initialize = function(el) {
-    var v = this, prevHandler,
-        w = v._width, h = v._height, pad = v._padding;
-    
-    // clear pre-existing container
-    d3.select(el).select("div.vega").remove();
-    
-    // add div container
-    this._el = el = d3.select(el)
-      .append("div")
-      .attr("class", "vega")
-      .style("position", "relative")
-      .node();
-    if (v._viewport) {
-      d3.select(el)
-        .style("width",  (v._viewport[0] || w)+"px")
-        .style("height", (v._viewport[1] || h)+"px")
-        .style("overflow", "auto");
-    }
-    
-    // renderer
-    v._renderer = (v._renderer || new this._io.Renderer())
-      .initialize(el, w, h, pad);
-    
-    // input handler
-    prevHandler = v._handler;
-    v._handler = new this._io.Handler()
-      .initialize(el, pad, v)
-      .model(v._model);
-
-    if (prevHandler) {
-      prevHandler.handlers().forEach(function(h) {
-        v._handler.on(h.type, h.handler);
-      });
-    }
-    
-    return this;
-  };
-  
-  prototype.render = function(items) {
-    this._renderer.render(this._model.scene(), items);
-    return this;
-  };
-  
-  prototype.on = function() {
-    this._handler.on.apply(this._handler, arguments);
-    return this;
-  };
-  
-  prototype.off = function() {
-    this._handler.off.apply(this._handler, arguments);
-    return this;
-  };
-  
-  prototype.update = function(opt) {    
-    opt = opt || {};
-    var view = this,
-        trans = opt.duration
-          ? vg.scene.transition(opt.duration, opt.ease)
-          : null;
-
-    view._build = view._build || (view._model.build(), true);
-    view._model.encode(trans, opt.props, opt.items);
-    
-    if (trans) {
-      trans.start(function(items) {
-        view._renderer.render(view._model.scene(), items);
-      });
-    }
-    else view.render(opt.items);
-
-    return view.autopad(opt);
-  };
-      
-  return view;
-})();
-
-// view constructor factory
-// takes definitions from parsed specification as input
-// returns a view constructor
-vg.ViewFactory = function(defs) {
-  return function(opt) {
-    opt = opt || {};
-    var v = new vg.View()
-      .width(defs.width)
-      .height(defs.height)
-      .padding(defs.padding)
-      .viewport(defs.viewport)
-      .renderer(opt.renderer || "canvas")
-      .defs(defs);
-
-    if (defs.data.load) v.data(defs.data.load);
-    if (opt.data) v.data(opt.data);
-    if (opt.el) v.initialize(opt.el);
-
-    if (opt.hover !== false) {
-      v.on("mouseover", function(evt, item) {
-        if (item.hasPropertySet("hover")) {
-          this.update({props:"hover", items:item});
-        }
-      })
-      .on("mouseout", function(evt, item) {
-        if (item.hasPropertySet("hover")) {
-          this.update({props:"update", items:item});
-        }
-      });
-    }
-  
-    return v;
-  };
-};
-vg.Spec = (function() {
-  var spec = function(s) {
-    this.spec = {
-      width: 500,
-      height: 500,
-      padding: 0,
-      data: [],
-      scales: [],
-      axes: [],
-      marks: []
-    };
-    if (s) vg.extend(this.spec, s);
-  };
-  
-  var prototype = spec.prototype;
-
-  prototype.width = function(w) {
-    this.spec.width = w;
-    return this;
-  };
-  
-  prototype.height = function(h) {
-    this.spec.height = h;
-    return this;
-  };
-  
-  prototype.padding = function(p) {
-    this.spec.padding = p;
-    return this;
-  };
-  
-  prototype.viewport = function(v) {
-    this.spec.viewport = v;
-    return this;
-  };
-
-  prototype.data = function(name, params) {
-    if (!params) params = vg.isString(name) ? {name: name} : name;
-    else params.name = name;
-    this.spec.data.push(params);
-    return this;
-  };
-  
-  prototype.scale = function(name, params) {
-    if (!params) params = vg.isString(name) ? {name: name} : name;
-    else params.name = name;
-    this.spec.scales.push(params);
-    return this;
-  };
-  
-  prototype.axis = function(params) {
-    this.spec.axes.push(params);
-    return this;
-  };
-  
-  prototype.mark = function(type, mark) {
-    if (!mark) mark = {type: type};
-    else mark.type = type;
-    mark.properties = {};
-    this.spec.marks.push(mark);
-    
-    var that = this;
-    return {
-      from: function(name, obj) {
-              mark.from = obj
-                ? (obj.data = name, obj)
-                : vg.isString(name) ? {data: name} : name;
-              return this;
-            },
-      prop: function(name, obj) {
-              mark.properties[name] = vg.keys(obj).reduce(function(o,k) {
-                var v = obj[k];
-                return (o[k] = vg.isObject(v) ? v : {value: v}, o);
-              }, {});
-              return this;
-            },
-      done: function() { return that; }
-    };
-  };
-
-  prototype.parse = function(callback) {
-    vg.parse.spec(this.spec, callback);
-  };
-
-  prototype.json = function() {
-    return this.spec;
-  };
-
-  return spec;
-})();
-
-vg.spec = function(s) {
-  return new vg.Spec(s);
-};
-vg.headless = {};vg.headless.View = (function() {
-  
-  var view = function(width, height, pad, type) {
-    this._canvas = null;
-    this._type = type;
-    this._el = "body";
-    this._build = false;
-    this._model = new vg.Model();
-    this._width = this.__width = width || 500;
-    this._height = this.__height = height || 500;
-    this._autopad = 1;
-    this._padding = pad || {top:0, left:0, bottom:0, right:0};
-    this._renderer = new vg[type].Renderer();
-    this.initialize();
-  };
-  
-  var prototype = view.prototype;
-
-  prototype.el = function(el) {
-    if (!arguments.length) return this._el;
-    if (this._el !== el) {
-      this._el = el;
-      this.initialize();
-    }
-    return this;
-  };
-
-  prototype.width = function(width) {
-    if (!arguments.length) return this._width;
-    if (this._width !== width) {
-      this._width = width;
-      this.initialize();
-      this._model.width(width);
-    }
-    return this;
-  };
-
-  prototype.height = function(height) {
-    if (!arguments.length) return this._height;
-    if (this._height !== height) {
-      this._height = height;
-      this.initialize();
-      this._model.height(this._height);
-    }
-    return this;
-  };
-
-  prototype.padding = function(pad) {
-    if (!arguments.length) return this._padding;
-    if (this._padding !== pad) {
-      if (vg.isString(pad)) {
-        this._autopad = 1;
-        this._padding = {top:0, left:0, bottom:0, right:0};
-        this._strict = (pad === "strict");
-      } else {
-        this._autopad = 0;
-        this._padding = pad;
-        this._strict = false;
-      }
-      this.initialize();
-    }
-    return this;
-  };
-
-  prototype.autopad = function(opt) {
-    if (this._autopad < 1) return this;
-    else this._autopad = 0;
-
-    var pad = this._padding,
-        b = this._model.scene().bounds,
-        inset = vg.config.autopadInset,
-        l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0,
-        t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0,
-        r = b.x2 > this._width  ? Math.ceil(+b.x2 - this._width) + inset : 0,
-        b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0;
-    pad = {left:l, top:t, right:r, bottom:b};
-
-    if (this._strict) {
-      this._autopad = 0;
-      this._padding = pad;
-      this._width = Math.max(0, this.__width - (l+r));
-      this._height = Math.max(0, this.__height - (t+b));
-      this._model.width(this._width);
-      this._model.height(this._height);
-      if (this._el) this.initialize();
-      this.update({props:"enter"}).update({props:"update"});
-    } else {
-      this.padding(pad).update(opt);
-    }
-    return this;
-  };
-
-  prototype.viewport = function() {
-    if (!arguments.length) return null;
-    return this;
-  };
-
-  prototype.defs = function(defs) {
-    if (!arguments.length) return this._model.defs();
-    this._model.defs(defs);
-    return this;
-  };
-
-  prototype.data = function(data) {
-    if (!arguments.length) return this._model.data();
-    var ingest = vg.keys(data).reduce(function(d, k) {
-      return (d[k] = vg.data.ingestAll(data[k]), d);
-    }, {});
-    this._model.data(ingest);
-    this._build = false;
-    return this;
-  };
-
-  prototype.renderer = function() {
-    return this._renderer;
-  };
-
-  prototype.canvas = function() {
-    return this._canvas;
-  };
-  
-  prototype.canvasAsync = function(callback) {
-    var r = this._renderer, view = this;
-    
-    function wait() {
-      if (r.pendingImages() === 0) {
-        view.render(); // re-render with all images
-        callback(view._canvas);
-      } else {
-        setTimeout(wait, 10);
-      }
-    }
-
-    // if images loading, poll until ready
-    (r.pendingImages() > 0) ? wait() : callback(this._canvas);
-  };
-  
-  prototype.svg = function() {
-    if (this._type !== "svg") return null;
-
-    var p = this._padding,
-        w = this._width  + (p ? p.left + p.right : 0),
-        h = this._height + (p ? p.top + p.bottom : 0);
-
-      // build svg text
-    var svg = d3.select(this._el)
-      .select("svg").node().innerHTML
-      .replace(/ href=/g, " xlink:href="); // ns hack. sigh.
-
-    return '<svg '
-      + 'width="' + w + '" '
-      + 'height="' + h + '" '
-      + vg.config.svgNamespace + '>' + svg + '</svg>'
-  };
-
-  prototype.initialize = function() {    
-    var w = this._width,
-        h = this._height,
-        pad = this._padding;
-    
-    if (this._type === "svg") {
-      this.initSVG(w, h, pad);
-    } else {
-      this.initCanvas(w, h, pad);
-    }
-    
-    return this;
-  };
-  
-  prototype.initCanvas = function(w, h, pad) {
-    var Canvas = require("canvas"),
-        tw = w + pad.left + pad.right,
-        th = h + pad.top + pad.bottom,
-        canvas = this._canvas = new Canvas(tw, th),
-        ctx = canvas.getContext("2d");
-    
-    // setup canvas context
-    ctx.setTransform(1, 0, 0, 1, pad.left, pad.top);
-
-    // configure renderer
-    this._renderer.context(ctx);
-    this._renderer.resize(w, h, pad);
-  };
-  
-  prototype.initSVG = function(w, h, pad) {
-    var tw = w + pad.left + pad.right,
-        th = h + pad.top + pad.bottom;
-
-    // configure renderer
-    this._renderer.initialize(this._el, w, h, pad);
-  }
-  
-  prototype.render = function(items) {
-    this._renderer.render(this._model.scene(), items);
-    return this;
-  };
-  
-  prototype.update = function(opt) {
-    opt = opt || {};
-    var view = this;
-    view._build = view._build || (view._model.build(), true);
-    view._model.encode(null, opt.props, opt.items);
-    view.render(opt.items);
-    return view.autopad(opt);
-  };
-    
-  return view;
-})();
-
-// headless view constructor factory
-// takes definitions from parsed specification as input
-// returns a view constructor
-vg.headless.View.Factory = function(defs) {
-  return function(opt) {
-    opt = opt || {};
-    var w = defs.width,
-        h = defs.height,
-        p = defs.padding,
-        r = opt.renderer || "canvas",
-        v = new vg.headless.View(w, h, p, r).defs(defs);
-    if (defs.data.load) v.data(defs.data.load);
-    if (opt.data) v.data(opt.data);
-    return v;
-  };
-};vg.headless.render = function(opt, callback) {
-  function draw(chart) {
-    try {
-      // create and render view
-      var view = chart({
-        data: opt.data,
-        renderer: opt.renderer
-      }).update();
-
-      if (opt.renderer === "svg") {
-        // extract rendered svg
-        callback(null, {svg: view.svg()});
-      } else {
-        // extract rendered canvas, waiting for any images to load
-        view.canvasAsync(function(canvas) {
-          callback(null, {canvas: canvas});
-        });
-      }
-    } catch (err) {
-      callback(err, null);
-    }
-  }
-
-  vg.parse.spec(opt.spec, draw, vg.headless.View.Factory);
-};  return vg;
-})(d3, typeof topojson === "undefined" ? null : topojson);
-// assumes D3 and topojson in global namespace

+ 0 - 6167
mod/dashboard/app/styles/bootstrap.css

@@ -1,6167 +0,0 @@
-/*!
- * Bootstrap v2.3.2
- *
- * Copyright 2012 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world @twitter by @mdo and @fat.
- */
-
-.clearfix {
-  *zoom: 1;
-}
-
-.clearfix:before,
-.clearfix:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.clearfix:after {
-  clear: both;
-}
-
-.hide-text {
-  font: 0/0 a;
-  color: transparent;
-  text-shadow: none;
-  background-color: transparent;
-  border: 0;
-}
-
-.input-block-level {
-  display: block;
-  width: 100%;
-  min-height: 30px;
-  -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
-}
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-nav,
-section {
-  display: block;
-}
-
-audio,
-canvas,
-video {
-  display: inline-block;
-  *display: inline;
-  *zoom: 1;
-}
-
-audio:not([controls]) {
-  display: none;
-}
-
-html {
-  font-size: 100%;
-  -webkit-text-size-adjust: 100%;
-      -ms-text-size-adjust: 100%;
-}
-
-a:focus {
-  outline: thin dotted #333;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-
-a:hover,
-a:active {
-  outline: 0;
-}
-
-sub,
-sup {
-  position: relative;
-  font-size: 75%;
-  line-height: 0;
-  vertical-align: baseline;
-}
-
-sup {
-  top: -0.5em;
-}
-
-sub {
-  bottom: -0.25em;
-}
-
-img {
-  width: auto\9;
-  height: auto;
-  max-width: 100%;
-  vertical-align: middle;
-  border: 0;
-  -ms-interpolation-mode: bicubic;
-}
-
-#map_canvas img,
-.google-maps img {
-  max-width: none;
-}
-
-button,
-input,
-select,
-textarea {
-  margin: 0;
-  font-size: 100%;
-  vertical-align: middle;
-}
-
-button,
-input {
-  *overflow: visible;
-  line-height: normal;
-}
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-  padding: 0;
-  border: 0;
-}
-
-button,
-html input[type="button"],
-input[type="reset"],
-input[type="submit"] {
-  cursor: pointer;
-  -webkit-appearance: button;
-}
-
-label,
-select,
-button,
-input[type="button"],
-input[type="reset"],
-input[type="submit"],
-input[type="radio"],
-input[type="checkbox"] {
-  cursor: pointer;
-}
-
-input[type="search"] {
-  -webkit-box-sizing: content-box;
-     -moz-box-sizing: content-box;
-          box-sizing: content-box;
-  -webkit-appearance: textfield;
-}
-
-input[type="search"]::-webkit-search-decoration,
-input[type="search"]::-webkit-search-cancel-button {
-  -webkit-appearance: none;
-}
-
-textarea {
-  overflow: auto;
-  vertical-align: top;
-}
-
-@media print {
-  * {
-    color: #000 !important;
-    text-shadow: none !important;
-    background: transparent !important;
-    box-shadow: none !important;
-  }
-  a,
-  a:visited {
-    text-decoration: underline;
-  }
-  a[href]:after {
-    content: " (" attr(href) ")";
-  }
-  abbr[title]:after {
-    content: " (" attr(title) ")";
-  }
-  .ir a:after,
-  a[href^="javascript:"]:after,
-  a[href^="#"]:after {
-    content: "";
-  }
-  pre,
-  blockquote {
-    border: 1px solid #999;
-    page-break-inside: avoid;
-  }
-  thead {
-    display: table-header-group;
-  }
-  tr,
-  img {
-    page-break-inside: avoid;
-  }
-  img {
-    max-width: 100% !important;
-  }
-  @page  {
-    margin: 0.5cm;
-  }
-  p,
-  h2,
-  h3 {
-    orphans: 3;
-    widows: 3;
-  }
-  h2,
-  h3 {
-    page-break-after: avoid;
-  }
-}
-
-body {
-  margin: 0;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: 14px;
-  line-height: 20px;
-  color: #333333;
-  background-color: #ffffff;
-}
-
-a {
-  color: #0088cc;
-  text-decoration: none;
-}
-
-a:hover,
-a:focus {
-  color: #005580;
-  text-decoration: underline;
-}
-
-.img-rounded {
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-}
-
-.img-polaroid {
-  padding: 4px;
-  background-color: #fff;
-  border: 1px solid #ccc;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-}
-
-.img-circle {
-  -webkit-border-radius: 500px;
-     -moz-border-radius: 500px;
-          border-radius: 500px;
-}
-
-.row {
-  margin-left: -20px;
-  *zoom: 1;
-}
-
-.row:before,
-.row:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.row:after {
-  clear: both;
-}
-
-[class*="span"] {
-  float: left;
-  min-height: 1px;
-  margin-left: 20px;
-}
-
-.container,
-.navbar-static-top .container,
-.navbar-fixed-top .container,
-.navbar-fixed-bottom .container {
-  width: 940px;
-}
-
-.span12 {
-  width: 940px;
-}
-
-.span11 {
-  width: 860px;
-}
-
-.span10 {
-  width: 780px;
-}
-
-.span9 {
-  width: 700px;
-}
-
-.span8 {
-  width: 620px;
-}
-
-.span7 {
-  width: 540px;
-}
-
-.span6 {
-  width: 460px;
-}
-
-.span5 {
-  width: 380px;
-}
-
-.span4 {
-  width: 300px;
-}
-
-.span3 {
-  width: 220px;
-}
-
-.span2 {
-  width: 140px;
-}
-
-.span1 {
-  width: 60px;
-}
-
-.offset12 {
-  margin-left: 980px;
-}
-
-.offset11 {
-  margin-left: 900px;
-}
-
-.offset10 {
-  margin-left: 820px;
-}
-
-.offset9 {
-  margin-left: 740px;
-}
-
-.offset8 {
-  margin-left: 660px;
-}
-
-.offset7 {
-  margin-left: 580px;
-}
-
-.offset6 {
-  margin-left: 500px;
-}
-
-.offset5 {
-  margin-left: 420px;
-}
-
-.offset4 {
-  margin-left: 340px;
-}
-
-.offset3 {
-  margin-left: 260px;
-}
-
-.offset2 {
-  margin-left: 180px;
-}
-
-.offset1 {
-  margin-left: 100px;
-}
-
-.row-fluid {
-  width: 100%;
-  *zoom: 1;
-}
-
-.row-fluid:before,
-.row-fluid:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.row-fluid:after {
-  clear: both;
-}
-
-.row-fluid [class*="span"] {
-  display: block;
-  float: left;
-  width: 100%;
-  min-height: 30px;
-  margin-left: 2.127659574468085%;
-  *margin-left: 2.074468085106383%;
-  -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
-}
-
-.row-fluid [class*="span"]:first-child {
-  margin-left: 0;
-}
-
-.row-fluid .controls-row [class*="span"] + [class*="span"] {
-  margin-left: 2.127659574468085%;
-}
-
-.row-fluid .span12 {
-  width: 100%;
-  *width: 99.94680851063829%;
-}
-
-.row-fluid .span11 {
-  width: 91.48936170212765%;
-  *width: 91.43617021276594%;
-}
-
-.row-fluid .span10 {
-  width: 82.97872340425532%;
-  *width: 82.92553191489361%;
-}
-
-.row-fluid .span9 {
-  width: 74.46808510638297%;
-  *width: 74.41489361702126%;
-}
-
-.row-fluid .span8 {
-  width: 65.95744680851064%;
-  *width: 65.90425531914893%;
-}
-
-.row-fluid .span7 {
-  width: 57.44680851063829%;
-  *width: 57.39361702127659%;
-}
-
-.row-fluid .span6 {
-  width: 48.93617021276595%;
-  *width: 48.88297872340425%;
-}
-
-.row-fluid .span5 {
-  width: 40.42553191489362%;
-  *width: 40.37234042553192%;
-}
-
-.row-fluid .span4 {
-  width: 31.914893617021278%;
-  *width: 31.861702127659576%;
-}
-
-.row-fluid .span3 {
-  width: 23.404255319148934%;
-  *width: 23.351063829787233%;
-}
-
-.row-fluid .span2 {
-  width: 14.893617021276595%;
-  *width: 14.840425531914894%;
-}
-
-.row-fluid .span1 {
-  width: 6.382978723404255%;
-  *width: 6.329787234042553%;
-}
-
-.row-fluid .offset12 {
-  margin-left: 104.25531914893617%;
-  *margin-left: 104.14893617021275%;
-}
-
-.row-fluid .offset12:first-child {
-  margin-left: 102.12765957446808%;
-  *margin-left: 102.02127659574467%;
-}
-
-.row-fluid .offset11 {
-  margin-left: 95.74468085106382%;
-  *margin-left: 95.6382978723404%;
-}
-
-.row-fluid .offset11:first-child {
-  margin-left: 93.61702127659574%;
-  *margin-left: 93.51063829787232%;
-}
-
-.row-fluid .offset10 {
-  margin-left: 87.23404255319149%;
-  *margin-left: 87.12765957446807%;
-}
-
-.row-fluid .offset10:first-child {
-  margin-left: 85.1063829787234%;
-  *margin-left: 84.99999999999999%;
-}
-
-.row-fluid .offset9 {
-  margin-left: 78.72340425531914%;
-  *margin-left: 78.61702127659572%;
-}
-
-.row-fluid .offset9:first-child {
-  margin-left: 76.59574468085106%;
-  *margin-left: 76.48936170212764%;
-}
-
-.row-fluid .offset8 {
-  margin-left: 70.2127659574468%;
-  *margin-left: 70.10638297872339%;
-}
-
-.row-fluid .offset8:first-child {
-  margin-left: 68.08510638297872%;
-  *margin-left: 67.9787234042553%;
-}
-
-.row-fluid .offset7 {
-  margin-left: 61.70212765957446%;
-  *margin-left: 61.59574468085106%;
-}
-
-.row-fluid .offset7:first-child {
-  margin-left: 59.574468085106375%;
-  *margin-left: 59.46808510638297%;
-}
-
-.row-fluid .offset6 {
-  margin-left: 53.191489361702125%;
-  *margin-left: 53.085106382978715%;
-}
-
-.row-fluid .offset6:first-child {
-  margin-left: 51.063829787234035%;
-  *margin-left: 50.95744680851063%;
-}
-
-.row-fluid .offset5 {
-  margin-left: 44.68085106382979%;
-  *margin-left: 44.57446808510638%;
-}
-
-.row-fluid .offset5:first-child {
-  margin-left: 42.5531914893617%;
-  *margin-left: 42.4468085106383%;
-}
-
-.row-fluid .offset4 {
-  margin-left: 36.170212765957444%;
-  *margin-left: 36.06382978723405%;
-}
-
-.row-fluid .offset4:first-child {
-  margin-left: 34.04255319148936%;
-  *margin-left: 33.93617021276596%;
-}
-
-.row-fluid .offset3 {
-  margin-left: 27.659574468085104%;
-  *margin-left: 27.5531914893617%;
-}
-
-.row-fluid .offset3:first-child {
-  margin-left: 25.53191489361702%;
-  *margin-left: 25.425531914893618%;
-}
-
-.row-fluid .offset2 {
-  margin-left: 19.148936170212764%;
-  *margin-left: 19.04255319148936%;
-}
-
-.row-fluid .offset2:first-child {
-  margin-left: 17.02127659574468%;
-  *margin-left: 16.914893617021278%;
-}
-
-.row-fluid .offset1 {
-  margin-left: 10.638297872340425%;
-  *margin-left: 10.53191489361702%;
-}
-
-.row-fluid .offset1:first-child {
-  margin-left: 8.51063829787234%;
-  *margin-left: 8.404255319148938%;
-}
-
-[class*="span"].hide,
-.row-fluid [class*="span"].hide {
-  display: none;
-}
-
-[class*="span"].pull-right,
-.row-fluid [class*="span"].pull-right {
-  float: right;
-}
-
-.container {
-  margin-right: auto;
-  margin-left: auto;
-  *zoom: 1;
-}
-
-.container:before,
-.container:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.container:after {
-  clear: both;
-}
-
-.container-fluid {
-  padding-right: 20px;
-  padding-left: 20px;
-  *zoom: 1;
-}
-
-.container-fluid:before,
-.container-fluid:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.container-fluid:after {
-  clear: both;
-}
-
-p {
-  margin: 0 0 10px;
-}
-
-.lead {
-  margin-bottom: 20px;
-  font-size: 21px;
-  font-weight: 200;
-  line-height: 30px;
-}
-
-small {
-  font-size: 85%;
-}
-
-strong {
-  font-weight: bold;
-}
-
-em {
-  font-style: italic;
-}
-
-cite {
-  font-style: normal;
-}
-
-.muted {
-  color: #999999;
-}
-
-a.muted:hover,
-a.muted:focus {
-  color: #808080;
-}
-
-.text-warning {
-  color: #c09853;
-}
-
-a.text-warning:hover,
-a.text-warning:focus {
-  color: #a47e3c;
-}
-
-.text-error {
-  color: #b94a48;
-}
-
-a.text-error:hover,
-a.text-error:focus {
-  color: #953b39;
-}
-
-.text-info {
-  color: #3a87ad;
-}
-
-a.text-info:hover,
-a.text-info:focus {
-  color: #2d6987;
-}
-
-.text-success {
-  color: #468847;
-}
-
-a.text-success:hover,
-a.text-success:focus {
-  color: #356635;
-}
-
-.text-left {
-  text-align: left;
-}
-
-.text-right {
-  text-align: right;
-}
-
-.text-center {
-  text-align: center;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
-  margin: 10px 0;
-  font-family: inherit;
-  font-weight: bold;
-  line-height: 20px;
-  color: inherit;
-  text-rendering: optimizelegibility;
-}
-
-h1 small,
-h2 small,
-h3 small,
-h4 small,
-h5 small,
-h6 small {
-  font-weight: normal;
-  line-height: 1;
-  color: #999999;
-}
-
-h1,
-h2,
-h3 {
-  line-height: 40px;
-}
-
-h1 {
-  font-size: 38.5px;
-}
-
-h2 {
-  font-size: 31.5px;
-}
-
-h3 {
-  font-size: 24.5px;
-}
-
-h4 {
-  font-size: 17.5px;
-}
-
-h5 {
-  font-size: 14px;
-}
-
-h6 {
-  font-size: 11.9px;
-}
-
-h1 small {
-  font-size: 24.5px;
-}
-
-h2 small {
-  font-size: 17.5px;
-}
-
-h3 small {
-  font-size: 14px;
-}
-
-h4 small {
-  font-size: 14px;
-}
-
-.page-header {
-  padding-bottom: 9px;
-  margin: 20px 0 30px;
-  border-bottom: 1px solid #eeeeee;
-}
-
-ul,
-ol {
-  padding: 0;
-  margin: 0 0 10px 25px;
-}
-
-ul ul,
-ul ol,
-ol ol,
-ol ul {
-  margin-bottom: 0;
-}
-
-li {
-  line-height: 20px;
-}
-
-ul.unstyled,
-ol.unstyled {
-  margin-left: 0;
-  list-style: none;
-}
-
-ul.inline,
-ol.inline {
-  margin-left: 0;
-  list-style: none;
-}
-
-ul.inline > li,
-ol.inline > li {
-  display: inline-block;
-  *display: inline;
-  padding-right: 5px;
-  padding-left: 5px;
-  *zoom: 1;
-}
-
-dl {
-  margin-bottom: 20px;
-}
-
-dt,
-dd {
-  line-height: 20px;
-}
-
-dt {
-  font-weight: bold;
-}
-
-dd {
-  margin-left: 10px;
-}
-
-.dl-horizontal {
-  *zoom: 1;
-}
-
-.dl-horizontal:before,
-.dl-horizontal:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.dl-horizontal:after {
-  clear: both;
-}
-
-.dl-horizontal dt {
-  float: left;
-  width: 160px;
-  overflow: hidden;
-  clear: left;
-  text-align: right;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.dl-horizontal dd {
-  margin-left: 180px;
-}
-
-hr {
-  margin: 20px 0;
-  border: 0;
-  border-top: 1px solid #eeeeee;
-  border-bottom: 1px solid #ffffff;
-}
-
-abbr[title],
-abbr[data-original-title] {
-  cursor: help;
-  border-bottom: 1px dotted #999999;
-}
-
-abbr.initialism {
-  font-size: 90%;
-  text-transform: uppercase;
-}
-
-blockquote {
-  padding: 0 0 0 15px;
-  margin: 0 0 20px;
-  border-left: 5px solid #eeeeee;
-}
-
-blockquote p {
-  margin-bottom: 0;
-  font-size: 17.5px;
-  font-weight: 300;
-  line-height: 1.25;
-}
-
-blockquote small {
-  display: block;
-  line-height: 20px;
-  color: #999999;
-}
-
-blockquote small:before {
-  content: '\2014 \00A0';
-}
-
-blockquote.pull-right {
-  float: right;
-  padding-right: 15px;
-  padding-left: 0;
-  border-right: 5px solid #eeeeee;
-  border-left: 0;
-}
-
-blockquote.pull-right p,
-blockquote.pull-right small {
-  text-align: right;
-}
-
-blockquote.pull-right small:before {
-  content: '';
-}
-
-blockquote.pull-right small:after {
-  content: '\00A0 \2014';
-}
-
-q:before,
-q:after,
-blockquote:before,
-blockquote:after {
-  content: "";
-}
-
-address {
-  display: block;
-  margin-bottom: 20px;
-  font-style: normal;
-  line-height: 20px;
-}
-
-code,
-pre {
-  padding: 0 3px 2px;
-  font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
-  font-size: 12px;
-  color: #333333;
-  -webkit-border-radius: 3px;
-     -moz-border-radius: 3px;
-          border-radius: 3px;
-}
-
-code {
-  padding: 2px 4px;
-  color: #d14;
-  white-space: nowrap;
-  background-color: #f7f7f9;
-  border: 1px solid #e1e1e8;
-}
-
-pre {
-  display: block;
-  padding: 9.5px;
-  margin: 0 0 10px;
-  font-size: 13px;
-  line-height: 20px;
-  word-break: break-all;
-  word-wrap: break-word;
-  white-space: pre;
-  white-space: pre-wrap;
-  background-color: #f5f5f5;
-  border: 1px solid #ccc;
-  border: 1px solid rgba(0, 0, 0, 0.15);
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-pre.prettyprint {
-  margin-bottom: 20px;
-}
-
-pre code {
-  padding: 0;
-  color: inherit;
-  white-space: pre;
-  white-space: pre-wrap;
-  background-color: transparent;
-  border: 0;
-}
-
-.pre-scrollable {
-  max-height: 340px;
-  overflow-y: scroll;
-}
-
-form {
-  margin: 0 0 20px;
-}
-
-fieldset {
-  padding: 0;
-  margin: 0;
-  border: 0;
-}
-
-legend {
-  display: block;
-  width: 100%;
-  padding: 0;
-  margin-bottom: 20px;
-  font-size: 21px;
-  line-height: 40px;
-  color: #333333;
-  border: 0;
-  border-bottom: 1px solid #e5e5e5;
-}
-
-legend small {
-  font-size: 15px;
-  color: #999999;
-}
-
-label,
-input,
-button,
-select,
-textarea {
-  font-size: 14px;
-  font-weight: normal;
-  line-height: 20px;
-}
-
-input,
-button,
-select,
-textarea {
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-}
-
-label {
-  display: block;
-  margin-bottom: 5px;
-}
-
-select,
-textarea,
-input[type="text"],
-input[type="password"],
-input[type="datetime"],
-input[type="datetime-local"],
-input[type="date"],
-input[type="month"],
-input[type="time"],
-input[type="week"],
-input[type="number"],
-input[type="email"],
-input[type="url"],
-input[type="search"],
-input[type="tel"],
-input[type="color"],
-.uneditable-input {
-  display: inline-block;
-  height: 20px;
-  padding: 4px 6px;
-  margin-bottom: 10px;
-  font-size: 14px;
-  line-height: 20px;
-  color: #555555;
-  vertical-align: middle;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-input,
-textarea,
-.uneditable-input {
-  width: 206px;
-}
-
-textarea {
-  height: auto;
-}
-
-textarea,
-input[type="text"],
-input[type="password"],
-input[type="datetime"],
-input[type="datetime-local"],
-input[type="date"],
-input[type="month"],
-input[type="time"],
-input[type="week"],
-input[type="number"],
-input[type="email"],
-input[type="url"],
-input[type="search"],
-input[type="tel"],
-input[type="color"],
-.uneditable-input {
-  background-color: #ffffff;
-  border: 1px solid #cccccc;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
-     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
-       -o-transition: border linear 0.2s, box-shadow linear 0.2s;
-          transition: border linear 0.2s, box-shadow linear 0.2s;
-}
-
-textarea:focus,
-input[type="text"]:focus,
-input[type="password"]:focus,
-input[type="datetime"]:focus,
-input[type="datetime-local"]:focus,
-input[type="date"]:focus,
-input[type="month"]:focus,
-input[type="time"]:focus,
-input[type="week"]:focus,
-input[type="number"]:focus,
-input[type="email"]:focus,
-input[type="url"]:focus,
-input[type="search"]:focus,
-input[type="tel"]:focus,
-input[type="color"]:focus,
-.uneditable-input:focus {
-  border-color: rgba(82, 168, 236, 0.8);
-  outline: 0;
-  outline: thin dotted \9;
-  /* IE6-9 */
-
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-}
-
-input[type="radio"],
-input[type="checkbox"] {
-  margin: 4px 0 0;
-  margin-top: 1px \9;
-  *margin-top: 0;
-  line-height: normal;
-}
-
-input[type="file"],
-input[type="image"],
-input[type="submit"],
-input[type="reset"],
-input[type="button"],
-input[type="radio"],
-input[type="checkbox"] {
-  width: auto;
-}
-
-select,
-input[type="file"] {
-  height: 30px;
-  /* In IE7, the height of the select element cannot be changed by height, only font-size */
-
-  *margin-top: 4px;
-  /* For IE7, add top margin to align select with labels */
-
-  line-height: 30px;
-}
-
-select {
-  width: 220px;
-  background-color: #ffffff;
-  border: 1px solid #cccccc;
-}
-
-select[multiple],
-select[size] {
-  height: auto;
-}
-
-select:focus,
-input[type="file"]:focus,
-input[type="radio"]:focus,
-input[type="checkbox"]:focus {
-  outline: thin dotted #333;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-
-.uneditable-input,
-.uneditable-textarea {
-  color: #999999;
-  cursor: not-allowed;
-  background-color: #fcfcfc;
-  border-color: #cccccc;
-  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
-     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
-          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
-}
-
-.uneditable-input {
-  overflow: hidden;
-  white-space: nowrap;
-}
-
-.uneditable-textarea {
-  width: auto;
-  height: auto;
-}
-
-input:-moz-placeholder,
-textarea:-moz-placeholder {
-  color: #999999;
-}
-
-input:-ms-input-placeholder,
-textarea:-ms-input-placeholder {
-  color: #999999;
-}
-
-input::-webkit-input-placeholder,
-textarea::-webkit-input-placeholder {
-  color: #999999;
-}
-
-.radio,
-.checkbox {
-  min-height: 20px;
-  padding-left: 20px;
-}
-
-.radio input[type="radio"],
-.checkbox input[type="checkbox"] {
-  float: left;
-  margin-left: -20px;
-}
-
-.controls > .radio:first-child,
-.controls > .checkbox:first-child {
-  padding-top: 5px;
-}
-
-.radio.inline,
-.checkbox.inline {
-  display: inline-block;
-  padding-top: 5px;
-  margin-bottom: 0;
-  vertical-align: middle;
-}
-
-.radio.inline + .radio.inline,
-.checkbox.inline + .checkbox.inline {
-  margin-left: 10px;
-}
-
-.input-mini {
-  width: 60px;
-}
-
-.input-small {
-  width: 90px;
-}
-
-.input-medium {
-  width: 150px;
-}
-
-.input-large {
-  width: 210px;
-}
-
-.input-xlarge {
-  width: 270px;
-}
-
-.input-xxlarge {
-  width: 530px;
-}
-
-input[class*="span"],
-select[class*="span"],
-textarea[class*="span"],
-.uneditable-input[class*="span"],
-.row-fluid input[class*="span"],
-.row-fluid select[class*="span"],
-.row-fluid textarea[class*="span"],
-.row-fluid .uneditable-input[class*="span"] {
-  float: none;
-  margin-left: 0;
-}
-
-.input-append input[class*="span"],
-.input-append .uneditable-input[class*="span"],
-.input-prepend input[class*="span"],
-.input-prepend .uneditable-input[class*="span"],
-.row-fluid input[class*="span"],
-.row-fluid select[class*="span"],
-.row-fluid textarea[class*="span"],
-.row-fluid .uneditable-input[class*="span"],
-.row-fluid .input-prepend [class*="span"],
-.row-fluid .input-append [class*="span"] {
-  display: inline-block;
-}
-
-input,
-textarea,
-.uneditable-input {
-  margin-left: 0;
-}
-
-.controls-row [class*="span"] + [class*="span"] {
-  margin-left: 20px;
-}
-
-input.span12,
-textarea.span12,
-.uneditable-input.span12 {
-  width: 926px;
-}
-
-input.span11,
-textarea.span11,
-.uneditable-input.span11 {
-  width: 846px;
-}
-
-input.span10,
-textarea.span10,
-.uneditable-input.span10 {
-  width: 766px;
-}
-
-input.span9,
-textarea.span9,
-.uneditable-input.span9 {
-  width: 686px;
-}
-
-input.span8,
-textarea.span8,
-.uneditable-input.span8 {
-  width: 606px;
-}
-
-input.span7,
-textarea.span7,
-.uneditable-input.span7 {
-  width: 526px;
-}
-
-input.span6,
-textarea.span6,
-.uneditable-input.span6 {
-  width: 446px;
-}
-
-input.span5,
-textarea.span5,
-.uneditable-input.span5 {
-  width: 366px;
-}
-
-input.span4,
-textarea.span4,
-.uneditable-input.span4 {
-  width: 286px;
-}
-
-input.span3,
-textarea.span3,
-.uneditable-input.span3 {
-  width: 206px;
-}
-
-input.span2,
-textarea.span2,
-.uneditable-input.span2 {
-  width: 126px;
-}
-
-input.span1,
-textarea.span1,
-.uneditable-input.span1 {
-  width: 46px;
-}
-
-.controls-row {
-  *zoom: 1;
-}
-
-.controls-row:before,
-.controls-row:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.controls-row:after {
-  clear: both;
-}
-
-.controls-row [class*="span"],
-.row-fluid .controls-row [class*="span"] {
-  float: left;
-}
-
-.controls-row .checkbox[class*="span"],
-.controls-row .radio[class*="span"] {
-  padding-top: 5px;
-}
-
-input[disabled],
-select[disabled],
-textarea[disabled],
-input[readonly],
-select[readonly],
-textarea[readonly] {
-  cursor: not-allowed;
-  background-color: #eeeeee;
-}
-
-input[type="radio"][disabled],
-input[type="checkbox"][disabled],
-input[type="radio"][readonly],
-input[type="checkbox"][readonly] {
-  background-color: transparent;
-}
-
-.control-group.warning .control-label,
-.control-group.warning .help-block,
-.control-group.warning .help-inline {
-  color: #c09853;
-}
-
-.control-group.warning .checkbox,
-.control-group.warning .radio,
-.control-group.warning input,
-.control-group.warning select,
-.control-group.warning textarea {
-  color: #c09853;
-}
-
-.control-group.warning input,
-.control-group.warning select,
-.control-group.warning textarea {
-  border-color: #c09853;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-}
-
-.control-group.warning input:focus,
-.control-group.warning select:focus,
-.control-group.warning textarea:focus {
-  border-color: #a47e3c;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
-}
-
-.control-group.warning .input-prepend .add-on,
-.control-group.warning .input-append .add-on {
-  color: #c09853;
-  background-color: #fcf8e3;
-  border-color: #c09853;
-}
-
-.control-group.error .control-label,
-.control-group.error .help-block,
-.control-group.error .help-inline {
-  color: #b94a48;
-}
-
-.control-group.error .checkbox,
-.control-group.error .radio,
-.control-group.error input,
-.control-group.error select,
-.control-group.error textarea {
-  color: #b94a48;
-}
-
-.control-group.error input,
-.control-group.error select,
-.control-group.error textarea {
-  border-color: #b94a48;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-}
-
-.control-group.error input:focus,
-.control-group.error select:focus,
-.control-group.error textarea:focus {
-  border-color: #953b39;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
-}
-
-.control-group.error .input-prepend .add-on,
-.control-group.error .input-append .add-on {
-  color: #b94a48;
-  background-color: #f2dede;
-  border-color: #b94a48;
-}
-
-.control-group.success .control-label,
-.control-group.success .help-block,
-.control-group.success .help-inline {
-  color: #468847;
-}
-
-.control-group.success .checkbox,
-.control-group.success .radio,
-.control-group.success input,
-.control-group.success select,
-.control-group.success textarea {
-  color: #468847;
-}
-
-.control-group.success input,
-.control-group.success select,
-.control-group.success textarea {
-  border-color: #468847;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-}
-
-.control-group.success input:focus,
-.control-group.success select:focus,
-.control-group.success textarea:focus {
-  border-color: #356635;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
-}
-
-.control-group.success .input-prepend .add-on,
-.control-group.success .input-append .add-on {
-  color: #468847;
-  background-color: #dff0d8;
-  border-color: #468847;
-}
-
-.control-group.info .control-label,
-.control-group.info .help-block,
-.control-group.info .help-inline {
-  color: #3a87ad;
-}
-
-.control-group.info .checkbox,
-.control-group.info .radio,
-.control-group.info input,
-.control-group.info select,
-.control-group.info textarea {
-  color: #3a87ad;
-}
-
-.control-group.info input,
-.control-group.info select,
-.control-group.info textarea {
-  border-color: #3a87ad;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-}
-
-.control-group.info input:focus,
-.control-group.info select:focus,
-.control-group.info textarea:focus {
-  border-color: #2d6987;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
-}
-
-.control-group.info .input-prepend .add-on,
-.control-group.info .input-append .add-on {
-  color: #3a87ad;
-  background-color: #d9edf7;
-  border-color: #3a87ad;
-}
-
-input:focus:invalid,
-textarea:focus:invalid,
-select:focus:invalid {
-  color: #b94a48;
-  border-color: #ee5f5b;
-}
-
-input:focus:invalid:focus,
-textarea:focus:invalid:focus,
-select:focus:invalid:focus {
-  border-color: #e9322d;
-  -webkit-box-shadow: 0 0 6px #f8b9b7;
-     -moz-box-shadow: 0 0 6px #f8b9b7;
-          box-shadow: 0 0 6px #f8b9b7;
-}
-
-.form-actions {
-  padding: 19px 20px 20px;
-  margin-top: 20px;
-  margin-bottom: 20px;
-  background-color: #f5f5f5;
-  border-top: 1px solid #e5e5e5;
-  *zoom: 1;
-}
-
-.form-actions:before,
-.form-actions:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.form-actions:after {
-  clear: both;
-}
-
-.help-block,
-.help-inline {
-  color: #595959;
-}
-
-.help-block {
-  display: block;
-  margin-bottom: 10px;
-}
-
-.help-inline {
-  display: inline-block;
-  *display: inline;
-  padding-left: 5px;
-  vertical-align: middle;
-  *zoom: 1;
-}
-
-.input-append,
-.input-prepend {
-  display: inline-block;
-  margin-bottom: 10px;
-  font-size: 0;
-  white-space: nowrap;
-  vertical-align: middle;
-}
-
-.input-append input,
-.input-prepend input,
-.input-append select,
-.input-prepend select,
-.input-append .uneditable-input,
-.input-prepend .uneditable-input,
-.input-append .dropdown-menu,
-.input-prepend .dropdown-menu,
-.input-append .popover,
-.input-prepend .popover {
-  font-size: 14px;
-}
-
-.input-append input,
-.input-prepend input,
-.input-append select,
-.input-prepend select,
-.input-append .uneditable-input,
-.input-prepend .uneditable-input {
-  position: relative;
-  margin-bottom: 0;
-  *margin-left: 0;
-  vertical-align: top;
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.input-append input:focus,
-.input-prepend input:focus,
-.input-append select:focus,
-.input-prepend select:focus,
-.input-append .uneditable-input:focus,
-.input-prepend .uneditable-input:focus {
-  z-index: 2;
-}
-
-.input-append .add-on,
-.input-prepend .add-on {
-  display: inline-block;
-  width: auto;
-  height: 20px;
-  min-width: 16px;
-  padding: 4px 5px;
-  font-size: 14px;
-  font-weight: normal;
-  line-height: 20px;
-  text-align: center;
-  text-shadow: 0 1px 0 #ffffff;
-  background-color: #eeeeee;
-  border: 1px solid #ccc;
-}
-
-.input-append .add-on,
-.input-prepend .add-on,
-.input-append .btn,
-.input-prepend .btn,
-.input-append .btn-group > .dropdown-toggle,
-.input-prepend .btn-group > .dropdown-toggle {
-  vertical-align: top;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.input-append .active,
-.input-prepend .active {
-  background-color: #a9dba9;
-  border-color: #46a546;
-}
-
-.input-prepend .add-on,
-.input-prepend .btn {
-  margin-right: -1px;
-}
-
-.input-prepend .add-on:first-child,
-.input-prepend .btn:first-child {
-  -webkit-border-radius: 4px 0 0 4px;
-     -moz-border-radius: 4px 0 0 4px;
-          border-radius: 4px 0 0 4px;
-}
-
-.input-append input,
-.input-append select,
-.input-append .uneditable-input {
-  -webkit-border-radius: 4px 0 0 4px;
-     -moz-border-radius: 4px 0 0 4px;
-          border-radius: 4px 0 0 4px;
-}
-
-.input-append input + .btn-group .btn:last-child,
-.input-append select + .btn-group .btn:last-child,
-.input-append .uneditable-input + .btn-group .btn:last-child {
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.input-append .add-on,
-.input-append .btn,
-.input-append .btn-group {
-  margin-left: -1px;
-}
-
-.input-append .add-on:last-child,
-.input-append .btn:last-child,
-.input-append .btn-group:last-child > .dropdown-toggle {
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.input-prepend.input-append input,
-.input-prepend.input-append select,
-.input-prepend.input-append .uneditable-input {
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.input-prepend.input-append input + .btn-group .btn,
-.input-prepend.input-append select + .btn-group .btn,
-.input-prepend.input-append .uneditable-input + .btn-group .btn {
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.input-prepend.input-append .add-on:first-child,
-.input-prepend.input-append .btn:first-child {
-  margin-right: -1px;
-  -webkit-border-radius: 4px 0 0 4px;
-     -moz-border-radius: 4px 0 0 4px;
-          border-radius: 4px 0 0 4px;
-}
-
-.input-prepend.input-append .add-on:last-child,
-.input-prepend.input-append .btn:last-child {
-  margin-left: -1px;
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.input-prepend.input-append .btn-group:first-child {
-  margin-left: 0;
-}
-
-input.search-query {
-  padding-right: 14px;
-  padding-right: 4px \9;
-  padding-left: 14px;
-  padding-left: 4px \9;
-  /* IE7-8 doesn't have border-radius, so don't indent the padding */
-
-  margin-bottom: 0;
-  -webkit-border-radius: 15px;
-     -moz-border-radius: 15px;
-          border-radius: 15px;
-}
-
-/* Allow for input prepend/append in search forms */
-
-.form-search .input-append .search-query,
-.form-search .input-prepend .search-query {
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.form-search .input-append .search-query {
-  -webkit-border-radius: 14px 0 0 14px;
-     -moz-border-radius: 14px 0 0 14px;
-          border-radius: 14px 0 0 14px;
-}
-
-.form-search .input-append .btn {
-  -webkit-border-radius: 0 14px 14px 0;
-     -moz-border-radius: 0 14px 14px 0;
-          border-radius: 0 14px 14px 0;
-}
-
-.form-search .input-prepend .search-query {
-  -webkit-border-radius: 0 14px 14px 0;
-     -moz-border-radius: 0 14px 14px 0;
-          border-radius: 0 14px 14px 0;
-}
-
-.form-search .input-prepend .btn {
-  -webkit-border-radius: 14px 0 0 14px;
-     -moz-border-radius: 14px 0 0 14px;
-          border-radius: 14px 0 0 14px;
-}
-
-.form-search input,
-.form-inline input,
-.form-horizontal input,
-.form-search textarea,
-.form-inline textarea,
-.form-horizontal textarea,
-.form-search select,
-.form-inline select,
-.form-horizontal select,
-.form-search .help-inline,
-.form-inline .help-inline,
-.form-horizontal .help-inline,
-.form-search .uneditable-input,
-.form-inline .uneditable-input,
-.form-horizontal .uneditable-input,
-.form-search .input-prepend,
-.form-inline .input-prepend,
-.form-horizontal .input-prepend,
-.form-search .input-append,
-.form-inline .input-append,
-.form-horizontal .input-append {
-  display: inline-block;
-  *display: inline;
-  margin-bottom: 0;
-  vertical-align: middle;
-  *zoom: 1;
-}
-
-.form-search .hide,
-.form-inline .hide,
-.form-horizontal .hide {
-  display: none;
-}
-
-.form-search label,
-.form-inline label,
-.form-search .btn-group,
-.form-inline .btn-group {
-  display: inline-block;
-}
-
-.form-search .input-append,
-.form-inline .input-append,
-.form-search .input-prepend,
-.form-inline .input-prepend {
-  margin-bottom: 0;
-}
-
-.form-search .radio,
-.form-search .checkbox,
-.form-inline .radio,
-.form-inline .checkbox {
-  padding-left: 0;
-  margin-bottom: 0;
-  vertical-align: middle;
-}
-
-.form-search .radio input[type="radio"],
-.form-search .checkbox input[type="checkbox"],
-.form-inline .radio input[type="radio"],
-.form-inline .checkbox input[type="checkbox"] {
-  float: left;
-  margin-right: 3px;
-  margin-left: 0;
-}
-
-.control-group {
-  margin-bottom: 10px;
-}
-
-legend + .control-group {
-  margin-top: 20px;
-  -webkit-margin-top-collapse: separate;
-}
-
-.form-horizontal .control-group {
-  margin-bottom: 20px;
-  *zoom: 1;
-}
-
-.form-horizontal .control-group:before,
-.form-horizontal .control-group:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.form-horizontal .control-group:after {
-  clear: both;
-}
-
-.form-horizontal .control-label {
-  float: left;
-  width: 160px;
-  padding-top: 5px;
-  text-align: right;
-}
-
-.form-horizontal .controls {
-  *display: inline-block;
-  *padding-left: 20px;
-  margin-left: 180px;
-  *margin-left: 0;
-}
-
-.form-horizontal .controls:first-child {
-  *padding-left: 180px;
-}
-
-.form-horizontal .help-block {
-  margin-bottom: 0;
-}
-
-.form-horizontal input + .help-block,
-.form-horizontal select + .help-block,
-.form-horizontal textarea + .help-block,
-.form-horizontal .uneditable-input + .help-block,
-.form-horizontal .input-prepend + .help-block,
-.form-horizontal .input-append + .help-block {
-  margin-top: 10px;
-}
-
-.form-horizontal .form-actions {
-  padding-left: 180px;
-}
-
-table {
-  max-width: 100%;
-  background-color: transparent;
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-.table {
-  width: 100%;
-  margin-bottom: 20px;
-}
-
-.table th,
-.table td {
-  padding: 8px;
-  line-height: 20px;
-  text-align: left;
-  vertical-align: top;
-  border-top: 1px solid #dddddd;
-}
-
-.table th {
-  font-weight: bold;
-}
-
-.table thead th {
-  vertical-align: bottom;
-}
-
-.table caption + thead tr:first-child th,
-.table caption + thead tr:first-child td,
-.table colgroup + thead tr:first-child th,
-.table colgroup + thead tr:first-child td,
-.table thead:first-child tr:first-child th,
-.table thead:first-child tr:first-child td {
-  border-top: 0;
-}
-
-.table tbody + tbody {
-  border-top: 2px solid #dddddd;
-}
-
-.table .table {
-  background-color: #ffffff;
-}
-
-.table-condensed th,
-.table-condensed td {
-  padding: 4px 5px;
-}
-
-.table-bordered {
-  border: 1px solid #dddddd;
-  border-collapse: separate;
-  *border-collapse: collapse;
-  border-left: 0;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.table-bordered th,
-.table-bordered td {
-  border-left: 1px solid #dddddd;
-}
-
-.table-bordered caption + thead tr:first-child th,
-.table-bordered caption + tbody tr:first-child th,
-.table-bordered caption + tbody tr:first-child td,
-.table-bordered colgroup + thead tr:first-child th,
-.table-bordered colgroup + tbody tr:first-child th,
-.table-bordered colgroup + tbody tr:first-child td,
-.table-bordered thead:first-child tr:first-child th,
-.table-bordered tbody:first-child tr:first-child th,
-.table-bordered tbody:first-child tr:first-child td {
-  border-top: 0;
-}
-
-.table-bordered thead:first-child tr:first-child > th:first-child,
-.table-bordered tbody:first-child tr:first-child > td:first-child,
-.table-bordered tbody:first-child tr:first-child > th:first-child {
-  -webkit-border-top-left-radius: 4px;
-          border-top-left-radius: 4px;
-  -moz-border-radius-topleft: 4px;
-}
-
-.table-bordered thead:first-child tr:first-child > th:last-child,
-.table-bordered tbody:first-child tr:first-child > td:last-child,
-.table-bordered tbody:first-child tr:first-child > th:last-child {
-  -webkit-border-top-right-radius: 4px;
-          border-top-right-radius: 4px;
-  -moz-border-radius-topright: 4px;
-}
-
-.table-bordered thead:last-child tr:last-child > th:first-child,
-.table-bordered tbody:last-child tr:last-child > td:first-child,
-.table-bordered tbody:last-child tr:last-child > th:first-child,
-.table-bordered tfoot:last-child tr:last-child > td:first-child,
-.table-bordered tfoot:last-child tr:last-child > th:first-child {
-  -webkit-border-bottom-left-radius: 4px;
-          border-bottom-left-radius: 4px;
-  -moz-border-radius-bottomleft: 4px;
-}
-
-.table-bordered thead:last-child tr:last-child > th:last-child,
-.table-bordered tbody:last-child tr:last-child > td:last-child,
-.table-bordered tbody:last-child tr:last-child > th:last-child,
-.table-bordered tfoot:last-child tr:last-child > td:last-child,
-.table-bordered tfoot:last-child tr:last-child > th:last-child {
-  -webkit-border-bottom-right-radius: 4px;
-          border-bottom-right-radius: 4px;
-  -moz-border-radius-bottomright: 4px;
-}
-
-.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {
-  -webkit-border-bottom-left-radius: 0;
-          border-bottom-left-radius: 0;
-  -moz-border-radius-bottomleft: 0;
-}
-
-.table-bordered tfoot + tbody:last-child tr:last-child td:last-child {
-  -webkit-border-bottom-right-radius: 0;
-          border-bottom-right-radius: 0;
-  -moz-border-radius-bottomright: 0;
-}
-
-.table-bordered caption + thead tr:first-child th:first-child,
-.table-bordered caption + tbody tr:first-child td:first-child,
-.table-bordered colgroup + thead tr:first-child th:first-child,
-.table-bordered colgroup + tbody tr:first-child td:first-child {
-  -webkit-border-top-left-radius: 4px;
-          border-top-left-radius: 4px;
-  -moz-border-radius-topleft: 4px;
-}
-
-.table-bordered caption + thead tr:first-child th:last-child,
-.table-bordered caption + tbody tr:first-child td:last-child,
-.table-bordered colgroup + thead tr:first-child th:last-child,
-.table-bordered colgroup + tbody tr:first-child td:last-child {
-  -webkit-border-top-right-radius: 4px;
-          border-top-right-radius: 4px;
-  -moz-border-radius-topright: 4px;
-}
-
-.table-striped tbody > tr:nth-child(odd) > td,
-.table-striped tbody > tr:nth-child(odd) > th {
-  background-color: #f9f9f9;
-}
-
-.table-hover tbody tr:hover > td,
-.table-hover tbody tr:hover > th {
-  background-color: #f5f5f5;
-}
-
-table td[class*="span"],
-table th[class*="span"],
-.row-fluid table td[class*="span"],
-.row-fluid table th[class*="span"] {
-  display: table-cell;
-  float: none;
-  margin-left: 0;
-}
-
-.table td.span1,
-.table th.span1 {
-  float: none;
-  width: 44px;
-  margin-left: 0;
-}
-
-.table td.span2,
-.table th.span2 {
-  float: none;
-  width: 124px;
-  margin-left: 0;
-}
-
-.table td.span3,
-.table th.span3 {
-  float: none;
-  width: 204px;
-  margin-left: 0;
-}
-
-.table td.span4,
-.table th.span4 {
-  float: none;
-  width: 284px;
-  margin-left: 0;
-}
-
-.table td.span5,
-.table th.span5 {
-  float: none;
-  width: 364px;
-  margin-left: 0;
-}
-
-.table td.span6,
-.table th.span6 {
-  float: none;
-  width: 444px;
-  margin-left: 0;
-}
-
-.table td.span7,
-.table th.span7 {
-  float: none;
-  width: 524px;
-  margin-left: 0;
-}
-
-.table td.span8,
-.table th.span8 {
-  float: none;
-  width: 604px;
-  margin-left: 0;
-}
-
-.table td.span9,
-.table th.span9 {
-  float: none;
-  width: 684px;
-  margin-left: 0;
-}
-
-.table td.span10,
-.table th.span10 {
-  float: none;
-  width: 764px;
-  margin-left: 0;
-}
-
-.table td.span11,
-.table th.span11 {
-  float: none;
-  width: 844px;
-  margin-left: 0;
-}
-
-.table td.span12,
-.table th.span12 {
-  float: none;
-  width: 924px;
-  margin-left: 0;
-}
-
-.table tbody tr.success > td {
-  background-color: #dff0d8;
-}
-
-.table tbody tr.error > td {
-  background-color: #f2dede;
-}
-
-.table tbody tr.warning > td {
-  background-color: #fcf8e3;
-}
-
-.table tbody tr.info > td {
-  background-color: #d9edf7;
-}
-
-.table-hover tbody tr.success:hover > td {
-  background-color: #d0e9c6;
-}
-
-.table-hover tbody tr.error:hover > td {
-  background-color: #ebcccc;
-}
-
-.table-hover tbody tr.warning:hover > td {
-  background-color: #faf2cc;
-}
-
-.table-hover tbody tr.info:hover > td {
-  background-color: #c4e3f3;
-}
-
-[class^="icon-"],
-[class*=" icon-"] {
-  display: inline-block;
-  width: 14px;
-  height: 14px;
-  margin-top: 1px;
-  *margin-right: .3em;
-  line-height: 14px;
-  vertical-align: text-top;
-  background-image: url("../img/glyphicons-halflings.png");
-  background-position: 14px 14px;
-  background-repeat: no-repeat;
-}
-
-/* White icons with optional class, or on hover/focus/active states of certain elements */
-
-.icon-white,
-.nav-pills > .active > a > [class^="icon-"],
-.nav-pills > .active > a > [class*=" icon-"],
-.nav-list > .active > a > [class^="icon-"],
-.nav-list > .active > a > [class*=" icon-"],
-.navbar-inverse .nav > .active > a > [class^="icon-"],
-.navbar-inverse .nav > .active > a > [class*=" icon-"],
-.dropdown-menu > li > a:hover > [class^="icon-"],
-.dropdown-menu > li > a:focus > [class^="icon-"],
-.dropdown-menu > li > a:hover > [class*=" icon-"],
-.dropdown-menu > li > a:focus > [class*=" icon-"],
-.dropdown-menu > .active > a > [class^="icon-"],
-.dropdown-menu > .active > a > [class*=" icon-"],
-.dropdown-submenu:hover > a > [class^="icon-"],
-.dropdown-submenu:focus > a > [class^="icon-"],
-.dropdown-submenu:hover > a > [class*=" icon-"],
-.dropdown-submenu:focus > a > [class*=" icon-"] {
-  background-image: url("../img/glyphicons-halflings-white.png");
-}
-
-.icon-glass {
-  background-position: 0      0;
-}
-
-.icon-music {
-  background-position: -24px 0;
-}
-
-.icon-search {
-  background-position: -48px 0;
-}
-
-.icon-envelope {
-  background-position: -72px 0;
-}
-
-.icon-heart {
-  background-position: -96px 0;
-}
-
-.icon-star {
-  background-position: -120px 0;
-}
-
-.icon-star-empty {
-  background-position: -144px 0;
-}
-
-.icon-user {
-  background-position: -168px 0;
-}
-
-.icon-film {
-  background-position: -192px 0;
-}
-
-.icon-th-large {
-  background-position: -216px 0;
-}
-
-.icon-th {
-  background-position: -240px 0;
-}
-
-.icon-th-list {
-  background-position: -264px 0;
-}
-
-.icon-ok {
-  background-position: -288px 0;
-}
-
-.icon-remove {
-  background-position: -312px 0;
-}
-
-.icon-zoom-in {
-  background-position: -336px 0;
-}
-
-.icon-zoom-out {
-  background-position: -360px 0;
-}
-
-.icon-off {
-  background-position: -384px 0;
-}
-
-.icon-signal {
-  background-position: -408px 0;
-}
-
-.icon-cog {
-  background-position: -432px 0;
-}
-
-.icon-trash {
-  background-position: -456px 0;
-}
-
-.icon-home {
-  background-position: 0 -24px;
-}
-
-.icon-file {
-  background-position: -24px -24px;
-}
-
-.icon-time {
-  background-position: -48px -24px;
-}
-
-.icon-road {
-  background-position: -72px -24px;
-}
-
-.icon-download-alt {
-  background-position: -96px -24px;
-}
-
-.icon-download {
-  background-position: -120px -24px;
-}
-
-.icon-upload {
-  background-position: -144px -24px;
-}
-
-.icon-inbox {
-  background-position: -168px -24px;
-}
-
-.icon-play-circle {
-  background-position: -192px -24px;
-}
-
-.icon-repeat {
-  background-position: -216px -24px;
-}
-
-.icon-refresh {
-  background-position: -240px -24px;
-}
-
-.icon-list-alt {
-  background-position: -264px -24px;
-}
-
-.icon-lock {
-  background-position: -287px -24px;
-}
-
-.icon-flag {
-  background-position: -312px -24px;
-}
-
-.icon-headphones {
-  background-position: -336px -24px;
-}
-
-.icon-volume-off {
-  background-position: -360px -24px;
-}
-
-.icon-volume-down {
-  background-position: -384px -24px;
-}
-
-.icon-volume-up {
-  background-position: -408px -24px;
-}
-
-.icon-qrcode {
-  background-position: -432px -24px;
-}
-
-.icon-barcode {
-  background-position: -456px -24px;
-}
-
-.icon-tag {
-  background-position: 0 -48px;
-}
-
-.icon-tags {
-  background-position: -25px -48px;
-}
-
-.icon-book {
-  background-position: -48px -48px;
-}
-
-.icon-bookmark {
-  background-position: -72px -48px;
-}
-
-.icon-print {
-  background-position: -96px -48px;
-}
-
-.icon-camera {
-  background-position: -120px -48px;
-}
-
-.icon-font {
-  background-position: -144px -48px;
-}
-
-.icon-bold {
-  background-position: -167px -48px;
-}
-
-.icon-italic {
-  background-position: -192px -48px;
-}
-
-.icon-text-height {
-  background-position: -216px -48px;
-}
-
-.icon-text-width {
-  background-position: -240px -48px;
-}
-
-.icon-align-left {
-  background-position: -264px -48px;
-}
-
-.icon-align-center {
-  background-position: -288px -48px;
-}
-
-.icon-align-right {
-  background-position: -312px -48px;
-}
-
-.icon-align-justify {
-  background-position: -336px -48px;
-}
-
-.icon-list {
-  background-position: -360px -48px;
-}
-
-.icon-indent-left {
-  background-position: -384px -48px;
-}
-
-.icon-indent-right {
-  background-position: -408px -48px;
-}
-
-.icon-facetime-video {
-  background-position: -432px -48px;
-}
-
-.icon-picture {
-  background-position: -456px -48px;
-}
-
-.icon-pencil {
-  background-position: 0 -72px;
-}
-
-.icon-map-marker {
-  background-position: -24px -72px;
-}
-
-.icon-adjust {
-  background-position: -48px -72px;
-}
-
-.icon-tint {
-  background-position: -72px -72px;
-}
-
-.icon-edit {
-  background-position: -96px -72px;
-}
-
-.icon-share {
-  background-position: -120px -72px;
-}
-
-.icon-check {
-  background-position: -144px -72px;
-}
-
-.icon-move {
-  background-position: -168px -72px;
-}
-
-.icon-step-backward {
-  background-position: -192px -72px;
-}
-
-.icon-fast-backward {
-  background-position: -216px -72px;
-}
-
-.icon-backward {
-  background-position: -240px -72px;
-}
-
-.icon-play {
-  background-position: -264px -72px;
-}
-
-.icon-pause {
-  background-position: -288px -72px;
-}
-
-.icon-stop {
-  background-position: -312px -72px;
-}
-
-.icon-forward {
-  background-position: -336px -72px;
-}
-
-.icon-fast-forward {
-  background-position: -360px -72px;
-}
-
-.icon-step-forward {
-  background-position: -384px -72px;
-}
-
-.icon-eject {
-  background-position: -408px -72px;
-}
-
-.icon-chevron-left {
-  background-position: -432px -72px;
-}
-
-.icon-chevron-right {
-  background-position: -456px -72px;
-}
-
-.icon-plus-sign {
-  background-position: 0 -96px;
-}
-
-.icon-minus-sign {
-  background-position: -24px -96px;
-}
-
-.icon-remove-sign {
-  background-position: -48px -96px;
-}
-
-.icon-ok-sign {
-  background-position: -72px -96px;
-}
-
-.icon-question-sign {
-  background-position: -96px -96px;
-}
-
-.icon-info-sign {
-  background-position: -120px -96px;
-}
-
-.icon-screenshot {
-  background-position: -144px -96px;
-}
-
-.icon-remove-circle {
-  background-position: -168px -96px;
-}
-
-.icon-ok-circle {
-  background-position: -192px -96px;
-}
-
-.icon-ban-circle {
-  background-position: -216px -96px;
-}
-
-.icon-arrow-left {
-  background-position: -240px -96px;
-}
-
-.icon-arrow-right {
-  background-position: -264px -96px;
-}
-
-.icon-arrow-up {
-  background-position: -289px -96px;
-}
-
-.icon-arrow-down {
-  background-position: -312px -96px;
-}
-
-.icon-share-alt {
-  background-position: -336px -96px;
-}
-
-.icon-resize-full {
-  background-position: -360px -96px;
-}
-
-.icon-resize-small {
-  background-position: -384px -96px;
-}
-
-.icon-plus {
-  background-position: -408px -96px;
-}
-
-.icon-minus {
-  background-position: -433px -96px;
-}
-
-.icon-asterisk {
-  background-position: -456px -96px;
-}
-
-.icon-exclamation-sign {
-  background-position: 0 -120px;
-}
-
-.icon-gift {
-  background-position: -24px -120px;
-}
-
-.icon-leaf {
-  background-position: -48px -120px;
-}
-
-.icon-fire {
-  background-position: -72px -120px;
-}
-
-.icon-eye-open {
-  background-position: -96px -120px;
-}
-
-.icon-eye-close {
-  background-position: -120px -120px;
-}
-
-.icon-warning-sign {
-  background-position: -144px -120px;
-}
-
-.icon-plane {
-  background-position: -168px -120px;
-}
-
-.icon-calendar {
-  background-position: -192px -120px;
-}
-
-.icon-random {
-  width: 16px;
-  background-position: -216px -120px;
-}
-
-.icon-comment {
-  background-position: -240px -120px;
-}
-
-.icon-magnet {
-  background-position: -264px -120px;
-}
-
-.icon-chevron-up {
-  background-position: -288px -120px;
-}
-
-.icon-chevron-down {
-  background-position: -313px -119px;
-}
-
-.icon-retweet {
-  background-position: -336px -120px;
-}
-
-.icon-shopping-cart {
-  background-position: -360px -120px;
-}
-
-.icon-folder-close {
-  width: 16px;
-  background-position: -384px -120px;
-}
-
-.icon-folder-open {
-  width: 16px;
-  background-position: -408px -120px;
-}
-
-.icon-resize-vertical {
-  background-position: -432px -119px;
-}
-
-.icon-resize-horizontal {
-  background-position: -456px -118px;
-}
-
-.icon-hdd {
-  background-position: 0 -144px;
-}
-
-.icon-bullhorn {
-  background-position: -24px -144px;
-}
-
-.icon-bell {
-  background-position: -48px -144px;
-}
-
-.icon-certificate {
-  background-position: -72px -144px;
-}
-
-.icon-thumbs-up {
-  background-position: -96px -144px;
-}
-
-.icon-thumbs-down {
-  background-position: -120px -144px;
-}
-
-.icon-hand-right {
-  background-position: -144px -144px;
-}
-
-.icon-hand-left {
-  background-position: -168px -144px;
-}
-
-.icon-hand-up {
-  background-position: -192px -144px;
-}
-
-.icon-hand-down {
-  background-position: -216px -144px;
-}
-
-.icon-circle-arrow-right {
-  background-position: -240px -144px;
-}
-
-.icon-circle-arrow-left {
-  background-position: -264px -144px;
-}
-
-.icon-circle-arrow-up {
-  background-position: -288px -144px;
-}
-
-.icon-circle-arrow-down {
-  background-position: -312px -144px;
-}
-
-.icon-globe {
-  background-position: -336px -144px;
-}
-
-.icon-wrench {
-  background-position: -360px -144px;
-}
-
-.icon-tasks {
-  background-position: -384px -144px;
-}
-
-.icon-filter {
-  background-position: -408px -144px;
-}
-
-.icon-briefcase {
-  background-position: -432px -144px;
-}
-
-.icon-fullscreen {
-  background-position: -456px -144px;
-}
-
-.dropup,
-.dropdown {
-  position: relative;
-}
-
-.dropdown-toggle {
-  *margin-bottom: -3px;
-}
-
-.dropdown-toggle:active,
-.open .dropdown-toggle {
-  outline: 0;
-}
-
-.caret {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  vertical-align: top;
-  border-top: 4px solid #000000;
-  border-right: 4px solid transparent;
-  border-left: 4px solid transparent;
-  content: "";
-}
-
-.dropdown .caret {
-  margin-top: 8px;
-  margin-left: 2px;
-}
-
-.dropdown-menu {
-  position: absolute;
-  top: 100%;
-  left: 0;
-  z-index: 1000;
-  display: none;
-  float: left;
-  min-width: 160px;
-  padding: 5px 0;
-  margin: 2px 0 0;
-  list-style: none;
-  background-color: #ffffff;
-  border: 1px solid #ccc;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  *border-right-width: 2px;
-  *border-bottom-width: 2px;
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-     -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-  -webkit-background-clip: padding-box;
-     -moz-background-clip: padding;
-          background-clip: padding-box;
-}
-
-.dropdown-menu.pull-right {
-  right: 0;
-  left: auto;
-}
-
-.dropdown-menu .divider {
-  *width: 100%;
-  height: 1px;
-  margin: 9px 1px;
-  *margin: -5px 0 5px;
-  overflow: hidden;
-  background-color: #e5e5e5;
-  border-bottom: 1px solid #ffffff;
-}
-
-.dropdown-menu > li > a {
-  display: block;
-  padding: 3px 20px;
-  clear: both;
-  font-weight: normal;
-  line-height: 20px;
-  color: #333333;
-  white-space: nowrap;
-}
-
-.dropdown-menu > li > a:hover,
-.dropdown-menu > li > a:focus,
-.dropdown-submenu:hover > a,
-.dropdown-submenu:focus > a {
-  color: #ffffff;
-  text-decoration: none;
-  background-color: #0081c2;
-  background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
-  background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
-  background-image: -o-linear-gradient(top, #0088cc, #0077b3);
-  background-image: linear-gradient(to bottom, #0088cc, #0077b3);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
-}
-
-.dropdown-menu > .active > a,
-.dropdown-menu > .active > a:hover,
-.dropdown-menu > .active > a:focus {
-  color: #ffffff;
-  text-decoration: none;
-  background-color: #0081c2;
-  background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
-  background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
-  background-image: -o-linear-gradient(top, #0088cc, #0077b3);
-  background-image: linear-gradient(to bottom, #0088cc, #0077b3);
-  background-repeat: repeat-x;
-  outline: 0;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
-}
-
-.dropdown-menu > .disabled > a,
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
-  color: #999999;
-}
-
-.dropdown-menu > .disabled > a:hover,
-.dropdown-menu > .disabled > a:focus {
-  text-decoration: none;
-  cursor: default;
-  background-color: transparent;
-  background-image: none;
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.open {
-  *z-index: 1000;
-}
-
-.open > .dropdown-menu {
-  display: block;
-}
-
-.dropdown-backdrop {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 990;
-}
-
-.pull-right > .dropdown-menu {
-  right: 0;
-  left: auto;
-}
-
-.dropup .caret,
-.navbar-fixed-bottom .dropdown .caret {
-  border-top: 0;
-  border-bottom: 4px solid #000000;
-  content: "";
-}
-
-.dropup .dropdown-menu,
-.navbar-fixed-bottom .dropdown .dropdown-menu {
-  top: auto;
-  bottom: 100%;
-  margin-bottom: 1px;
-}
-
-.dropdown-submenu {
-  position: relative;
-}
-
-.dropdown-submenu > .dropdown-menu {
-  top: 0;
-  left: 100%;
-  margin-top: -6px;
-  margin-left: -1px;
-  -webkit-border-radius: 0 6px 6px 6px;
-     -moz-border-radius: 0 6px 6px 6px;
-          border-radius: 0 6px 6px 6px;
-}
-
-.dropdown-submenu:hover > .dropdown-menu {
-  display: block;
-}
-
-.dropup .dropdown-submenu > .dropdown-menu {
-  top: auto;
-  bottom: 0;
-  margin-top: 0;
-  margin-bottom: -2px;
-  -webkit-border-radius: 5px 5px 5px 0;
-     -moz-border-radius: 5px 5px 5px 0;
-          border-radius: 5px 5px 5px 0;
-}
-
-.dropdown-submenu > a:after {
-  display: block;
-  float: right;
-  width: 0;
-  height: 0;
-  margin-top: 5px;
-  margin-right: -10px;
-  border-color: transparent;
-  border-left-color: #cccccc;
-  border-style: solid;
-  border-width: 5px 0 5px 5px;
-  content: " ";
-}
-
-.dropdown-submenu:hover > a:after {
-  border-left-color: #ffffff;
-}
-
-.dropdown-submenu.pull-left {
-  float: none;
-}
-
-.dropdown-submenu.pull-left > .dropdown-menu {
-  left: -100%;
-  margin-left: 10px;
-  -webkit-border-radius: 6px 0 6px 6px;
-     -moz-border-radius: 6px 0 6px 6px;
-          border-radius: 6px 0 6px 6px;
-}
-
-.dropdown .dropdown-menu .nav-header {
-  padding-right: 20px;
-  padding-left: 20px;
-}
-
-.typeahead {
-  z-index: 1051;
-  margin-top: 2px;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.well {
-  min-height: 20px;
-  padding: 19px;
-  margin-bottom: 20px;
-  background-color: #f5f5f5;
-  border: 1px solid #e3e3e3;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-}
-
-.well blockquote {
-  border-color: #ddd;
-  border-color: rgba(0, 0, 0, 0.15);
-}
-
-.well-large {
-  padding: 24px;
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-}
-
-.well-small {
-  padding: 9px;
-  -webkit-border-radius: 3px;
-     -moz-border-radius: 3px;
-          border-radius: 3px;
-}
-
-.fade {
-  opacity: 0;
-  -webkit-transition: opacity 0.15s linear;
-     -moz-transition: opacity 0.15s linear;
-       -o-transition: opacity 0.15s linear;
-          transition: opacity 0.15s linear;
-}
-
-.fade.in {
-  opacity: 1;
-}
-
-.collapse {
-  position: relative;
-  height: 0;
-  overflow: hidden;
-  -webkit-transition: height 0.35s ease;
-     -moz-transition: height 0.35s ease;
-       -o-transition: height 0.35s ease;
-          transition: height 0.35s ease;
-}
-
-.collapse.in {
-  height: auto;
-}
-
-.close {
-  float: right;
-  font-size: 20px;
-  font-weight: bold;
-  line-height: 20px;
-  color: #000000;
-  text-shadow: 0 1px 0 #ffffff;
-  opacity: 0.2;
-  filter: alpha(opacity=20);
-}
-
-.close:hover,
-.close:focus {
-  color: #000000;
-  text-decoration: none;
-  cursor: pointer;
-  opacity: 0.4;
-  filter: alpha(opacity=40);
-}
-
-button.close {
-  padding: 0;
-  cursor: pointer;
-  background: transparent;
-  border: 0;
-  -webkit-appearance: none;
-}
-
-.btn {
-  display: inline-block;
-  *display: inline;
-  padding: 4px 12px;
-  margin-bottom: 0;
-  *margin-left: .3em;
-  font-size: 14px;
-  line-height: 20px;
-  color: #333333;
-  text-align: center;
-  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
-  vertical-align: middle;
-  cursor: pointer;
-  background-color: #f5f5f5;
-  *background-color: #e6e6e6;
-  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
-  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
-  background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
-  background-repeat: repeat-x;
-  border: 1px solid #cccccc;
-  *border: 0;
-  border-color: #e6e6e6 #e6e6e6 #bfbfbf;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  border-bottom-color: #b3b3b3;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-  *zoom: 1;
-  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn:hover,
-.btn:focus,
-.btn:active,
-.btn.active,
-.btn.disabled,
-.btn[disabled] {
-  color: #333333;
-  background-color: #e6e6e6;
-  *background-color: #d9d9d9;
-}
-
-.btn:active,
-.btn.active {
-  background-color: #cccccc \9;
-}
-
-.btn:first-child {
-  *margin-left: 0;
-}
-
-.btn:hover,
-.btn:focus {
-  color: #333333;
-  text-decoration: none;
-  background-position: 0 -15px;
-  -webkit-transition: background-position 0.1s linear;
-     -moz-transition: background-position 0.1s linear;
-       -o-transition: background-position 0.1s linear;
-          transition: background-position 0.1s linear;
-}
-
-.btn:focus {
-  outline: thin dotted #333;
-  outline: 5px auto -webkit-focus-ring-color;
-  outline-offset: -2px;
-}
-
-.btn.active,
-.btn:active {
-  background-image: none;
-  outline: 0;
-  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn.disabled,
-.btn[disabled] {
-  cursor: default;
-  background-image: none;
-  opacity: 0.65;
-  filter: alpha(opacity=65);
-  -webkit-box-shadow: none;
-     -moz-box-shadow: none;
-          box-shadow: none;
-}
-
-.btn-large {
-  padding: 11px 19px;
-  font-size: 17.5px;
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-}
-
-.btn-large [class^="icon-"],
-.btn-large [class*=" icon-"] {
-  margin-top: 4px;
-}
-
-.btn-small {
-  padding: 2px 10px;
-  font-size: 11.9px;
-  -webkit-border-radius: 3px;
-     -moz-border-radius: 3px;
-          border-radius: 3px;
-}
-
-.btn-small [class^="icon-"],
-.btn-small [class*=" icon-"] {
-  margin-top: 0;
-}
-
-.btn-mini [class^="icon-"],
-.btn-mini [class*=" icon-"] {
-  margin-top: -1px;
-}
-
-.btn-mini {
-  padding: 0 6px;
-  font-size: 10.5px;
-  -webkit-border-radius: 3px;
-     -moz-border-radius: 3px;
-          border-radius: 3px;
-}
-
-.btn-block {
-  display: block;
-  width: 100%;
-  padding-right: 0;
-  padding-left: 0;
-  -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
-}
-
-.btn-block + .btn-block {
-  margin-top: 5px;
-}
-
-input[type="submit"].btn-block,
-input[type="reset"].btn-block,
-input[type="button"].btn-block {
-  width: 100%;
-}
-
-.btn-primary.active,
-.btn-warning.active,
-.btn-danger.active,
-.btn-success.active,
-.btn-info.active,
-.btn-inverse.active {
-  color: rgba(255, 255, 255, 0.75);
-}
-
-.btn-primary {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #006dcc;
-  *background-color: #0044cc;
-  background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
-  background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
-  background-image: -o-linear-gradient(top, #0088cc, #0044cc);
-  background-image: linear-gradient(to bottom, #0088cc, #0044cc);
-  background-repeat: repeat-x;
-  border-color: #0044cc #0044cc #002a80;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-primary:hover,
-.btn-primary:focus,
-.btn-primary:active,
-.btn-primary.active,
-.btn-primary.disabled,
-.btn-primary[disabled] {
-  color: #ffffff;
-  background-color: #0044cc;
-  *background-color: #003bb3;
-}
-
-.btn-primary:active,
-.btn-primary.active {
-  background-color: #003399 \9;
-}
-
-.btn-warning {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #faa732;
-  *background-color: #f89406;
-  background-image: -moz-linear-gradient(top, #fbb450, #f89406);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
-  background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
-  background-image: -o-linear-gradient(top, #fbb450, #f89406);
-  background-image: linear-gradient(to bottom, #fbb450, #f89406);
-  background-repeat: repeat-x;
-  border-color: #f89406 #f89406 #ad6704;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-warning:hover,
-.btn-warning:focus,
-.btn-warning:active,
-.btn-warning.active,
-.btn-warning.disabled,
-.btn-warning[disabled] {
-  color: #ffffff;
-  background-color: #f89406;
-  *background-color: #df8505;
-}
-
-.btn-warning:active,
-.btn-warning.active {
-  background-color: #c67605 \9;
-}
-
-.btn-danger {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #da4f49;
-  *background-color: #bd362f;
-  background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
-  background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
-  background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
-  background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
-  background-repeat: repeat-x;
-  border-color: #bd362f #bd362f #802420;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-danger:hover,
-.btn-danger:focus,
-.btn-danger:active,
-.btn-danger.active,
-.btn-danger.disabled,
-.btn-danger[disabled] {
-  color: #ffffff;
-  background-color: #bd362f;
-  *background-color: #a9302a;
-}
-
-.btn-danger:active,
-.btn-danger.active {
-  background-color: #942a25 \9;
-}
-
-.btn-success {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #5bb75b;
-  *background-color: #51a351;
-  background-image: -moz-linear-gradient(top, #62c462, #51a351);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
-  background-image: -webkit-linear-gradient(top, #62c462, #51a351);
-  background-image: -o-linear-gradient(top, #62c462, #51a351);
-  background-image: linear-gradient(to bottom, #62c462, #51a351);
-  background-repeat: repeat-x;
-  border-color: #51a351 #51a351 #387038;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-success:hover,
-.btn-success:focus,
-.btn-success:active,
-.btn-success.active,
-.btn-success.disabled,
-.btn-success[disabled] {
-  color: #ffffff;
-  background-color: #51a351;
-  *background-color: #499249;
-}
-
-.btn-success:active,
-.btn-success.active {
-  background-color: #408140 \9;
-}
-
-.btn-info {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #49afcd;
-  *background-color: #2f96b4;
-  background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
-  background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
-  background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
-  background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
-  background-repeat: repeat-x;
-  border-color: #2f96b4 #2f96b4 #1f6377;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-info:hover,
-.btn-info:focus,
-.btn-info:active,
-.btn-info.active,
-.btn-info.disabled,
-.btn-info[disabled] {
-  color: #ffffff;
-  background-color: #2f96b4;
-  *background-color: #2a85a0;
-}
-
-.btn-info:active,
-.btn-info.active {
-  background-color: #24748c \9;
-}
-
-.btn-inverse {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #363636;
-  *background-color: #222222;
-  background-image: -moz-linear-gradient(top, #444444, #222222);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
-  background-image: -webkit-linear-gradient(top, #444444, #222222);
-  background-image: -o-linear-gradient(top, #444444, #222222);
-  background-image: linear-gradient(to bottom, #444444, #222222);
-  background-repeat: repeat-x;
-  border-color: #222222 #222222 #000000;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.btn-inverse:hover,
-.btn-inverse:focus,
-.btn-inverse:active,
-.btn-inverse.active,
-.btn-inverse.disabled,
-.btn-inverse[disabled] {
-  color: #ffffff;
-  background-color: #222222;
-  *background-color: #151515;
-}
-
-.btn-inverse:active,
-.btn-inverse.active {
-  background-color: #080808 \9;
-}
-
-button.btn,
-input[type="submit"].btn {
-  *padding-top: 3px;
-  *padding-bottom: 3px;
-}
-
-button.btn::-moz-focus-inner,
-input[type="submit"].btn::-moz-focus-inner {
-  padding: 0;
-  border: 0;
-}
-
-button.btn.btn-large,
-input[type="submit"].btn.btn-large {
-  *padding-top: 7px;
-  *padding-bottom: 7px;
-}
-
-button.btn.btn-small,
-input[type="submit"].btn.btn-small {
-  *padding-top: 3px;
-  *padding-bottom: 3px;
-}
-
-button.btn.btn-mini,
-input[type="submit"].btn.btn-mini {
-  *padding-top: 1px;
-  *padding-bottom: 1px;
-}
-
-.btn-link,
-.btn-link:active,
-.btn-link[disabled] {
-  background-color: transparent;
-  background-image: none;
-  -webkit-box-shadow: none;
-     -moz-box-shadow: none;
-          box-shadow: none;
-}
-
-.btn-link {
-  color: #0088cc;
-  cursor: pointer;
-  border-color: transparent;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.btn-link:hover,
-.btn-link:focus {
-  color: #005580;
-  text-decoration: underline;
-  background-color: transparent;
-}
-
-.btn-link[disabled]:hover,
-.btn-link[disabled]:focus {
-  color: #333333;
-  text-decoration: none;
-}
-
-.btn-group {
-  position: relative;
-  display: inline-block;
-  *display: inline;
-  *margin-left: .3em;
-  font-size: 0;
-  white-space: nowrap;
-  vertical-align: middle;
-  *zoom: 1;
-}
-
-.btn-group:first-child {
-  *margin-left: 0;
-}
-
-.btn-group + .btn-group {
-  margin-left: 5px;
-}
-
-.btn-toolbar {
-  margin-top: 10px;
-  margin-bottom: 10px;
-  font-size: 0;
-}
-
-.btn-toolbar > .btn + .btn,
-.btn-toolbar > .btn-group + .btn,
-.btn-toolbar > .btn + .btn-group {
-  margin-left: 5px;
-}
-
-.btn-group > .btn {
-  position: relative;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.btn-group > .btn + .btn {
-  margin-left: -1px;
-}
-
-.btn-group > .btn,
-.btn-group > .dropdown-menu,
-.btn-group > .popover {
-  font-size: 14px;
-}
-
-.btn-group > .btn-mini {
-  font-size: 10.5px;
-}
-
-.btn-group > .btn-small {
-  font-size: 11.9px;
-}
-
-.btn-group > .btn-large {
-  font-size: 17.5px;
-}
-
-.btn-group > .btn:first-child {
-  margin-left: 0;
-  -webkit-border-bottom-left-radius: 4px;
-          border-bottom-left-radius: 4px;
-  -webkit-border-top-left-radius: 4px;
-          border-top-left-radius: 4px;
-  -moz-border-radius-bottomleft: 4px;
-  -moz-border-radius-topleft: 4px;
-}
-
-.btn-group > .btn:last-child,
-.btn-group > .dropdown-toggle {
-  -webkit-border-top-right-radius: 4px;
-          border-top-right-radius: 4px;
-  -webkit-border-bottom-right-radius: 4px;
-          border-bottom-right-radius: 4px;
-  -moz-border-radius-topright: 4px;
-  -moz-border-radius-bottomright: 4px;
-}
-
-.btn-group > .btn.large:first-child {
-  margin-left: 0;
-  -webkit-border-bottom-left-radius: 6px;
-          border-bottom-left-radius: 6px;
-  -webkit-border-top-left-radius: 6px;
-          border-top-left-radius: 6px;
-  -moz-border-radius-bottomleft: 6px;
-  -moz-border-radius-topleft: 6px;
-}
-
-.btn-group > .btn.large:last-child,
-.btn-group > .large.dropdown-toggle {
-  -webkit-border-top-right-radius: 6px;
-          border-top-right-radius: 6px;
-  -webkit-border-bottom-right-radius: 6px;
-          border-bottom-right-radius: 6px;
-  -moz-border-radius-topright: 6px;
-  -moz-border-radius-bottomright: 6px;
-}
-
-.btn-group > .btn:hover,
-.btn-group > .btn:focus,
-.btn-group > .btn:active,
-.btn-group > .btn.active {
-  z-index: 2;
-}
-
-.btn-group .dropdown-toggle:active,
-.btn-group.open .dropdown-toggle {
-  outline: 0;
-}
-
-.btn-group > .btn + .dropdown-toggle {
-  *padding-top: 5px;
-  padding-right: 8px;
-  *padding-bottom: 5px;
-  padding-left: 8px;
-  -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn-group > .btn-mini + .dropdown-toggle {
-  *padding-top: 2px;
-  padding-right: 5px;
-  *padding-bottom: 2px;
-  padding-left: 5px;
-}
-
-.btn-group > .btn-small + .dropdown-toggle {
-  *padding-top: 5px;
-  *padding-bottom: 4px;
-}
-
-.btn-group > .btn-large + .dropdown-toggle {
-  *padding-top: 7px;
-  padding-right: 12px;
-  *padding-bottom: 7px;
-  padding-left: 12px;
-}
-
-.btn-group.open .dropdown-toggle {
-  background-image: none;
-  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.btn-group.open .btn.dropdown-toggle {
-  background-color: #e6e6e6;
-}
-
-.btn-group.open .btn-primary.dropdown-toggle {
-  background-color: #0044cc;
-}
-
-.btn-group.open .btn-warning.dropdown-toggle {
-  background-color: #f89406;
-}
-
-.btn-group.open .btn-danger.dropdown-toggle {
-  background-color: #bd362f;
-}
-
-.btn-group.open .btn-success.dropdown-toggle {
-  background-color: #51a351;
-}
-
-.btn-group.open .btn-info.dropdown-toggle {
-  background-color: #2f96b4;
-}
-
-.btn-group.open .btn-inverse.dropdown-toggle {
-  background-color: #222222;
-}
-
-.btn .caret {
-  margin-top: 8px;
-  margin-left: 0;
-}
-
-.btn-large .caret {
-  margin-top: 6px;
-}
-
-.btn-large .caret {
-  border-top-width: 5px;
-  border-right-width: 5px;
-  border-left-width: 5px;
-}
-
-.btn-mini .caret,
-.btn-small .caret {
-  margin-top: 8px;
-}
-
-.dropup .btn-large .caret {
-  border-bottom-width: 5px;
-}
-
-.btn-primary .caret,
-.btn-warning .caret,
-.btn-danger .caret,
-.btn-info .caret,
-.btn-success .caret,
-.btn-inverse .caret {
-  border-top-color: #ffffff;
-  border-bottom-color: #ffffff;
-}
-
-.btn-group-vertical {
-  display: inline-block;
-  *display: inline;
-  /* IE7 inline-block hack */
-
-  *zoom: 1;
-}
-
-.btn-group-vertical > .btn {
-  display: block;
-  float: none;
-  max-width: 100%;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.btn-group-vertical > .btn + .btn {
-  margin-top: -1px;
-  margin-left: 0;
-}
-
-.btn-group-vertical > .btn:first-child {
-  -webkit-border-radius: 4px 4px 0 0;
-     -moz-border-radius: 4px 4px 0 0;
-          border-radius: 4px 4px 0 0;
-}
-
-.btn-group-vertical > .btn:last-child {
-  -webkit-border-radius: 0 0 4px 4px;
-     -moz-border-radius: 0 0 4px 4px;
-          border-radius: 0 0 4px 4px;
-}
-
-.btn-group-vertical > .btn-large:first-child {
-  -webkit-border-radius: 6px 6px 0 0;
-     -moz-border-radius: 6px 6px 0 0;
-          border-radius: 6px 6px 0 0;
-}
-
-.btn-group-vertical > .btn-large:last-child {
-  -webkit-border-radius: 0 0 6px 6px;
-     -moz-border-radius: 0 0 6px 6px;
-          border-radius: 0 0 6px 6px;
-}
-
-.alert {
-  padding: 8px 35px 8px 14px;
-  margin-bottom: 20px;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-  background-color: #fcf8e3;
-  border: 1px solid #fbeed5;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.alert,
-.alert h4 {
-  color: #c09853;
-}
-
-.alert h4 {
-  margin: 0;
-}
-
-.alert .close {
-  position: relative;
-  top: -2px;
-  right: -21px;
-  line-height: 20px;
-}
-
-.alert-success {
-  color: #468847;
-  background-color: #dff0d8;
-  border-color: #d6e9c6;
-}
-
-.alert-success h4 {
-  color: #468847;
-}
-
-.alert-danger,
-.alert-error {
-  color: #b94a48;
-  background-color: #f2dede;
-  border-color: #eed3d7;
-}
-
-.alert-danger h4,
-.alert-error h4 {
-  color: #b94a48;
-}
-
-.alert-info {
-  color: #3a87ad;
-  background-color: #d9edf7;
-  border-color: #bce8f1;
-}
-
-.alert-info h4 {
-  color: #3a87ad;
-}
-
-.alert-block {
-  padding-top: 14px;
-  padding-bottom: 14px;
-}
-
-.alert-block > p,
-.alert-block > ul {
-  margin-bottom: 0;
-}
-
-.alert-block p + p {
-  margin-top: 5px;
-}
-
-.nav {
-  margin-bottom: 20px;
-  margin-left: 0;
-  list-style: none;
-}
-
-.nav > li > a {
-  display: block;
-}
-
-.nav > li > a:hover,
-.nav > li > a:focus {
-  text-decoration: none;
-  background-color: #eeeeee;
-}
-
-.nav > li > a > img {
-  max-width: none;
-}
-
-.nav > .pull-right {
-  float: right;
-}
-
-.nav-header {
-  display: block;
-  padding: 3px 15px;
-  font-size: 11px;
-  font-weight: bold;
-  line-height: 20px;
-  color: #999999;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-  text-transform: uppercase;
-}
-
-.nav li + .nav-header {
-  margin-top: 9px;
-}
-
-.nav-list {
-  padding-right: 15px;
-  padding-left: 15px;
-  margin-bottom: 0;
-}
-
-.nav-list > li > a,
-.nav-list .nav-header {
-  margin-right: -15px;
-  margin-left: -15px;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-}
-
-.nav-list > li > a {
-  padding: 3px 15px;
-}
-
-.nav-list > .active > a,
-.nav-list > .active > a:hover,
-.nav-list > .active > a:focus {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
-  background-color: #0088cc;
-}
-
-.nav-list [class^="icon-"],
-.nav-list [class*=" icon-"] {
-  margin-right: 2px;
-}
-
-.nav-list .divider {
-  *width: 100%;
-  height: 1px;
-  margin: 9px 1px;
-  *margin: -5px 0 5px;
-  overflow: hidden;
-  background-color: #e5e5e5;
-  border-bottom: 1px solid #ffffff;
-}
-
-.nav-tabs,
-.nav-pills {
-  *zoom: 1;
-}
-
-.nav-tabs:before,
-.nav-pills:before,
-.nav-tabs:after,
-.nav-pills:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.nav-tabs:after,
-.nav-pills:after {
-  clear: both;
-}
-
-.nav-tabs > li,
-.nav-pills > li {
-  float: left;
-}
-
-.nav-tabs > li > a,
-.nav-pills > li > a {
-  padding-right: 12px;
-  padding-left: 12px;
-  margin-right: 2px;
-  line-height: 14px;
-}
-
-.nav-tabs {
-  border-bottom: 1px solid #ddd;
-}
-
-.nav-tabs > li {
-  margin-bottom: -1px;
-}
-
-.nav-tabs > li > a {
-  padding-top: 8px;
-  padding-bottom: 8px;
-  line-height: 20px;
-  border: 1px solid transparent;
-  -webkit-border-radius: 4px 4px 0 0;
-     -moz-border-radius: 4px 4px 0 0;
-          border-radius: 4px 4px 0 0;
-}
-
-.nav-tabs > li > a:hover,
-.nav-tabs > li > a:focus {
-  border-color: #eeeeee #eeeeee #dddddd;
-}
-
-.nav-tabs > .active > a,
-.nav-tabs > .active > a:hover,
-.nav-tabs > .active > a:focus {
-  color: #555555;
-  cursor: default;
-  background-color: #ffffff;
-  border: 1px solid #ddd;
-  border-bottom-color: transparent;
-}
-
-.nav-pills > li > a {
-  padding-top: 8px;
-  padding-bottom: 8px;
-  margin-top: 2px;
-  margin-bottom: 2px;
-  -webkit-border-radius: 5px;
-     -moz-border-radius: 5px;
-          border-radius: 5px;
-}
-
-.nav-pills > .active > a,
-.nav-pills > .active > a:hover,
-.nav-pills > .active > a:focus {
-  color: #ffffff;
-  background-color: #0088cc;
-}
-
-.nav-stacked > li {
-  float: none;
-}
-
-.nav-stacked > li > a {
-  margin-right: 0;
-}
-
-.nav-tabs.nav-stacked {
-  border-bottom: 0;
-}
-
-.nav-tabs.nav-stacked > li > a {
-  border: 1px solid #ddd;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.nav-tabs.nav-stacked > li:first-child > a {
-  -webkit-border-top-right-radius: 4px;
-          border-top-right-radius: 4px;
-  -webkit-border-top-left-radius: 4px;
-          border-top-left-radius: 4px;
-  -moz-border-radius-topright: 4px;
-  -moz-border-radius-topleft: 4px;
-}
-
-.nav-tabs.nav-stacked > li:last-child > a {
-  -webkit-border-bottom-right-radius: 4px;
-          border-bottom-right-radius: 4px;
-  -webkit-border-bottom-left-radius: 4px;
-          border-bottom-left-radius: 4px;
-  -moz-border-radius-bottomright: 4px;
-  -moz-border-radius-bottomleft: 4px;
-}
-
-.nav-tabs.nav-stacked > li > a:hover,
-.nav-tabs.nav-stacked > li > a:focus {
-  z-index: 2;
-  border-color: #ddd;
-}
-
-.nav-pills.nav-stacked > li > a {
-  margin-bottom: 3px;
-}
-
-.nav-pills.nav-stacked > li:last-child > a {
-  margin-bottom: 1px;
-}
-
-.nav-tabs .dropdown-menu {
-  -webkit-border-radius: 0 0 6px 6px;
-     -moz-border-radius: 0 0 6px 6px;
-          border-radius: 0 0 6px 6px;
-}
-
-.nav-pills .dropdown-menu {
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-}
-
-.nav .dropdown-toggle .caret {
-  margin-top: 6px;
-  border-top-color: #0088cc;
-  border-bottom-color: #0088cc;
-}
-
-.nav .dropdown-toggle:hover .caret,
-.nav .dropdown-toggle:focus .caret {
-  border-top-color: #005580;
-  border-bottom-color: #005580;
-}
-
-/* move down carets for tabs */
-
-.nav-tabs .dropdown-toggle .caret {
-  margin-top: 8px;
-}
-
-.nav .active .dropdown-toggle .caret {
-  border-top-color: #fff;
-  border-bottom-color: #fff;
-}
-
-.nav-tabs .active .dropdown-toggle .caret {
-  border-top-color: #555555;
-  border-bottom-color: #555555;
-}
-
-.nav > .dropdown.active > a:hover,
-.nav > .dropdown.active > a:focus {
-  cursor: pointer;
-}
-
-.nav-tabs .open .dropdown-toggle,
-.nav-pills .open .dropdown-toggle,
-.nav > li.dropdown.open.active > a:hover,
-.nav > li.dropdown.open.active > a:focus {
-  color: #ffffff;
-  background-color: #999999;
-  border-color: #999999;
-}
-
-.nav li.dropdown.open .caret,
-.nav li.dropdown.open.active .caret,
-.nav li.dropdown.open a:hover .caret,
-.nav li.dropdown.open a:focus .caret {
-  border-top-color: #ffffff;
-  border-bottom-color: #ffffff;
-  opacity: 1;
-  filter: alpha(opacity=100);
-}
-
-.tabs-stacked .open > a:hover,
-.tabs-stacked .open > a:focus {
-  border-color: #999999;
-}
-
-.tabbable {
-  *zoom: 1;
-}
-
-.tabbable:before,
-.tabbable:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.tabbable:after {
-  clear: both;
-}
-
-.tab-content {
-  overflow: auto;
-}
-
-.tabs-below > .nav-tabs,
-.tabs-right > .nav-tabs,
-.tabs-left > .nav-tabs {
-  border-bottom: 0;
-}
-
-.tab-content > .tab-pane,
-.pill-content > .pill-pane {
-  display: none;
-}
-
-.tab-content > .active,
-.pill-content > .active {
-  display: block;
-}
-
-.tabs-below > .nav-tabs {
-  border-top: 1px solid #ddd;
-}
-
-.tabs-below > .nav-tabs > li {
-  margin-top: -1px;
-  margin-bottom: 0;
-}
-
-.tabs-below > .nav-tabs > li > a {
-  -webkit-border-radius: 0 0 4px 4px;
-     -moz-border-radius: 0 0 4px 4px;
-          border-radius: 0 0 4px 4px;
-}
-
-.tabs-below > .nav-tabs > li > a:hover,
-.tabs-below > .nav-tabs > li > a:focus {
-  border-top-color: #ddd;
-  border-bottom-color: transparent;
-}
-
-.tabs-below > .nav-tabs > .active > a,
-.tabs-below > .nav-tabs > .active > a:hover,
-.tabs-below > .nav-tabs > .active > a:focus {
-  border-color: transparent #ddd #ddd #ddd;
-}
-
-.tabs-left > .nav-tabs > li,
-.tabs-right > .nav-tabs > li {
-  float: none;
-}
-
-.tabs-left > .nav-tabs > li > a,
-.tabs-right > .nav-tabs > li > a {
-  min-width: 74px;
-  margin-right: 0;
-  margin-bottom: 3px;
-}
-
-.tabs-left > .nav-tabs {
-  float: left;
-  margin-right: 19px;
-  border-right: 1px solid #ddd;
-}
-
-.tabs-left > .nav-tabs > li > a {
-  margin-right: -1px;
-  -webkit-border-radius: 4px 0 0 4px;
-     -moz-border-radius: 4px 0 0 4px;
-          border-radius: 4px 0 0 4px;
-}
-
-.tabs-left > .nav-tabs > li > a:hover,
-.tabs-left > .nav-tabs > li > a:focus {
-  border-color: #eeeeee #dddddd #eeeeee #eeeeee;
-}
-
-.tabs-left > .nav-tabs .active > a,
-.tabs-left > .nav-tabs .active > a:hover,
-.tabs-left > .nav-tabs .active > a:focus {
-  border-color: #ddd transparent #ddd #ddd;
-  *border-right-color: #ffffff;
-}
-
-.tabs-right > .nav-tabs {
-  float: right;
-  margin-left: 19px;
-  border-left: 1px solid #ddd;
-}
-
-.tabs-right > .nav-tabs > li > a {
-  margin-left: -1px;
-  -webkit-border-radius: 0 4px 4px 0;
-     -moz-border-radius: 0 4px 4px 0;
-          border-radius: 0 4px 4px 0;
-}
-
-.tabs-right > .nav-tabs > li > a:hover,
-.tabs-right > .nav-tabs > li > a:focus {
-  border-color: #eeeeee #eeeeee #eeeeee #dddddd;
-}
-
-.tabs-right > .nav-tabs .active > a,
-.tabs-right > .nav-tabs .active > a:hover,
-.tabs-right > .nav-tabs .active > a:focus {
-  border-color: #ddd #ddd #ddd transparent;
-  *border-left-color: #ffffff;
-}
-
-.nav > .disabled > a {
-  color: #999999;
-}
-
-.nav > .disabled > a:hover,
-.nav > .disabled > a:focus {
-  text-decoration: none;
-  cursor: default;
-  background-color: transparent;
-}
-
-.navbar {
-  *position: relative;
-  *z-index: 2;
-  margin-bottom: 20px;
-  overflow: visible;
-}
-
-.navbar-inner {
-  min-height: 40px;
-  padding-right: 20px;
-  padding-left: 20px;
-  background-color: #fafafa;
-  background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
-  background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
-  background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
-  background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
-  background-repeat: repeat-x;
-  border: 1px solid #d4d4d4;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);
-  *zoom: 1;
-  -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
-     -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
-          box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
-}
-
-.navbar-inner:before,
-.navbar-inner:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.navbar-inner:after {
-  clear: both;
-}
-
-.navbar .container {
-  width: auto;
-}
-
-.nav-collapse.collapse {
-  height: auto;
-  overflow: visible;
-}
-
-.navbar .brand {
-  display: block;
-  float: left;
-  padding: 10px 20px 10px;
-  margin-left: -20px;
-  font-size: 20px;
-  font-weight: 200;
-  color: #777777;
-  text-shadow: 0 1px 0 #ffffff;
-}
-
-.navbar .brand:hover,
-.navbar .brand:focus {
-  text-decoration: none;
-}
-
-.navbar-text {
-  margin-bottom: 0;
-  line-height: 40px;
-  color: #777777;
-}
-
-.navbar-link {
-  color: #777777;
-}
-
-.navbar-link:hover,
-.navbar-link:focus {
-  color: #333333;
-}
-
-.navbar .divider-vertical {
-  height: 40px;
-  margin: 0 9px;
-  border-right: 1px solid #ffffff;
-  border-left: 1px solid #f2f2f2;
-}
-
-.navbar .btn,
-.navbar .btn-group {
-  margin-top: 5px;
-}
-
-.navbar .btn-group .btn,
-.navbar .input-prepend .btn,
-.navbar .input-append .btn,
-.navbar .input-prepend .btn-group,
-.navbar .input-append .btn-group {
-  margin-top: 0;
-}
-
-.navbar-form {
-  margin-bottom: 0;
-  *zoom: 1;
-}
-
-.navbar-form:before,
-.navbar-form:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.navbar-form:after {
-  clear: both;
-}
-
-.navbar-form input,
-.navbar-form select,
-.navbar-form .radio,
-.navbar-form .checkbox {
-  margin-top: 5px;
-}
-
-.navbar-form input,
-.navbar-form select,
-.navbar-form .btn {
-  display: inline-block;
-  margin-bottom: 0;
-}
-
-.navbar-form input[type="image"],
-.navbar-form input[type="checkbox"],
-.navbar-form input[type="radio"] {
-  margin-top: 3px;
-}
-
-.navbar-form .input-append,
-.navbar-form .input-prepend {
-  margin-top: 5px;
-  white-space: nowrap;
-}
-
-.navbar-form .input-append input,
-.navbar-form .input-prepend input {
-  margin-top: 0;
-}
-
-.navbar-search {
-  position: relative;
-  float: left;
-  margin-top: 5px;
-  margin-bottom: 0;
-}
-
-.navbar-search .search-query {
-  padding: 4px 14px;
-  margin-bottom: 0;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  font-weight: normal;
-  line-height: 1;
-  -webkit-border-radius: 15px;
-     -moz-border-radius: 15px;
-          border-radius: 15px;
-}
-
-.navbar-static-top {
-  position: static;
-  margin-bottom: 0;
-}
-
-.navbar-static-top .navbar-inner {
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.navbar-fixed-top,
-.navbar-fixed-bottom {
-  position: fixed;
-  right: 0;
-  left: 0;
-  z-index: 1030;
-  margin-bottom: 0;
-}
-
-.navbar-fixed-top .navbar-inner,
-.navbar-static-top .navbar-inner {
-  border-width: 0 0 1px;
-}
-
-.navbar-fixed-bottom .navbar-inner {
-  border-width: 1px 0 0;
-}
-
-.navbar-fixed-top .navbar-inner,
-.navbar-fixed-bottom .navbar-inner {
-  padding-right: 0;
-  padding-left: 0;
-  -webkit-border-radius: 0;
-     -moz-border-radius: 0;
-          border-radius: 0;
-}
-
-.navbar-static-top .container,
-.navbar-fixed-top .container,
-.navbar-fixed-bottom .container {
-  width: 940px;
-}
-
-.navbar-fixed-top {
-  top: 0;
-}
-
-.navbar-fixed-top .navbar-inner,
-.navbar-static-top .navbar-inner {
-  -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
-     -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
-          box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
-}
-
-.navbar-fixed-bottom {
-  bottom: 0;
-}
-
-.navbar-fixed-bottom .navbar-inner {
-  -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
-     -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
-          box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
-}
-
-.navbar .nav {
-  position: relative;
-  left: 0;
-  display: block;
-  float: left;
-  margin: 0 10px 0 0;
-}
-
-.navbar .nav.pull-right {
-  float: right;
-  margin-right: 0;
-}
-
-.navbar .nav > li {
-  float: left;
-}
-
-.navbar .nav > li > a {
-  float: none;
-  padding: 10px 15px 10px;
-  color: #777777;
-  text-decoration: none;
-  text-shadow: 0 1px 0 #ffffff;
-}
-
-.navbar .nav .dropdown-toggle .caret {
-  margin-top: 8px;
-}
-
-.navbar .nav > li > a:focus,
-.navbar .nav > li > a:hover {
-  color: #333333;
-  text-decoration: none;
-  background-color: transparent;
-}
-
-.navbar .nav > .active > a,
-.navbar .nav > .active > a:hover,
-.navbar .nav > .active > a:focus {
-  color: #555555;
-  text-decoration: none;
-  background-color: #e5e5e5;
-  -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
-     -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
-          box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
-}
-
-.navbar .btn-navbar {
-  display: none;
-  float: right;
-  padding: 7px 10px;
-  margin-right: 5px;
-  margin-left: 5px;
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #ededed;
-  *background-color: #e5e5e5;
-  background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));
-  background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5);
-  background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5);
-  background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
-  background-repeat: repeat-x;
-  border-color: #e5e5e5 #e5e5e5 #bfbfbf;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
-     -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
-          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
-}
-
-.navbar .btn-navbar:hover,
-.navbar .btn-navbar:focus,
-.navbar .btn-navbar:active,
-.navbar .btn-navbar.active,
-.navbar .btn-navbar.disabled,
-.navbar .btn-navbar[disabled] {
-  color: #ffffff;
-  background-color: #e5e5e5;
-  *background-color: #d9d9d9;
-}
-
-.navbar .btn-navbar:active,
-.navbar .btn-navbar.active {
-  background-color: #cccccc \9;
-}
-
-.navbar .btn-navbar .icon-bar {
-  display: block;
-  width: 18px;
-  height: 2px;
-  background-color: #f5f5f5;
-  -webkit-border-radius: 1px;
-     -moz-border-radius: 1px;
-          border-radius: 1px;
-  -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
-     -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
-          box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
-}
-
-.btn-navbar .icon-bar + .icon-bar {
-  margin-top: 3px;
-}
-
-.navbar .nav > li > .dropdown-menu:before {
-  position: absolute;
-  top: -7px;
-  left: 9px;
-  display: inline-block;
-  border-right: 7px solid transparent;
-  border-bottom: 7px solid #ccc;
-  border-left: 7px solid transparent;
-  border-bottom-color: rgba(0, 0, 0, 0.2);
-  content: '';
-}
-
-.navbar .nav > li > .dropdown-menu:after {
-  position: absolute;
-  top: -6px;
-  left: 10px;
-  display: inline-block;
-  border-right: 6px solid transparent;
-  border-bottom: 6px solid #ffffff;
-  border-left: 6px solid transparent;
-  content: '';
-}
-
-.navbar-fixed-bottom .nav > li > .dropdown-menu:before {
-  top: auto;
-  bottom: -7px;
-  border-top: 7px solid #ccc;
-  border-bottom: 0;
-  border-top-color: rgba(0, 0, 0, 0.2);
-}
-
-.navbar-fixed-bottom .nav > li > .dropdown-menu:after {
-  top: auto;
-  bottom: -6px;
-  border-top: 6px solid #ffffff;
-  border-bottom: 0;
-}
-
-.navbar .nav li.dropdown > a:hover .caret,
-.navbar .nav li.dropdown > a:focus .caret {
-  border-top-color: #333333;
-  border-bottom-color: #333333;
-}
-
-.navbar .nav li.dropdown.open > .dropdown-toggle,
-.navbar .nav li.dropdown.active > .dropdown-toggle,
-.navbar .nav li.dropdown.open.active > .dropdown-toggle {
-  color: #555555;
-  background-color: #e5e5e5;
-}
-
-.navbar .nav li.dropdown > .dropdown-toggle .caret {
-  border-top-color: #777777;
-  border-bottom-color: #777777;
-}
-
-.navbar .nav li.dropdown.open > .dropdown-toggle .caret,
-.navbar .nav li.dropdown.active > .dropdown-toggle .caret,
-.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {
-  border-top-color: #555555;
-  border-bottom-color: #555555;
-}
-
-.navbar .pull-right > li > .dropdown-menu,
-.navbar .nav > li > .dropdown-menu.pull-right {
-  right: 0;
-  left: auto;
-}
-
-.navbar .pull-right > li > .dropdown-menu:before,
-.navbar .nav > li > .dropdown-menu.pull-right:before {
-  right: 12px;
-  left: auto;
-}
-
-.navbar .pull-right > li > .dropdown-menu:after,
-.navbar .nav > li > .dropdown-menu.pull-right:after {
-  right: 13px;
-  left: auto;
-}
-
-.navbar .pull-right > li > .dropdown-menu .dropdown-menu,
-.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu {
-  right: 100%;
-  left: auto;
-  margin-right: -1px;
-  margin-left: 0;
-  -webkit-border-radius: 6px 0 6px 6px;
-     -moz-border-radius: 6px 0 6px 6px;
-          border-radius: 6px 0 6px 6px;
-}
-
-.navbar-inverse .navbar-inner {
-  background-color: #1b1b1b;
-  background-image: -moz-linear-gradient(top, #222222, #111111);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));
-  background-image: -webkit-linear-gradient(top, #222222, #111111);
-  background-image: -o-linear-gradient(top, #222222, #111111);
-  background-image: linear-gradient(to bottom, #222222, #111111);
-  background-repeat: repeat-x;
-  border-color: #252525;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);
-}
-
-.navbar-inverse .brand,
-.navbar-inverse .nav > li > a {
-  color: #999999;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-}
-
-.navbar-inverse .brand:hover,
-.navbar-inverse .nav > li > a:hover,
-.navbar-inverse .brand:focus,
-.navbar-inverse .nav > li > a:focus {
-  color: #ffffff;
-}
-
-.navbar-inverse .brand {
-  color: #999999;
-}
-
-.navbar-inverse .navbar-text {
-  color: #999999;
-}
-
-.navbar-inverse .nav > li > a:focus,
-.navbar-inverse .nav > li > a:hover {
-  color: #ffffff;
-  background-color: transparent;
-}
-
-.navbar-inverse .nav .active > a,
-.navbar-inverse .nav .active > a:hover,
-.navbar-inverse .nav .active > a:focus {
-  color: #ffffff;
-  background-color: #111111;
-}
-
-.navbar-inverse .navbar-link {
-  color: #999999;
-}
-
-.navbar-inverse .navbar-link:hover,
-.navbar-inverse .navbar-link:focus {
-  color: #ffffff;
-}
-
-.navbar-inverse .divider-vertical {
-  border-right-color: #222222;
-  border-left-color: #111111;
-}
-
-.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,
-.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,
-.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {
-  color: #ffffff;
-  background-color: #111111;
-}
-
-.navbar-inverse .nav li.dropdown > a:hover .caret,
-.navbar-inverse .nav li.dropdown > a:focus .caret {
-  border-top-color: #ffffff;
-  border-bottom-color: #ffffff;
-}
-
-.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {
-  border-top-color: #999999;
-  border-bottom-color: #999999;
-}
-
-.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,
-.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,
-.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {
-  border-top-color: #ffffff;
-  border-bottom-color: #ffffff;
-}
-
-.navbar-inverse .navbar-search .search-query {
-  color: #ffffff;
-  background-color: #515151;
-  border-color: #111111;
-  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
-     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
-          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
-  -webkit-transition: none;
-     -moz-transition: none;
-       -o-transition: none;
-          transition: none;
-}
-
-.navbar-inverse .navbar-search .search-query:-moz-placeholder {
-  color: #cccccc;
-}
-
-.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {
-  color: #cccccc;
-}
-
-.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {
-  color: #cccccc;
-}
-
-.navbar-inverse .navbar-search .search-query:focus,
-.navbar-inverse .navbar-search .search-query.focused {
-  padding: 5px 15px;
-  color: #333333;
-  text-shadow: 0 1px 0 #ffffff;
-  background-color: #ffffff;
-  border: 0;
-  outline: 0;
-  -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
-     -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
-          box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
-}
-
-.navbar-inverse .btn-navbar {
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #0e0e0e;
-  *background-color: #040404;
-  background-image: -moz-linear-gradient(top, #151515, #040404);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));
-  background-image: -webkit-linear-gradient(top, #151515, #040404);
-  background-image: -o-linear-gradient(top, #151515, #040404);
-  background-image: linear-gradient(to bottom, #151515, #040404);
-  background-repeat: repeat-x;
-  border-color: #040404 #040404 #000000;
-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-
-.navbar-inverse .btn-navbar:hover,
-.navbar-inverse .btn-navbar:focus,
-.navbar-inverse .btn-navbar:active,
-.navbar-inverse .btn-navbar.active,
-.navbar-inverse .btn-navbar.disabled,
-.navbar-inverse .btn-navbar[disabled] {
-  color: #ffffff;
-  background-color: #040404;
-  *background-color: #000000;
-}
-
-.navbar-inverse .btn-navbar:active,
-.navbar-inverse .btn-navbar.active {
-  background-color: #000000 \9;
-}
-
-.breadcrumb {
-  padding: 8px 15px;
-  margin: 0 0 20px;
-  list-style: none;
-  background-color: #f5f5f5;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.breadcrumb > li {
-  display: inline-block;
-  *display: inline;
-  text-shadow: 0 1px 0 #ffffff;
-  *zoom: 1;
-}
-
-.breadcrumb > li > .divider {
-  padding: 0 5px;
-  color: #ccc;
-}
-
-.breadcrumb > .active {
-  color: #999999;
-}
-
-.pagination {
-  margin: 20px 0;
-}
-
-.pagination ul {
-  display: inline-block;
-  *display: inline;
-  margin-bottom: 0;
-  margin-left: 0;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  *zoom: 1;
-  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
-     -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
-          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.pagination ul > li {
-  display: inline;
-}
-
-.pagination ul > li > a,
-.pagination ul > li > span {
-  float: left;
-  padding: 4px 12px;
-  line-height: 20px;
-  text-decoration: none;
-  background-color: #ffffff;
-  border: 1px solid #dddddd;
-  border-left-width: 0;
-}
-
-.pagination ul > li > a:hover,
-.pagination ul > li > a:focus,
-.pagination ul > .active > a,
-.pagination ul > .active > span {
-  background-color: #f5f5f5;
-}
-
-.pagination ul > .active > a,
-.pagination ul > .active > span {
-  color: #999999;
-  cursor: default;
-}
-
-.pagination ul > .disabled > span,
-.pagination ul > .disabled > a,
-.pagination ul > .disabled > a:hover,
-.pagination ul > .disabled > a:focus {
-  color: #999999;
-  cursor: default;
-  background-color: transparent;
-}
-
-.pagination ul > li:first-child > a,
-.pagination ul > li:first-child > span {
-  border-left-width: 1px;
-  -webkit-border-bottom-left-radius: 4px;
-          border-bottom-left-radius: 4px;
-  -webkit-border-top-left-radius: 4px;
-          border-top-left-radius: 4px;
-  -moz-border-radius-bottomleft: 4px;
-  -moz-border-radius-topleft: 4px;
-}
-
-.pagination ul > li:last-child > a,
-.pagination ul > li:last-child > span {
-  -webkit-border-top-right-radius: 4px;
-          border-top-right-radius: 4px;
-  -webkit-border-bottom-right-radius: 4px;
-          border-bottom-right-radius: 4px;
-  -moz-border-radius-topright: 4px;
-  -moz-border-radius-bottomright: 4px;
-}
-
-.pagination-centered {
-  text-align: center;
-}
-
-.pagination-right {
-  text-align: right;
-}
-
-.pagination-large ul > li > a,
-.pagination-large ul > li > span {
-  padding: 11px 19px;
-  font-size: 17.5px;
-}
-
-.pagination-large ul > li:first-child > a,
-.pagination-large ul > li:first-child > span {
-  -webkit-border-bottom-left-radius: 6px;
-          border-bottom-left-radius: 6px;
-  -webkit-border-top-left-radius: 6px;
-          border-top-left-radius: 6px;
-  -moz-border-radius-bottomleft: 6px;
-  -moz-border-radius-topleft: 6px;
-}
-
-.pagination-large ul > li:last-child > a,
-.pagination-large ul > li:last-child > span {
-  -webkit-border-top-right-radius: 6px;
-          border-top-right-radius: 6px;
-  -webkit-border-bottom-right-radius: 6px;
-          border-bottom-right-radius: 6px;
-  -moz-border-radius-topright: 6px;
-  -moz-border-radius-bottomright: 6px;
-}
-
-.pagination-mini ul > li:first-child > a,
-.pagination-small ul > li:first-child > a,
-.pagination-mini ul > li:first-child > span,
-.pagination-small ul > li:first-child > span {
-  -webkit-border-bottom-left-radius: 3px;
-          border-bottom-left-radius: 3px;
-  -webkit-border-top-left-radius: 3px;
-          border-top-left-radius: 3px;
-  -moz-border-radius-bottomleft: 3px;
-  -moz-border-radius-topleft: 3px;
-}
-
-.pagination-mini ul > li:last-child > a,
-.pagination-small ul > li:last-child > a,
-.pagination-mini ul > li:last-child > span,
-.pagination-small ul > li:last-child > span {
-  -webkit-border-top-right-radius: 3px;
-          border-top-right-radius: 3px;
-  -webkit-border-bottom-right-radius: 3px;
-          border-bottom-right-radius: 3px;
-  -moz-border-radius-topright: 3px;
-  -moz-border-radius-bottomright: 3px;
-}
-
-.pagination-small ul > li > a,
-.pagination-small ul > li > span {
-  padding: 2px 10px;
-  font-size: 11.9px;
-}
-
-.pagination-mini ul > li > a,
-.pagination-mini ul > li > span {
-  padding: 0 6px;
-  font-size: 10.5px;
-}
-
-.pager {
-  margin: 20px 0;
-  text-align: center;
-  list-style: none;
-  *zoom: 1;
-}
-
-.pager:before,
-.pager:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.pager:after {
-  clear: both;
-}
-
-.pager li {
-  display: inline;
-}
-
-.pager li > a,
-.pager li > span {
-  display: inline-block;
-  padding: 5px 14px;
-  background-color: #fff;
-  border: 1px solid #ddd;
-  -webkit-border-radius: 15px;
-     -moz-border-radius: 15px;
-          border-radius: 15px;
-}
-
-.pager li > a:hover,
-.pager li > a:focus {
-  text-decoration: none;
-  background-color: #f5f5f5;
-}
-
-.pager .next > a,
-.pager .next > span {
-  float: right;
-}
-
-.pager .previous > a,
-.pager .previous > span {
-  float: left;
-}
-
-.pager .disabled > a,
-.pager .disabled > a:hover,
-.pager .disabled > a:focus,
-.pager .disabled > span {
-  color: #999999;
-  cursor: default;
-  background-color: #fff;
-}
-
-.modal-backdrop {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1040;
-  background-color: #000000;
-}
-
-.modal-backdrop.fade {
-  opacity: 0;
-}
-
-.modal-backdrop,
-.modal-backdrop.fade.in {
-  opacity: 0.8;
-  filter: alpha(opacity=80);
-}
-
-.modal {
-  position: fixed;
-  top: 10%;
-  left: 50%;
-  z-index: 1050;
-  width: 560px;
-  margin-left: -280px;
-  background-color: #ffffff;
-  border: 1px solid #999;
-  border: 1px solid rgba(0, 0, 0, 0.3);
-  *border: 1px solid #999;
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-  outline: none;
-  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
-     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
-          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
-  -webkit-background-clip: padding-box;
-     -moz-background-clip: padding-box;
-          background-clip: padding-box;
-}
-
-.modal.fade {
-  top: -25%;
-  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;
-     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;
-       -o-transition: opacity 0.3s linear, top 0.3s ease-out;
-          transition: opacity 0.3s linear, top 0.3s ease-out;
-}
-
-.modal.fade.in {
-  top: 10%;
-}
-
-.modal-header {
-  padding: 9px 15px;
-  border-bottom: 1px solid #eee;
-}
-
-.modal-header .close {
-  margin-top: 2px;
-}
-
-.modal-header h3 {
-  margin: 0;
-  line-height: 30px;
-}
-
-.modal-body {
-  position: relative;
-  max-height: 400px;
-  padding: 15px;
-  overflow-y: auto;
-}
-
-.modal-form {
-  margin-bottom: 0;
-}
-
-.modal-footer {
-  padding: 14px 15px 15px;
-  margin-bottom: 0;
-  text-align: right;
-  background-color: #f5f5f5;
-  border-top: 1px solid #ddd;
-  -webkit-border-radius: 0 0 6px 6px;
-     -moz-border-radius: 0 0 6px 6px;
-          border-radius: 0 0 6px 6px;
-  *zoom: 1;
-  -webkit-box-shadow: inset 0 1px 0 #ffffff;
-     -moz-box-shadow: inset 0 1px 0 #ffffff;
-          box-shadow: inset 0 1px 0 #ffffff;
-}
-
-.modal-footer:before,
-.modal-footer:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.modal-footer:after {
-  clear: both;
-}
-
-.modal-footer .btn + .btn {
-  margin-bottom: 0;
-  margin-left: 5px;
-}
-
-.modal-footer .btn-group .btn + .btn {
-  margin-left: -1px;
-}
-
-.modal-footer .btn-block + .btn-block {
-  margin-left: 0;
-}
-
-.tooltip {
-  position: absolute;
-  z-index: 1030;
-  display: block;
-  font-size: 11px;
-  line-height: 1.4;
-  opacity: 0;
-  filter: alpha(opacity=0);
-  visibility: visible;
-}
-
-.tooltip.in {
-  opacity: 0.8;
-  filter: alpha(opacity=80);
-}
-
-.tooltip.top {
-  padding: 5px 0;
-  margin-top: -3px;
-}
-
-.tooltip.right {
-  padding: 0 5px;
-  margin-left: 3px;
-}
-
-.tooltip.bottom {
-  padding: 5px 0;
-  margin-top: 3px;
-}
-
-.tooltip.left {
-  padding: 0 5px;
-  margin-left: -3px;
-}
-
-.tooltip-inner {
-  max-width: 200px;
-  padding: 8px;
-  color: #ffffff;
-  text-align: center;
-  text-decoration: none;
-  background-color: #000000;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.tooltip-arrow {
-  position: absolute;
-  width: 0;
-  height: 0;
-  border-color: transparent;
-  border-style: solid;
-}
-
-.tooltip.top .tooltip-arrow {
-  bottom: 0;
-  left: 50%;
-  margin-left: -5px;
-  border-top-color: #000000;
-  border-width: 5px 5px 0;
-}
-
-.tooltip.right .tooltip-arrow {
-  top: 50%;
-  left: 0;
-  margin-top: -5px;
-  border-right-color: #000000;
-  border-width: 5px 5px 5px 0;
-}
-
-.tooltip.left .tooltip-arrow {
-  top: 50%;
-  right: 0;
-  margin-top: -5px;
-  border-left-color: #000000;
-  border-width: 5px 0 5px 5px;
-}
-
-.tooltip.bottom .tooltip-arrow {
-  top: 0;
-  left: 50%;
-  margin-left: -5px;
-  border-bottom-color: #000000;
-  border-width: 0 5px 5px;
-}
-
-.popover {
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 1010;
-  display: none;
-  max-width: 276px;
-  padding: 1px;
-  text-align: left;
-  white-space: normal;
-  background-color: #ffffff;
-  border: 1px solid #ccc;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-     -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-  -webkit-background-clip: padding-box;
-     -moz-background-clip: padding;
-          background-clip: padding-box;
-}
-
-.popover.top {
-  margin-top: -10px;
-}
-
-.popover.right {
-  margin-left: 10px;
-}
-
-.popover.bottom {
-  margin-top: 10px;
-}
-
-.popover.left {
-  margin-left: -10px;
-}
-
-.popover-title {
-  padding: 8px 14px;
-  margin: 0;
-  font-size: 14px;
-  font-weight: normal;
-  line-height: 18px;
-  background-color: #f7f7f7;
-  border-bottom: 1px solid #ebebeb;
-  -webkit-border-radius: 5px 5px 0 0;
-     -moz-border-radius: 5px 5px 0 0;
-          border-radius: 5px 5px 0 0;
-}
-
-.popover-title:empty {
-  display: none;
-}
-
-.popover-content {
-  padding: 9px 14px;
-}
-
-.popover .arrow,
-.popover .arrow:after {
-  position: absolute;
-  display: block;
-  width: 0;
-  height: 0;
-  border-color: transparent;
-  border-style: solid;
-}
-
-.popover .arrow {
-  border-width: 11px;
-}
-
-.popover .arrow:after {
-  border-width: 10px;
-  content: "";
-}
-
-.popover.top .arrow {
-  bottom: -11px;
-  left: 50%;
-  margin-left: -11px;
-  border-top-color: #999;
-  border-top-color: rgba(0, 0, 0, 0.25);
-  border-bottom-width: 0;
-}
-
-.popover.top .arrow:after {
-  bottom: 1px;
-  margin-left: -10px;
-  border-top-color: #ffffff;
-  border-bottom-width: 0;
-}
-
-.popover.right .arrow {
-  top: 50%;
-  left: -11px;
-  margin-top: -11px;
-  border-right-color: #999;
-  border-right-color: rgba(0, 0, 0, 0.25);
-  border-left-width: 0;
-}
-
-.popover.right .arrow:after {
-  bottom: -10px;
-  left: 1px;
-  border-right-color: #ffffff;
-  border-left-width: 0;
-}
-
-.popover.bottom .arrow {
-  top: -11px;
-  left: 50%;
-  margin-left: -11px;
-  border-bottom-color: #999;
-  border-bottom-color: rgba(0, 0, 0, 0.25);
-  border-top-width: 0;
-}
-
-.popover.bottom .arrow:after {
-  top: 1px;
-  margin-left: -10px;
-  border-bottom-color: #ffffff;
-  border-top-width: 0;
-}
-
-.popover.left .arrow {
-  top: 50%;
-  right: -11px;
-  margin-top: -11px;
-  border-left-color: #999;
-  border-left-color: rgba(0, 0, 0, 0.25);
-  border-right-width: 0;
-}
-
-.popover.left .arrow:after {
-  right: 1px;
-  bottom: -10px;
-  border-left-color: #ffffff;
-  border-right-width: 0;
-}
-
-.thumbnails {
-  margin-left: -20px;
-  list-style: none;
-  *zoom: 1;
-}
-
-.thumbnails:before,
-.thumbnails:after {
-  display: table;
-  line-height: 0;
-  content: "";
-}
-
-.thumbnails:after {
-  clear: both;
-}
-
-.row-fluid .thumbnails {
-  margin-left: 0;
-}
-
-.thumbnails > li {
-  float: left;
-  margin-bottom: 20px;
-  margin-left: 20px;
-}
-
-.thumbnail {
-  display: block;
-  padding: 4px;
-  line-height: 20px;
-  border: 1px solid #ddd;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
-     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
-          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
-  -webkit-transition: all 0.2s ease-in-out;
-     -moz-transition: all 0.2s ease-in-out;
-       -o-transition: all 0.2s ease-in-out;
-          transition: all 0.2s ease-in-out;
-}
-
-a.thumbnail:hover,
-a.thumbnail:focus {
-  border-color: #0088cc;
-  -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
-     -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
-          box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
-}
-
-.thumbnail > img {
-  display: block;
-  max-width: 100%;
-  margin-right: auto;
-  margin-left: auto;
-}
-
-.thumbnail .caption {
-  padding: 9px;
-  color: #555555;
-}
-
-.media,
-.media-body {
-  overflow: hidden;
-  *overflow: visible;
-  zoom: 1;
-}
-
-.media,
-.media .media {
-  margin-top: 15px;
-}
-
-.media:first-child {
-  margin-top: 0;
-}
-
-.media-object {
-  display: block;
-}
-
-.media-heading {
-  margin: 0 0 5px;
-}
-
-.media > .pull-left {
-  margin-right: 10px;
-}
-
-.media > .pull-right {
-  margin-left: 10px;
-}
-
-.media-list {
-  margin-left: 0;
-  list-style: none;
-}
-
-.label,
-.badge {
-  display: inline-block;
-  padding: 2px 4px;
-  font-size: 11.844px;
-  font-weight: bold;
-  line-height: 14px;
-  color: #ffffff;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  white-space: nowrap;
-  vertical-align: baseline;
-  background-color: #999999;
-}
-
-.label {
-  -webkit-border-radius: 3px;
-     -moz-border-radius: 3px;
-          border-radius: 3px;
-}
-
-.badge {
-  padding-right: 9px;
-  padding-left: 9px;
-  -webkit-border-radius: 9px;
-     -moz-border-radius: 9px;
-          border-radius: 9px;
-}
-
-.label:empty,
-.badge:empty {
-  display: none;
-}
-
-a.label:hover,
-a.label:focus,
-a.badge:hover,
-a.badge:focus {
-  color: #ffffff;
-  text-decoration: none;
-  cursor: pointer;
-}
-
-.label-important,
-.badge-important {
-  background-color: #b94a48;
-}
-
-.label-important[href],
-.badge-important[href] {
-  background-color: #953b39;
-}
-
-.label-warning,
-.badge-warning {
-  background-color: #f89406;
-}
-
-.label-warning[href],
-.badge-warning[href] {
-  background-color: #c67605;
-}
-
-.label-success,
-.badge-success {
-  background-color: #468847;
-}
-
-.label-success[href],
-.badge-success[href] {
-  background-color: #356635;
-}
-
-.label-info,
-.badge-info {
-  background-color: #3a87ad;
-}
-
-.label-info[href],
-.badge-info[href] {
-  background-color: #2d6987;
-}
-
-.label-inverse,
-.badge-inverse {
-  background-color: #333333;
-}
-
-.label-inverse[href],
-.badge-inverse[href] {
-  background-color: #1a1a1a;
-}
-
-.btn .label,
-.btn .badge {
-  position: relative;
-  top: -1px;
-}
-
-.btn-mini .label,
-.btn-mini .badge {
-  top: 0;
-}
-
-@-webkit-keyframes progress-bar-stripes {
-  from {
-    background-position: 40px 0;
-  }
-  to {
-    background-position: 0 0;
-  }
-}
-
-@-moz-keyframes progress-bar-stripes {
-  from {
-    background-position: 40px 0;
-  }
-  to {
-    background-position: 0 0;
-  }
-}
-
-@-ms-keyframes progress-bar-stripes {
-  from {
-    background-position: 40px 0;
-  }
-  to {
-    background-position: 0 0;
-  }
-}
-
-@-o-keyframes progress-bar-stripes {
-  from {
-    background-position: 0 0;
-  }
-  to {
-    background-position: 40px 0;
-  }
-}
-
-@keyframes progress-bar-stripes {
-  from {
-    background-position: 40px 0;
-  }
-  to {
-    background-position: 0 0;
-  }
-}
-
-.progress {
-  height: 20px;
-  margin-bottom: 20px;
-  overflow: hidden;
-  background-color: #f7f7f7;
-  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
-  background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
-  background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
-  background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
-  background-repeat: repeat-x;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
-  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-     -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-}
-
-.progress .bar {
-  float: left;
-  width: 0;
-  height: 100%;
-  font-size: 12px;
-  color: #ffffff;
-  text-align: center;
-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-  background-color: #0e90d2;
-  background-image: -moz-linear-gradient(top, #149bdf, #0480be);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
-  background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
-  background-image: -o-linear-gradient(top, #149bdf, #0480be);
-  background-image: linear-gradient(to bottom, #149bdf, #0480be);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
-  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-     -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-  -webkit-box-sizing: border-box;
-     -moz-box-sizing: border-box;
-          box-sizing: border-box;
-  -webkit-transition: width 0.6s ease;
-     -moz-transition: width 0.6s ease;
-       -o-transition: width 0.6s ease;
-          transition: width 0.6s ease;
-}
-
-.progress .bar + .bar {
-  -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-     -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-          box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-}
-
-.progress-striped .bar {
-  background-color: #149bdf;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  -webkit-background-size: 40px 40px;
-     -moz-background-size: 40px 40px;
-       -o-background-size: 40px 40px;
-          background-size: 40px 40px;
-}
-
-.progress.active .bar {
-  -webkit-animation: progress-bar-stripes 2s linear infinite;
-     -moz-animation: progress-bar-stripes 2s linear infinite;
-      -ms-animation: progress-bar-stripes 2s linear infinite;
-       -o-animation: progress-bar-stripes 2s linear infinite;
-          animation: progress-bar-stripes 2s linear infinite;
-}
-
-.progress-danger .bar,
-.progress .bar-danger {
-  background-color: #dd514c;
-  background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));
-  background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
-  background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
-  background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);
-}
-
-.progress-danger.progress-striped .bar,
-.progress-striped .bar-danger {
-  background-color: #ee5f5b;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-
-.progress-success .bar,
-.progress .bar-success {
-  background-color: #5eb95e;
-  background-image: -moz-linear-gradient(top, #62c462, #57a957);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));
-  background-image: -webkit-linear-gradient(top, #62c462, #57a957);
-  background-image: -o-linear-gradient(top, #62c462, #57a957);
-  background-image: linear-gradient(to bottom, #62c462, #57a957);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);
-}
-
-.progress-success.progress-striped .bar,
-.progress-striped .bar-success {
-  background-color: #62c462;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-
-.progress-info .bar,
-.progress .bar-info {
-  background-color: #4bb1cf;
-  background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));
-  background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
-  background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
-  background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);
-}
-
-.progress-info.progress-striped .bar,
-.progress-striped .bar-info {
-  background-color: #5bc0de;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-
-.progress-warning .bar,
-.progress .bar-warning {
-  background-color: #faa732;
-  background-image: -moz-linear-gradient(top, #fbb450, #f89406);
-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
-  background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
-  background-image: -o-linear-gradient(top, #fbb450, #f89406);
-  background-image: linear-gradient(to bottom, #fbb450, #f89406);
-  background-repeat: repeat-x;
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
-}
-
-.progress-warning.progress-striped .bar,
-.progress-striped .bar-warning {
-  background-color: #fbb450;
-  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
-  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
-}
-
-.accordion {
-  margin-bottom: 20px;
-}
-
-.accordion-group {
-  margin-bottom: 2px;
-  border: 1px solid #e5e5e5;
-  -webkit-border-radius: 4px;
-     -moz-border-radius: 4px;
-          border-radius: 4px;
-}
-
-.accordion-heading {
-  border-bottom: 0;
-}
-
-.accordion-heading .accordion-toggle {
-  display: block;
-  padding: 8px 15px;
-}
-
-.accordion-toggle {
-  cursor: pointer;
-}
-
-.accordion-inner {
-  padding: 9px 15px;
-  border-top: 1px solid #e5e5e5;
-}
-
-.carousel {
-  position: relative;
-  margin-bottom: 20px;
-  line-height: 1;
-}
-
-.carousel-inner {
-  position: relative;
-  width: 100%;
-  overflow: hidden;
-}
-
-.carousel-inner > .item {
-  position: relative;
-  display: none;
-  -webkit-transition: 0.6s ease-in-out left;
-     -moz-transition: 0.6s ease-in-out left;
-       -o-transition: 0.6s ease-in-out left;
-          transition: 0.6s ease-in-out left;
-}
-
-.carousel-inner > .item > img,
-.carousel-inner > .item > a > img {
-  display: block;
-  line-height: 1;
-}
-
-.carousel-inner > .active,
-.carousel-inner > .next,
-.carousel-inner > .prev {
-  display: block;
-}
-
-.carousel-inner > .active {
-  left: 0;
-}
-
-.carousel-inner > .next,
-.carousel-inner > .prev {
-  position: absolute;
-  top: 0;
-  width: 100%;
-}
-
-.carousel-inner > .next {
-  left: 100%;
-}
-
-.carousel-inner > .prev {
-  left: -100%;
-}
-
-.carousel-inner > .next.left,
-.carousel-inner > .prev.right {
-  left: 0;
-}
-
-.carousel-inner > .active.left {
-  left: -100%;
-}
-
-.carousel-inner > .active.right {
-  left: 100%;
-}
-
-.carousel-control {
-  position: absolute;
-  top: 40%;
-  left: 15px;
-  width: 40px;
-  height: 40px;
-  margin-top: -20px;
-  font-size: 60px;
-  font-weight: 100;
-  line-height: 30px;
-  color: #ffffff;
-  text-align: center;
-  background: #222222;
-  border: 3px solid #ffffff;
-  -webkit-border-radius: 23px;
-     -moz-border-radius: 23px;
-          border-radius: 23px;
-  opacity: 0.5;
-  filter: alpha(opacity=50);
-}
-
-.carousel-control.right {
-  right: 15px;
-  left: auto;
-}
-
-.carousel-control:hover,
-.carousel-control:focus {
-  color: #ffffff;
-  text-decoration: none;
-  opacity: 0.9;
-  filter: alpha(opacity=90);
-}
-
-.carousel-indicators {
-  position: absolute;
-  top: 15px;
-  right: 15px;
-  z-index: 5;
-  margin: 0;
-  list-style: none;
-}
-
-.carousel-indicators li {
-  display: block;
-  float: left;
-  width: 10px;
-  height: 10px;
-  margin-left: 5px;
-  text-indent: -999px;
-  background-color: #ccc;
-  background-color: rgba(255, 255, 255, 0.25);
-  border-radius: 5px;
-}
-
-.carousel-indicators .active {
-  background-color: #fff;
-}
-
-.carousel-caption {
-  position: absolute;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  padding: 15px;
-  background: #333333;
-  background: rgba(0, 0, 0, 0.75);
-}
-
-.carousel-caption h4,
-.carousel-caption p {
-  line-height: 20px;
-  color: #ffffff;
-}
-
-.carousel-caption h4 {
-  margin: 0 0 5px;
-}
-
-.carousel-caption p {
-  margin-bottom: 0;
-}
-
-.hero-unit {
-  padding: 60px;
-  margin-bottom: 30px;
-  font-size: 18px;
-  font-weight: 200;
-  line-height: 30px;
-  color: inherit;
-  background-color: #eeeeee;
-  -webkit-border-radius: 6px;
-     -moz-border-radius: 6px;
-          border-radius: 6px;
-}
-
-.hero-unit h1 {
-  margin-bottom: 0;
-  font-size: 60px;
-  line-height: 1;
-  letter-spacing: -1px;
-  color: inherit;
-}
-
-.hero-unit li {
-  line-height: 30px;
-}
-
-.pull-right {
-  float: right;
-}
-
-.pull-left {
-  float: left;
-}
-
-.hide {
-  display: none;
-}
-
-.show {
-  display: block;
-}
-
-.invisible {
-  visibility: hidden;
-}
-
-.affix {
-  position: fixed;
-}

+ 0 - 186
mod/dashboard/app/styles/browser.css

@@ -1,186 +0,0 @@
-.etcd-container.etcd-browser {
-  width: 100%;
-  height: 500px;
-}
-
-.home-container .etcd-container.etcd-browser {
-  height: 400px;
-}
-
-.etcd-container.etcd-browser .etcd-header {
-  height: 37px;
-}
-
-.etcd-container.etcd-browser.etcd-preview-reveal .etcd-back {
-  display: block;
-}
-
-.etcd-container.etcd-browser.etcd-preview-hide .etcd-back {
-  display: block;
-}
-
-.etcd-container.etcd-browser.etcd-preview-reveal .etcd-add {
-}
-
-.etcd-container.etcd-browser.etcd-preview-hide .etcd-add {
-}
-
-.etcd-container.etcd-browser .etcd-header .etcd-browser-path {
-  position: absolute;
-  left: 72px;
-  right: 0px;
-  top: 0;
-  margin: 6px 5px 6px 5px;
-}
-
-.etcd-container.etcd-browser .etcd-header .etcd-browser-path input {
-  width: 100%;
-  box-sizing: border-box;
-    -moz-box-sizing: border-box;
-    -webkit-box-sizing: border-box;
-}
-
-.etcd-container.etcd-browser .etcd-header .etcd-save {
-  position: absolute;
-  width: 54px;
-  right: -55px;
-  margin: 6px 0;
-}
-
-.etcd-container.etcd-browser.etcd-save-reveal .etcd-header .etcd-save {
-  right: 7px;
-}
-
-.etcd-container.etcd-browser.etcd-save-reveal .etcd-header .etcd-browser-path {
-  right: 62px;
-}
-
-.etcd-container.etcd-browser.etcd-save-hide .etcd-header .etcd-save {
-  right: -55px;
-}
-
-.etcd-container.etcd-browser.etcd-save-hide .etcd-header .etcd-browser-path {
-  right: 0px;
-}
-
-.etcd-container.etcd-browser .etcd-preview {
-  position: absolute;
-  left: 100%;
-  min-height: 100%;
-  overflow-y: auto;
-  overflow-x: hidden;
-  top: 0px;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  background-color: #fff;
-  width: 100%;
-  border-left: 1px solid #ddd;
-}
-
-.etcd-container.etcd-browser .etcd-preview pre, .etcd-container.etcd-browser .etcd-preview textarea {
-  padding: 20px 20px 20px 20px;
-  margin: 0px;
-  font-family: Consolas, "Liberation Mono", Courier, monospace;
-  height: 100%;
-  width: 100%;
-  white-space: pre-wrap;
-  position: absolute;
-  font-size: 13px;
-  border: 1px;
-  outline: none;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-}
-
-.etcd-container.etcd-browser.etcd-preview-reveal .etcd-preview pre, .etcd-container.etcd-browser.etcd-preview-reveal .etcd-preview textarea {
-  display: block;
-}
-
-.etcd-container.etcd-browser .etcd-preview .etcd-empty {
-  top: 0px;
-  bottom: 0px;
-  width: 100%;
-  text-align: center;
-  position: absolute;
-}
-
-.etcd-container.etcd-browser.etcd-preview-reveal .etcd-empty {
-  display: none;
-}
-
-.etcd-container.etcd-browser .etcd-preview .etcd-empty-message {
-  margin-top: 25%;
-  color: #999;
-}
-
-/* Single Column Positioning */
-@media (max-width: 700px) {
-  .etcd-container.etcd-browser .etcd-list {
-    width: 100%;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-reveal .etcd-list {
-    left: -100%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-hide .etcd-list {
-    left: 0%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-
-  .etcd-container.etcd-browser .etcd-preview {
-    left: 100%;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-reveal .etcd-preview { left: -1px;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-hide .etcd-preview {
-    left: 100%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-}
-
-
-/* Double Column Positioning */
-@media (min-width: 700px) {
-  .etcd-container.etcd-browser .etcd-list {
-      width: 50%;
-  }
-
-  .etcd-container.etcd-browser .etcd-preview {
-    left: 50%;
-    width: 50%;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-reveal .etcd-preview {
-    left: 50%; /* does nothing */
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-reveal .etcd-preview .etcd-empty {
-    display: none;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-hide .etcd-preview {
-    left: 50%; /* does nothing */
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-hide .etcd-preview .etcd-empty {
-    display: block;
-  }
-
-  .etcd-container.etcd-browser.etcd-preview-hide .etcd-preview pre, .etcd-container.etcd-browser.etcd-preview-hide .etcd-preview textarea {
-    display: none;
-  }
-}
-

+ 0 - 381
mod/dashboard/app/styles/etcd-widgets.css

@@ -1,381 +0,0 @@
-body {
-  margin: 0px;
-}
-
-.etcd-container {
-  background-color: #fff;
-  border: 1px solid #ddd;
-  border-radius: 5px;
-  box-shadow: rgba(0, 0, 0, 0.14902) 0px 1px 3px;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  overflow: hidden;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  position: relative;
-  user-select: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  margin: 20px 0;
-  height: 100%;
-}
-
-a {
-  color: #2176AC;
-  text-decoration: none;
-}
-
-a:hover, a:active {
-  text-decoration: underline;
-}
-
-input[type=text] {
-  box-shadow: inset 0 1px 2px rgba(0,0,0,.5);
-  border: none;
-  border-radius: 3px;
-  font-size: 13px;
-  padding-left: 5px;
-  padding-right: 5px;
-  height: 25px;
-}
-
-input[type=text]:focus {
-}
-
-h2 {
-  font-size: 22px;
-  font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  font-weight: 500;
-  margin: 0 0 20px 0;
-  padding: 0;
-}
-
-.etcd-button {
-  display:inline-block;
-  padding:6px 12px;
-  margin-bottom:0;
-  font-size:14px;
-  font-weight:normal;
-  line-height:1.428571429;
-  text-align:center;
-  white-space:nowrap;
-  vertical-align:middle;
-  cursor:pointer;
-  border:1px solid transparent;
-  border-radius:4px;
-  -webkit-user-select:none;
-  -moz-user-select:none;
-  -ms-user-select:none;
-  -o-user-select:none;
-  user-select:none;
-  margin: 0px;
-  border: none;
-  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.25);
-}
-
-.etcd-button.etcd-button-small {
-  height: 25px;
-  padding: 0 10px;
-  font-size: 13px;
-}
-
-.etcd-button-primary {
-  background-color: #428BCA;
-  color: #fff;
-  text-shadow: 0 0 3px rgba(0,0,0,0.25);
-}
-
-.etcd-button-primary:active {
-  background-color: #2276ad;
-}
-
-.etcd-popover {
-  background: #333;
-  border-radius: 3px;
-  padding: 15px;
-  position: absolute;
-  top: 39px;
-  z-index: 9999;
-  color: #fff;
-  font-size: 13px;
-  box-shadow: 0px 2px 10px rgba(0,0,0,.5);
-  display: none;
-}
-
-.etcd-popover-error .etcd-popover-content {
-  color: #FF3C43;
-  font-weight: bold;
-  user-select: text;
-  -webkit-user-select: text;
-  -moz-user-select: text;
-  -ms-user-select: text;
-}
-
-.etcd-popover-notch {
-  width: 14px;
-  height: 14px;
-  -webkit-transform: rotate(45deg);
-  -moz-transform: rotate(45deg);
-  -ms-transform: rotate(45deg);
-  position: absolute;
-  margin-top: -5px;
-  margin-left: 3px;
-  background: #333;
-  top: 0px;
-  right: 15px;
-}
-
-.etcd-popover.etcd-popover-right {
-  left: 77px;
-}
-
-.etcd-popover-right .etcd-popover-notch {
-  left: 15px;
-}
-
-.etcd-popover.etcd-popover-left {
-  right: 10px;
-}
-
-.etcd-popover-left .etcd-popover-notch {
-  right: 15px;
-}
-
-.etcd-popover-confirm {
-  margin-top: 10px;
-}
-
-.etcd-popover-confirm button {
-}
-
-.etcd-header {
-  width: 100%;
-  position: relative;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-}
-.etcd-header.solid {
-  background: #eeeeee;
-  background: -moz-linear-gradient(top,  #eeeeee 0%, #dddddd 100%);
-  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#dddddd));
-  background: -webkit-linear-gradient(top,  #eeeeee 0%,#dddddd 100%);
-  background: -o-linear-gradient(top,  #eeeeee 0%,#dddddd 100%);
-  background: -ms-linear-gradient(top,  #eeeeee 0%,#dddddd 100%);
-  background: linear-gradient(to bottom,  #eeeeee 0%,#dddddd 100%);
-  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#dddddd',GradientType=0 );
-}
-
-.etcd-body {
-  top: 0px;
-  left: 0px;
-  position: relative;
-  overflow: hidden;
-  height: 100%;
-  width: 100%;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-}
-
-.etcd-body table {
-  width: 100%;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-}
-
-.etcd-body table thead td {
-  text-transform: uppercase;
-  font-size: 11px;
-  line-height: 20px;
-  border-bottom: 1px solid #ddd;
-  padding-top: 0px;
-  padding-right: 10px;
-  padding-bottom: 0px;
-  padding-left: 0px;
-  color: #666;
-}
-
-.etcd-body table tbody td {
-  line-height: 18px;
-  border-bottom: 1px solid #ddd;
-  padding-top: 6px;
-  padding-right: 10px;
-  padding-bottom: 6px;
-  padding-left: 0px;
-  vertical-align: text-top;
-  user-select: text;
-  -webkit-user-select: text;
-  -moz-user-select: text;
-  -ms-user-select: text;
-}
-
-.etcd-body table .etcd-ttl-header {
-  width: 33%;
-}
-
-.etcd-body table tbody .etcd-ttl {
-  font-size: 13px;
-}
-
-.etcd-body table tbody .etcd-ttl .etcd-ttl-none {
-  color: #999;
-  font-weight: 100;
-}
-
-.etcd-body table .etcd-actions-header {
-  width: 30px;
-}
-
-.etcd-body table thead td:first-child, .etcd-body table tbody td:first-child {
-  padding-left: 10px;
-}
-
-.etcd-body table thead td:last-child, .etcd-body table tbody td:last-child {
-  padding-right: 10px;
-}
-
-.etcd-container .etcd-preview .etcd-dialog {
-  background: #333;
-  position: absolute;
-  right: 0px;
-  left: 0px;
-  padding: 20px;
-  color: #fff;
-  font-size: 14px;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  bottom: 0px;
-  opacity: 0;
-  min-height: 110px; /* REMOVE ME! */
-  transition-property: all;
-  transition-duration: 150ms;
-  transition-timing-function: ease-in-out;
-}
-
-.etcd-container .etcd-preview .etcd-dialog .etcd-dialog-message {
-  margin-bottom: 20px;
-}
-
-.etcd-container .etcd-preview .etcd-dialog .etcd-dialog-buttons a {
-  line-height: 34px;
-  color: #fff;
-  vertical-align: middle;
-  margin-left: 10px;
-}
-
-.etcd-body .etcd-list {
-  padding: 20px;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  overflow: auto;
-  height: 100%;
-  position: absolute;
-}
-
-.etcd-body .etcd-list .etcd-selected {
-  background-color: #EAF3FF;
-}
-
-.etcd-body .etcd-list a.directory {
-  font-weight: bold;
-}
-
-.etcd-list tr:hover .etcd-delete {
-  visibility: visible;
-  fill: #ff0000;
-}
-
-.etcd-delete {
-  height: 20px;
-  width: 25px;
-  vertical-align: middle;
-  margin: 0px;
-  display: inline-block;
-}
-
-.etcd-delete {
-  height: 20px;
-  fill: #eee;
-}
-
-.etcd-selected .etcd-delete {
-  height: 20px;
-  fill: #ddd;
-}
-
-.etcd-delete:hover {
-  cursor: pointer;
-  fill: #ff0000;
-}
-
-.etcd-back {
-  height: 37px;
-  width: 37px;
-  vertical-align: middle;
-  margin: 0px;
-  position: absolute;
-  top: 0px;
-  left: 3px;
-  display: none;
-}
-
-
-.etcd-back svg {
-  height: 20px;
-  padding: 8px 6px;
-}
-
-.etcd-back:hover svg {
-  cursor: pointer;
-  fill: #428bca;
-}
-
-.etcd-back.etcd-disabled svg {
-  fill: #bbb;
-}
-
-.etcd-add {
-  height: 37px;
-  width: 37px;
-  vertical-align: middle;
-  margin: 0px;
-  position: absolute;
-  top: 0px;
-  left: 36px;
-}
-
-
-.etcd-add svg {
-  height: 22px;
-  padding: 7px 6px;
-}
-
-.etcd-add:hover svg {
-  cursor: pointer;
-  fill: #428bca;
-}
-
-.etcd-add.etcd-disabled svg {
-  fill: #bbb;
-}
-
-.etcd-format-selector {
-  position: absolute;
-  top: 12px;
-  right: 16px;
-  z-index: 999;
-}
-
-.etcd-format-selector .etcd-selector-item {
-  display: inline-block;
-  height: 12px;
-  width: 12px;
-  padding: 8px 4px;
-}
-
-.etcd-format-selector .etcd-selector-item:hover {
-  cursor: pointer;
-}
-
-.etcd-format-selector .etcd-selector-item svg {
-  fill: #333;
-}
-

+ 0 - 56
mod/dashboard/app/styles/main.css

@@ -1,56 +0,0 @@
-html {
-  height: 100%;
-}
-
-body {
-  background: #fafafa;
-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #333;
-  padding: 30px;
-  margin: 0px;
-  height: 100%;
-}
-h1 {
-    font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
-    font-weight: 400;
-    margin: 0px 0px 20px 0px;
-    padding: 0px;
-}
-
-a {
-    color: #1e6ec1;
-    text-decoration: none;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-#footer {
-    width: 100%;
-    font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
-    margin-top: 20px;
-}
-
-#coreos-logo {
-    margin: 10px auto 0 auto;
-    height: 30px;
-    width: 80px;
-}
-
-#coreos-logo svg {
-    fill: #999;
-    MAX-WIDTH: 100PX;
-    DISPLAY: INLINE-BLOCK;
-    VERTICAL-ALIGN: MIDDLE;
-}
-
-#POWERED-BY {
-    FONT-SIZE: 12PX;
-    COLOR: #333;
-    WIDTH: 100%;
-    DISPLAY: INLINE-BLOCK;
-    VERTICAL-ALIGN: MIDDLE;
-    LINE-HEIGHT: 190%;
-    TEXT-ALIGN: CENTER;
-}

+ 0 - 144
mod/dashboard/app/styles/stats.css

@@ -1,144 +0,0 @@
-.etcd-container.etcd-stats {
-  width: 100%;
-  height: 500px;
-}
-
-.home-container .etcd-container.etcd-stats {
-  height: 400px;
-}
-
-.etcd-container.etcd-stats h2 {
-  margin-top: -7px;
-}
-
-.etcd-container.etcd-stats table .etcd-latency {
-  width: 50%;
-}
-
-.etcd-container.etcd-stats .etcd-list {
-  position: absolute;
-  left: 100%;
-  min-height: 100%;
-  overflow-y: auto;
-  overflow-x: hidden;
-  top: 0px;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  background-color: #fff;
-  width: 100%;
-  border-left: 1px solid #ddd;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-square {
-  height: 10px;
-  width: 10px;
-  display: inline-block;
-  margin-right: 5px;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-square-red {
-  background-color: #c40022;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-square-orange {
-  background-color: #FFC000;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-square-green {
-  background-color: #00DB24;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-peer-type {
-  color: #999;
-  padding-left: 3px;
-  font-size: 13px;
-  line-height: 100%;
-}
-
-.etcd-container.etcd-stats .etcd-list .etcd-latency-value {
-  display: inline-block;
-}
-
-.etcd-container.etcd-stats .etcd-graph {
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  position: absolute;
-  top: 0px;
-  bottom: 0px;
-  left: 0px;
-  right: 0px;
-  padding: 20px;
-}
-
-.etcd-container.etcd-stats .etcd-graph .etcd-graph-container {
-  position: absolute;
-  top: 60px;
-  bottom: 20px;
-  left: 20px;
-  right: 20px;
-  box-sizing: border-box;
-  -moz-box-sizing: border-box;
-}
-
-
-/* Single Column Positioning */
-@media (max-width: 700px) {
-  .etcd-container.etcd-stats .etcd-list {
-    width: 100%;
-    left: 100%;
-  }
-
-  .etcd-container.etcd-stats .etcd-graph {
-    left: 0%;
-  }
-
-  .etcd-container.etcd-stats.etcd-table-reveal .etcd-graph {
-    left: -100%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-  .etcd-container.etcd-stats.etcd-table-hide .etcd-graph {
-    left: 0%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-
-  }
-  .etcd-container.etcd-stats.etcd-table-hide .etcd-format-selector .etcd-selector-graph svg * {
-    fill: #428bca;
-  }
-
-  .etcd-container.etcd-stats.etcd-table-hide .etcd-list {
-    left: 100%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-  .etcd-container.etcd-stats.etcd-table-reveal .etcd-list {
-    left: 0%;
-    transition-property: all;
-      transition-duration: 250ms;
-      transition-timing-function: ease-in-out;
-  }
-  .etcd-container.etcd-stats.etcd-table-reveal .etcd-format-selector .etcd-selector-table svg * {
-    fill: #428bca;
-  }
-}
-
-/* Double Column Positioning */
-@media (min-width: 700px) {
-  .etcd-container.etcd-stats .etcd-list {
-    width: 50%;
-    left: 50%;
-  }
-
-  .etcd-container.etcd-stats .etcd-graph {
-    left: 0%;
-    width: 50%;
-  }
-
-  .etcd-container.etcd-stats .etcd-format-selector {
-    display: none;
-  }
-}

+ 0 - 73
mod/dashboard/app/views/browser.html

@@ -1,73 +0,0 @@
-<div ng-controller="BrowserCtrl" class="etcd-container etcd-browser {{columns}} {{preview}} {{save}}">
-
-  <div class="etcd-popover etcd-popover-error" id="etcd-save-error">
-    <div class="etcd-popover-notch"></div>
-    <div class="etcd-popover-content">Error:</div>
-  </div>
-
-  <div class="etcd-popover etcd-popover-error" id="etcd-browse-error">
-    <div class="etcd-popover-notch"></div>
-    <div class="etcd-popover-content">Error:</div>
-  </div>
-
-  <div class="etcd-header solid">
-    <a class="etcd-back" ng-click="back()" ng-class="{false:'etcd-disabled'}[enableBack]">
-      <img src="images/back.svg"/>
-    </a>
-    <a class="etcd-add" ng-click="add()"><img src="images/add.svg"/></a>
-    <div class="etcd-browser-path">
-      <input type="text" ng-model="inputPath" ng-enter="onEnter()" tabindex="888" />
-    </div>
-    <button class="etcd-button etcd-button-small etcd-button-primary etcd-save" ng-click="saveData()">Save</button>
-  </div>
-
-
-  <div class="etcd-body">
-
-    <div class="etcd-list">
-      <table cellpadding="0" cellspacing="0">
-      <thead>
-        <td class="etcd-name-header">Name</td>
-        <td class="etcd-ttl-header">TTL</td>
-        <td class="etcd-actions-header">&nbsp;</td>
-      </thead>
-      <tbody>
-        <tr ng-repeat="key in list | orderBy:'key'">
-          <td>
-            <highlight ng-class="{true:'directory'}[key.dir]" ng-click="setActiveKey(key.key)" highlight-base="etcdPath" highlight-current="key.key">{{key.key}}</highlight>
-          </td>
-          <td ng-switch on="!!key.expiration" class="etcd-ttl">
-            <div ng-switch-when="true"><time relative datetime="{{key.expiration.substring(0, key.expiration.lastIndexOf('-'))}}"></time></div>
-            <div ng-switch-default class="etcd-ttl-none">&mdash;</div>
-          </td>
-          <td>
-            <div class="etcd-actions">
-              <div ng-switch on="!!key.dir">
-                <img class="etcd-delete" src="images/delete.svg" ng-switch-when="false" ng-click="deleteKey(key.key)" />
-                <div ng-switch-when="true"></div>
-              </div>
-            </div>
-          </td>
-        </tr>
-      </tbody>
-      </table>
-    </div>
-
-    <div class="etcd-preview">
-      <textarea placeholder="Enter a key name above and the value here" ng-model="singleValue" tabindex="888" ng-change="showSave()"></textarea>
-      <div class="etcd-empty">
-        <div class="etcd-empty-message">{{preview_message}}</div>
-      </div>
-      <div class="etcd-dialog">
-        <div class="etcd-dialog-message">Save and replicate this change?</div>
-          <div class="etcd-dialog-buttons">
-            <button class="etcd-button etcd-button-primary">Save Changes</button>
-            <a href="javascript:void(0);">Cancel</a>
-          </div>
-        </div>
-      </div>
-    </div>
-
-  </div>
-
-</div>

+ 0 - 4
mod/dashboard/app/views/home.html

@@ -1,4 +0,0 @@
-<a href="stats" tabindex="-1">stats only</a>
-<div ng-include="prefixUrl('/views/stats.html')" class="home-container"></div>
-<a href="browser" tabindex="-1">browser only</a>
-<div ng-include="prefixUrl('/views/browser.html')" class="home-container"></div>

+ 0 - 49
mod/dashboard/app/views/stats.html

@@ -1,49 +0,0 @@
-<div ng-controller="StatsCtrl" class="etcd-container etcd-stats {{columns}} {{tableVisibility}}">
-    <div class="etcd-body">
-        <div class="etcd-format-selector">
-            <div class="etcd-selector-item etcd-selector-graph" ng-click="showGraph()">
-                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-                preserveAspectRatio="xMinYMin" viewBox="0 0 60 60.007" enable-background="new 0 0 60 60.007" xml:space="preserve">
-                <path fill="#1D1D1B" d="M30-0.091c-16.621,0-30.094,13.474-30.094,30.094c0,16.621,13.474,30.094,30.094,30.094
-                s30.094-13.474,30.094-30.094C60.094,13.383,46.621-0.091,30-0.091z M30,47.239c-9.519,0-17.235-7.716-17.235-17.235
-                S20.481,12.768,30,12.768c9.519,0,17.235,7.716,17.235,17.235S39.519,47.239,30,47.239z"/>
-                </svg>
-
-            </div>
-            <div class="etcd-selector-item etcd-selector-table" ng-click="showTable()">
-                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-                preserveAspectRatio="xMinYMin" viewBox="0 0 59.496 59.503" enable-background="new 0 0 59.496 59.503" xml:space="preserve">
-                <rect x="0" y="0" fill="#1D1D1B" width="59.496" height="13.111"/>
-                <rect x="0" y="23.196" fill="#1D1D1B" width="59.496" height="13.111"/>
-                <rect x="0" y="46.392" fill="#1D1D1B" width="59.496" height="13.111"/>
-                </svg>
-            </div>
-        </div>
-        <div class="etcd-graph">
-            <h2>Peer Latency</h2>
-            <div class="etcd-graph-container" id="latency">
-            </div>
-        </div>
-        <div class="etcd-list">
-            <h2>Peer List</h2>
-            <table cellpadding="0" cellspacing="0">
-            <thead>
-                <td class="etcd-name-header">Peer Name</td>
-                <td class="etcd-latency">Latency</td>
-            </thead>
-            <tbody>
-                <tr ng-repeat="peer in peers">
-                    <td ng-switch on="{true:'leader', false: 'follower'}[leaderName == peer.name]">
-                        <div ng-switch-when="leader">{{peer.name}}<span class="etcd-peer-type">(leader)</span></div>
-                        <div ng-switch-default>{{peer.name}}</div>
-                    </td>
-                    <td>
-                        <div class="etcd-square ng-class: {'etcd-square-green': peer.latency.current < 25, 'etcd-square-orange': peer.latency.current < 60, 'etcd-square-red': peer.latency.current >= 60}"></div>
-                        <div class="etcd-latency-value">{{peer.latency.current | number:1 }} ms</div>
-                    </td>
-                </tr>
-            </tbody>
-            </table>
-        </div>
-    </div>
-</div>

+ 0 - 22
mod/dashboard/bower.json

@@ -1,22 +0,0 @@
-{
-  "name": "etcdDashboard",
-  "version": "0.0.0",
-  "dependencies": {
-    "angular": "~1.2.0-rc.2",
-    "json3": "~3.2.4",
-    "jquery": "~1.9.1",
-    "bootstrap-sass": "~2.3.1",
-    "es5-shim": "~2.0.8",
-    "angular-route": "~1.2.0-rc.2",
-    "angular-resource": "~1.2.0-rc.2",
-    "angular-cookies": "~1.2.0-rc.2",
-    "angular-sanitize": "~1.2.0-rc.2",
-    "d3": "~3.3.6",
-    "moment": "~2.3.0",
-    "underscore.string": "~2.3.3"
-  },
-  "devDependencies": {
-    "angular-mocks": "~1.2.0-rc.2",
-    "underscore": "~1.5.2"
-  }
-}

+ 0 - 18
mod/dashboard/build

@@ -1,18 +0,0 @@
-#!/bin/bash -e
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cd ${DIR}
-git clean -x -f dist
-
-npm install
-bower install
-grunt build
-
-go get github.com/jteeuwen/go-bindata/...
-
-dirs=
-for i in `find dist -type d`; do
-	dirs="${dirs} ${i}"
-done
-
-${GOPATH}/bin/go-bindata -nomemcopy -pkg "resources" -o resources/resources.go -prefix dist ${dirs}

+ 0 - 63
mod/dashboard/dashboard.go

@@ -1,63 +0,0 @@
-package dashboard
-
-import (
-	"bytes"
-	"net/http"
-	"os"
-	"path"
-	"time"
-
-	"github.com/coreos/etcd/log"
-	"github.com/coreos/etcd/mod/dashboard/resources"
-)
-
-func memoryFileServer(w http.ResponseWriter, req *http.Request) {
-	log.Debugf("[recv] %s %s [%s]", req.Method, req.URL.Path, req.RemoteAddr)
-	upath := req.URL.Path
-	if len(upath) == 0 {
-		upath = "index.html"
-	}
-
-	// TODO: use the new mux to do this work
-	dir, file := path.Split(upath)
-	if file == "browser" || file == "stats" {
-		file = file + ".html"
-	}
-	upath = path.Join(dir, file)
-	b, err := resources.Asset(upath)
-
-	if err != nil {
-		http.Error(w, upath+": File not found", http.StatusNotFound)
-		return
-	}
-
-	http.ServeContent(w, req, upath, time.Time{}, bytes.NewReader(b))
-	return
-}
-
-func getDashDir() string {
-	return os.Getenv("ETCD_DASHBOARD_DIR")
-}
-
-// DashboardHttpHandler either uses the compiled in virtual filesystem for the
-// dashboard assets or if ETCD_DASHBOARD_DIR is set uses that as the source of
-// assets.
-func HttpHandler() (handler http.Handler) {
-	handler = http.HandlerFunc(memoryFileServer)
-
-	// Serve the dashboard from a filesystem if the magic env variable is enabled
-	dashDir := getDashDir()
-	if len(dashDir) != 0 {
-		log.Debugf("Using dashboard directory %s", dashDir)
-		handler = http.FileServer(http.Dir(dashDir))
-	}
-
-	return handler
-}
-
-// Always returns the index.html page.
-func IndexPage(w http.ResponseWriter, req *http.Request) {
-	dashDir := getDashDir()
-	http.ServeFile(w, req, path.Join(dashDir, "index.html"))
-	return
-}

+ 0 - 54
mod/dashboard/karma-e2e.conf.js

@@ -1,54 +0,0 @@
-// Karma configuration
-// http://karma-runner.github.io/0.10/config/configuration-file.html
-
-module.exports = function(config) {
-  config.set({
-    // base path, that will be used to resolve files and exclude
-    basePath: '',
-
-    // testing framework to use (jasmine/mocha/qunit/...)
-    frameworks: ['ng-scenario'],
-
-    // list of files / patterns to load in the browser
-    files: [
-      'test/e2e/**/*.js'
-    ],
-
-    // list of files / patterns to exclude
-    exclude: [],
-
-    // web server port
-    port: 8080,
-
-    // level of logging
-    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: false,
-
-
-    // Start these browsers, currently available:
-    // - Chrome
-    // - ChromeCanary
-    // - Firefox
-    // - Opera
-    // - Safari (only Mac)
-    // - PhantomJS
-    // - IE (only Windows)
-    browsers: ['Chrome'],
-
-
-    // Continuous Integration mode
-    // if true, it capture browsers, run tests and exit
-    singleRun: false
-
-    // Uncomment the following lines if you are using grunt's server to run the tests
-    // proxies: {
-    //   '/': 'http://localhost:9000/'
-    // },
-    // URL root prevent conflicts with the site root
-    // urlRoot: '_karma_'
-  });
-};

+ 0 - 52
mod/dashboard/karma.conf.js

@@ -1,52 +0,0 @@
-// Karma configuration
-// http://karma-runner.github.io/0.10/config/configuration-file.html
-
-module.exports = function(config) {
-  config.set({
-    // base path, that will be used to resolve files and exclude
-    basePath: '',
-
-    // testing framework to use (jasmine/mocha/qunit/...)
-    frameworks: ['jasmine'],
-
-    // list of files / patterns to load in the browser
-    files: [
-      'app/bower_components/angular/angular.js',
-      'app/bower_components/angular-mocks/angular-mocks.js',
-      'app/scripts/*.js',
-      'app/scripts/**/*.js',
-      'test/mock/**/*.js',
-      'test/spec/**/*.js'
-    ],
-
-    // list of files / patterns to exclude
-    exclude: [],
-
-    // web server port
-    port: 8080,
-
-    // level of logging
-    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: false,
-
-
-    // Start these browsers, currently available:
-    // - Chrome
-    // - ChromeCanary
-    // - Firefox
-    // - Opera
-    // - Safari (only Mac)
-    // - PhantomJS
-    // - IE (only Windows)
-    browsers: ['Chrome'],
-
-
-    // Continuous Integration mode
-    // if true, it capture browsers, run tests and exit
-    singleRun: false
-  });
-};

+ 0 - 36
mod/dashboard/package.json

@@ -1,36 +0,0 @@
-{
-  "name": "etcd-dashboard",
-  "version": "0.0.0",
-  "dependencies": {},
-  "devDependencies": {
-    "grunt": "~0.4.1",
-    "grunt-contrib-copy": "~0.4.1",
-    "grunt-contrib-concat": "~0.3.0",
-    "grunt-contrib-coffee": "~0.7.0",
-    "grunt-contrib-uglify": "~0.2.0",
-    "grunt-contrib-compass": "~0.5.0",
-    "grunt-contrib-jshint": "~0.6.0",
-    "grunt-contrib-cssmin": "~0.6.0",
-    "grunt-contrib-clean": "~0.5.0",
-    "grunt-contrib-htmlmin": "~0.1.3",
-    "grunt-contrib-imagemin": "~0.2.0",
-    "grunt-contrib-watch": "~0.5.2",
-    "grunt-autoprefixer": "~0.2.0",
-    "grunt-usemin": "~2.0.2",
-    "grunt-svgmin": "~0.2.0",
-    "grunt-rev": "~0.1.0",
-    "grunt-open": "~0.2.0",
-    "grunt-concurrent": "~0.3.0",
-    "load-grunt-tasks": "~0.1.0",
-    "grunt-google-cdn": "~0.2.0",
-    "grunt-ngmin": "~0.0.2",
-    "time-grunt": "~0.1.0",
-    "grunt-karma": "~0.6.2"
-  },
-  "engines": {
-    "node": ">=0.8.0"
-  },
-  "scripts": {
-    "test": "grunt test"
-  }
-}

+ 0 - 35
mod/dashboard/test/.jshintrc

@@ -1,35 +0,0 @@
-{
-  "node": true,
-  "browser": true,
-  "esnext": true,
-  "bitwise": true,
-  "camelcase": true,
-  "curly": true,
-  "eqeqeq": true,
-  "immed": true,
-  "indent": 2,
-  "latedef": true,
-  "newcap": true,
-  "noarg": true,
-  "quotmark": "single",
-  "regexp": true,
-  "undef": true,
-  "unused": true,
-  "strict": true,
-  "trailing": true,
-  "smarttabs": true,
-  "globals": {
-    "after": false,
-    "afterEach": false,
-    "angular": false,
-    "before": false,
-    "beforeEach": false,
-    "browser": false,
-    "describe": false,
-    "expect": false,
-    "inject": false,
-    "it": false,
-    "spyOn": false
-  }
-}
-

+ 0 - 10
mod/dashboard/test/runner.html

@@ -1,10 +0,0 @@
-<!doctype html>
-<html lang="en">
-  <head>
-    <title>End2end Test Runner</title>
-    <script src="vendor/angular-scenario.js" ng-autotest></script>
-    <script src="scenarios.js"></script>
-  </head>
-  <body>
-  </body>
-</html>

+ 0 - 22
mod/dashboard/test/spec/controllers/main.js

@@ -1,22 +0,0 @@
-'use strict';
-
-describe('Controller: MainCtrl', function () {
-
-  // load the controller's module
-  beforeEach(module('etcdDashboardApp'));
-
-  var MainCtrl,
-    scope;
-
-  // Initialize the controller and a mock scope
-  beforeEach(inject(function ($controller, $rootScope) {
-    scope = $rootScope.$new();
-    MainCtrl = $controller('MainCtrl', {
-      $scope: scope
-    });
-  }));
-
-  it('should attach a list of awesomeThings to the scope', function () {
-    expect(scope.awesomeThings.length).toBe(3);
-  });
-});

Некоторые файлы не были показаны из-за большого количества измененных файлов