Repository: tabulapdf/tabula Branch: master Commit: 1b8b60fa71a6 Files: 66 Total size: 710.7 KB Directory structure: gitextract_p3cg83uv/ ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── release.yml ├── .gitignore ├── .ruby-version ├── .travis.yml ├── AUTHORS.md ├── CONTRIBUTING.md ├── Dockerfile ├── Gemfile ├── Jarfile ├── LICENSE.md ├── NOTICE.txt ├── README.md ├── Rakefile ├── build/ │ ├── appbundler-1.0.jar │ ├── dist-LICENSE.txt │ ├── dist-README.txt │ └── icons/ │ └── tabula.icns ├── build.xml ├── config.rb ├── config.ru ├── docker-compose.yml ├── lib/ │ ├── tabula_java_wrapper.rb │ ├── tabula_job_executor/ │ │ ├── executor.rb │ │ └── jobs/ │ │ ├── detect_tables.rb │ │ ├── generate_document_data.rb │ │ └── generate_thumbnails.rb │ ├── tabula_workspace.rb │ └── thumbnail_generator.rb └── webapp/ ├── index.html ├── static/ │ ├── css/ │ │ ├── _bootstrap-variables.scss │ │ ├── selectors.css │ │ └── styles.css │ ├── js/ │ │ ├── debug_pdf_view.js │ │ ├── library.js │ │ ├── pdf_view.js │ │ ├── rectangularSelector.js │ │ ├── resizableSelection.js │ │ ├── tabula.js │ │ ├── template_library.js │ │ └── vendor/ │ │ ├── backbone-min.js │ │ ├── bootstrap/ │ │ │ ├── affix.js │ │ │ ├── alert.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── tooltip.js │ │ │ └── transition.js │ │ ├── bootstrap.js │ │ ├── handlebars-v1.3.0.js │ │ ├── table2CSV.js │ │ ├── underscore-min.js │ │ └── upload-group.js │ ├── sass/ │ │ ├── _bootstrap-variables.scss │ │ ├── selectors.scss │ │ └── styles.scss │ └── swf/ │ └── ZeroClipboard.swf ├── tabula_debug.rb ├── tabula_job_progress.rb ├── tabula_settings.rb └── tabula_web.rb ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms open_collective: tabulapdf ================================================ FILE: .github/workflows/release.yml ================================================ on: release: types: [published] permissions: contents: read packages: write jobs: release: runs-on: ubuntu-latest steps: - uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - uses: docker/build-push-action@v4 with: push: true tags: | ghcr.io/${{ github.repository }}:${{ github.ref_name }} ghcr.io/${{ github.repository }}:latest ================================================ FILE: .gitignore ================================================ static/pdfs local_settings.rb tabula.war .sass-cache lib/jars/javacv* .ruby-gemset TEST_PDFS .DS_Store build/Tabula.app build/tabula.jar build/tabula-*.zip build/mac build/windows build/tabula launch4j/ # Based on https://github.com/github/gitignore/blob/master/Ruby.gitignore *.gem *.rbc *.swp .bundle .config .DS_store coverage InstalledFiles lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp ================================================ FILE: .ruby-version ================================================ jruby-9.2.13.0 ================================================ FILE: .travis.yml ================================================ sudo: false language: ruby dist: trusty before_install: - gem update --system - gem install bundler - gem install jbundler rvm: - jruby-9.1.9.0 jdk: - oraclejdk8 - openjdk7 script: bundle exec jbundle install && bundle exec rake war && bundle exec rake jardist notifications: email: false ================================================ FILE: AUTHORS.md ================================================ # Authors & Acknowledgments Tabula was originally started by Manuel Aristarán in late 2012. The PRIMARY AUTHORS are (and/or have been): * Manuel Aristarán - MIT Media Lab (formerly La Nación, Knight-Mozilla OpenNews) * Mike Tigas - ProPublica, Knight-Mozilla OpenNews * Jeremy B. Merrill - The New York Times (formerly ProPublica) * Jason Das, designer * David Frackman * Travis Swicegood - Texas Tribune Special thanks to these organizations: * Knight-Mozilla OpenNews * ProPublica * La Nación * The New York Times * Knight Lab at Northwestern University * The John S. and James L. Knight Foundation ================================================ FILE: CONTRIBUTING.md ================================================ CONTRIBUTING ============ Tabula is an open-source project, which means it depends on volunteers to build and improve it. Interested in helping out? We'd love to have your help! You can help by: - [Reporting a bug](https://github.com/tabulapdf/tabula/issues/new). - Adding or editing documentation. - Contributing code via a Pull Request from ideas listed in the [Enhancements](https://github.com/tabulapdf/tabula/labels/enhancement) section of the issues. - Spreading the word about Tabula to people who might be able to benefit from using it. Did you have a problem? Guidelines for reporting a bug ------------------------------------------------------ Did Tabula not work for you? We'd like to know about it. We'd also like to know if Tabula worked, but wasn't as easy or useful as it could be. Here's what you can tell us to so we can help you better. 1. What error message did you get? (We need the whole thing! If it looks like gobbledygook to you, it's probably very useful to us. That's why it's there!) 2. What steps did you take? The more precise, the better. 3. What PDF were you trying to extract data from? Some PDFs are wacky, so seeing the exact PDF will be useful. We understand that sometimes PDFs are confidential. If you can share it, just not publicly, send us an email. If you cant', we understand, but might not be able to help you. 4. What version of Tabula are you using? If you're using an older version, we may have solved the problem already. 5. What platform are you on? Windows 7 or 8? Mac? Linux? If your computer uses a language other than English or Spanish, we'd like to know that too. Guidelines for contributing code -------------------------------- If you'd like to contribute code, here's some stuff you should know: You're also welcome to send us a note, if you'd like. All of our email addresses are listed on our Github pages. Tabula comes in a bunch of parts, all located in the [TabulaPDF Github organization](https://github.com/tabulapdf). -The [tabula](https://github.com/tabulapdf/tabula) repo is the UI. We aim for it to soon be all front-end, but right now has a small web server, written in Ruby, to interface between the front-end and extractor library, called "tabula-extractor" - [tabula-java](https://github.com/tabulapdf/tabula-java/) is a pure Java port, for speed/wider usability. The [Enhancements](https://github.com/tabulapdf/tabula/labels/enhancement) section of the issues lists some important improvements to Tabula that you could try out. They're well-suited to contributors, since they don't depend on a deep knowledge of all of Tabula's parts and they don't depend on close coordination. ================================================ FILE: Dockerfile ================================================ FROM jruby:9.2-jdk RUN apt-get update -qq && apt-get install -y build-essential git \ && apt-get clean && rm -rf /var/lib/apt/lists/* RUN echo 'gem: --no-rdoc --no-ri' >> /.gemrc ENV GEM_HOME /usr/local/bundle ENV PATH $GEM_HOME/bin:$PATH RUN gem install bundler -v '< 2' \ && bundle config --global path "$GEM_HOME" \ && bundle config --global bin "$GEM_HOME/bin" # don't create ".bundle" in all our apps ENV BUNDLE_APP_CONFIG $GEM_HOME WORKDIR /app EXPOSE 9292 CMD ["jruby", "-G", "-r", "jbundler", "-S", "rackup", "-o", "0.0.0.0", "config.ru"] # these didn't work as ONBUILD, strangely. Idk why. -JBM COPY Gemfile Gemfile.lock Jarfile Jarfile.lock ./ RUN bundle install && jruby -S jbundle install COPY . . ================================================ FILE: Gemfile ================================================ #since war/jar bundle requires gem package; use gem-in-a-box for testing #or execute tabula via "rackup". #source "http://127.0.0.1:9292" source "https://rubygems.org" platform :jruby do gem "cuba", "~> 3.9.2" gem "rack", ">= 2.0.6" gem "tilt", "~> 2.0.8" group :development do gem 'jar-dependencies', '0.3.12' gem 'jbundler', '~> 0.9.3' gem "rake" gem "warbler", "~> 2.0.5" gem "jruby-jars", "9.2.0.0" gem "bootstrap-sass", ">= 3.4.1" gem "compass" end end ================================================ FILE: Jarfile ================================================ jar 'technology.tabula:tabula', '1.0.4' ================================================ FILE: LICENSE.md ================================================ Copyright (C) 2012-2020 Manuel Aristarán Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: NOTICE.txt ================================================ Tabula © 2012-2020 Manuel Aristarán. Available under MIT License. See `AUTHORS.md` and `LICENSE.md`. This product includes software (lib/pdfbox-app-1.8.0.jar) developed at The Apache Software Foundation (http://www.apache.org/). ================================================ FILE: README.md ================================================ **Is `tabula` an active project?** Tabula is, and always has been, a volunteer-run project. We've occasionally had funding for specific features, but it's never been a commercial undertaking. At the moment, none of the original authors have the time to actively work on the project. The end-user application, hosted on this repo, is unlikely to see updates from us in the near future. [`tabula-java`](https://github.com/tabulapdf/tabula-java) sees updates and occasional bug-fix releases from time to time. -- **Repo Note**: The `master` branch is an *in development* version of Tabula. This may be substantially different from the latest [releases of Tabula](https://github.com/tabulapdf/tabula/releases). --- # Tabula [tabula `master`](https://github.com/tabulapdf/tabula/tree/master) [![Build Status](https://travis-ci.org/tabulapdf/tabula.svg?branch=master)](https://travis-ci.org/tabulapdf/tabula) Tabula helps you liberate data tables trapped inside PDF files. * [Download from the official site](http://tabula.technology/) * [Read more about Tabula on OpenNews Source](https://source.opennews.org/en-US/articles/introducing-tabula/) * Interested in using Tabula on the command-line? Check out [tabula-java](https://github.com/tabulapdf/tabula-java), a Java library and command-line interface for Tabula. (This is the extraction library that powers Tabula.) © 2012-2020 Manuel Aristarán. Available under MIT License. See [`AUTHORS.md`](AUTHORS.md) and [`LICENSE.md`](LICENSE.md). - [Why Tabula?](#why-tabula) - [Using Tabula](#using-tabula) - [Known issues](#known-issues) - [Incorporating Tabula into your own project](#incorporating-tabula-into-your-own-project) - [Running Tabula from source (for developers)](#running-tabula-from-source-for-developers) - [Building a packaged application version](#building-a-packaged-application-version) - [Contributing](#contributing) - [Backers](#backers) ## Why Tabula? If you’ve ever tried to do anything with data provided to you in PDFs, you know how painful this is — you can’t easily copy-and-paste rows of data out of PDF files. Tabula allows you to extract that data in CSV format, through a simple web interface. **Caveat**: Tabula only works on text-based PDFs, not scanned documents. If you can click-and-drag to select text in your table in a PDF viewer (even if the output is disorganized trash), then your PDF is text-based and Tabula should work. **Security Concerns?**: Tabula is designed with security in mind. Your PDF and the extracted data *never* touch the net -- when you use Tabula on your local machine, as long as your browser's URL bar says "localhost" or "127.0.0.1", all processing takes place on your local machine. Other than to retrieve a few badges and other static assets, there are two calls that are made from your browser to external machines; one fetches the list of latest Tabula versions from GitHub to alert you if Tabula has been updated, the other makes a call to a stats counter that helps us determine how often various versions of Tabula are being used. If this is a problem, the version check can be disabled by adding `-Dtabula.disable_version_check=1` to the command line at startup, and the stats counter call can be disabled by adding `-Dtabula.disable_notifications=1`. Please note: If you are providing Tabula as a service using a reverse SSL proxy, users [may notice a security warning](https://github.com/tabulapdf/tabula/issues/924) due to our stats counter endpoint being hosted at a non-secure URL, so you may wish to disable the notifications in this scenario. ## Using Tabula First, make sure you have a recent copy of Java installed. You can [download Java here][jre_download]. Tabula requires a Java Runtime Environment compatible with Java 7 (i.e. Java 7, 8 or higher). If you have a problem, check [Known Issues](#knownissues) first, then [report an issue](http://www.github.com/tabulapdf/tabula/issues). * ### Windows Download `tabula-win.zip` from [the download site][tabula_dl]. Unzip the whole thing and open the `tabula.exe` file inside. A browser should automatically open to http://127.0.0.1:8080/ . If not, open your web browser of choice and visit that link. To close Tabula, just go back to the console window and press "Control-C" (as if to copy). * ### Mac OS X Download `tabula-mac.zip` from [the download site][tabula_dl]. Unzip and open the Tabula app inside. A browser should automatically open to http://127.0.0.1:8080/ . If not, open your web browser of choice and visit that link. To close Tabula, find the Tabula icon in your dock, right-click (or control-click) on it, and press "Quit". Note: If you’re running Mac OS X 10.8 or later, you might get an error like "Tabula is damaged and can't be opened." We're working on fixing this, but click [here](#gatekeeper) for a workaround. * ### Linux snap Tabula is packaged as a snap package. If you have snap on your system, you can install it with ```bash sudo snap install tabula ``` * ### Other platforms (e.g. Linux) Download `tabula-jar.zip` from [the download site][tabula_dl] and unzip it to the directory of your choice. Open a terminal window, and `cd` to inside the `tabula` directory you just unzipped. Then run: `java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -jar tabula.jar` Then manually navigate your browser to http://127.0.0.1:8080/ (New in Tabula 1.1. To go back to the old behavior that automatically launches your web browser, use the `-Dtabula.openBrowser=true` option. Tabula binds to port 8080 by default. You can change it with the `warbler.port` option; for example, to use port 9999: `java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -Dwarbler.port=9999 -jar tabula.jar` * ### [Docker Compose](https://docs.docker.com/compose/) quick start using [Amazon Correttto](https://github.com/corretto) image Make a new directory e.g. `tabulapdf` and enter it. `mkdir -p /opt/docker/tabulapdf` `cd /opt/docker/tabulapdf` Download tabula-jar package - for example version 1.2.1 `wget https://github.com/tabulapdf/tabula/releases/download/v1.2.1/tabula-jar-1.2.1.zip` verify checksum (compare output with the release page) `sha256sum tabula-jar-1.2.1.zip` and unzip it. `unzip tabula-jar-1.2.1.zip` Place or create a `docker-compose.yml` file, adjust accordingly ``` ### tabulapdf docker-compose.yml example ### services: tabulapdf: image: amazoncorretto:17 container_name: tabulapdf-app command: > java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -Dwarbler.port=8080 -Dtabula.openBrowser=false -jar /app/tabula.jar volumes: - ./tabula:/app ports: - "8080:8080" ``` Run the app with `docker compose up -d` The app will be exposed on port 8080 and can be easily paired with a reverse proxy e.g. traefik If the program fails to run, double-check that you have [Java installed][jre_download] and then try again. [jre_download]: https://www.java.com/download/ [tabula_dl]: http://tabula.technology ## Known issues There are some bugs that we're aware of that we haven't managed to fix yet. If there's not a solution here or you need more help, please go ahead and [report an issue](http://www.github.com/tabulapdf/tabula/issues). * **Legacy Java Environment (SE 6) Is Required:** (Mac): The Mac operating system recently changed how it packages the Java Runtime Environment. If you get this error, download Tabula's ["large experimental" package](https://github.com/tabulapdf/tabula/releases/download/v0.9.7/tabula-mac-0.9.7-large-experimental.zip). This package includes its own Java Runtime Environment and should work without this issue. * **"Tabula is damaged and can't be opened"** (Mac): If you’re running Mac OS X 10.8 or later, GateKeeper may prevent you from opening the Tabula app. Please [see this GateKeeper page][gatekeeper] for more information. 1. Right-click on Tabula.app and select Open from the context menu. 2. The system will tell you that the application is "from an unidentified developer" and ask you whether you want to open it. Click Open to allow the application to run. The system remembers this choice and won't prompt you again. (If you continue to have issues, double-check the [OS X GateKeeper documentation][gatekeeper] for more information.) [gatekeeper]: http://support.apple.com/kb/HT5290 * **org.jruby.exceptions.RaiseException: (Encoding::CompatibilityError) incompatible character encodings:** (Windows): Your Windows computer expects a type of encoding other than Unicode or Windows's English encoding. You can fix this by entering a few simple commands in the Command Prompt. (The commands won't affect anything besides Tabula.) 1. Open a Command Prompt 2. type `cd` and then the path to the directory that contains `tabula.exe`, e.g. `cd C:\Users\Username\Downloads` 3. Change that terminal's codepage to Unicode by typing: `chcp 65001` 4. Run Tabula by typing `tabula.exe` * **A browser tab opens, but something other than Tabula loads there. Or Tabula doesn't start.** It's possible another program is using port 8080, which Tabula binds to by default. You can try closing the other program, or change the port Tabula uses by running Tabula from the terminal with the `warbler.port` property: `java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -Dwarbler.port=9999 -jar tabula.jar` ## Incorporating Tabula into your own project Tabula is open-source, so we'd love for you to incorporate pieces of Tabula into your own projects. The "guts" of Tabula -- that is, the logic and heuristics that reconstruct tables from PDFs -- is contained in the [tabula-java](https://github.com/tabulapdf/tabula-java/) repo. There's a JAR file that you can easily incorporate into JVM languages like Java, Scala or Clojure and it includes a command-line tool for you to automate your extraction tasks. Visit that repo for more information on how to use `tabula-java` on the CLI and on how Tabula exports `tabula-java` scripts. ### Bindings: Tabula has bindings for JRuby and R. If you end up writing bindings for another language, let us know and we'll add a link here. - [tabulizer](https://github.com/leeper/tabulizer) provides [R](https://www.r-project.org/) bindings for tabula-java and is community-supported by [@leeper](https://github.com/leeper). - [tabula-js](https://github.com/ezodude/tabula-js) provides [Node.js](https://nodejs.org/en/) bindings for tabula-java; it is community-supported by [@ezodude](https://github.com/ezodude). - [tabula-py](https://github.com/chezou/tabula-py) provides [Python](https://python.org) bindings for tabula-java; it is community-supported by [@chezou](https://github.com/chezou). - [tabula-extractor](https://github.com/tabulapdf/tabula-extractor/) *DEPRECATED* - Provides JRuby bindings for tabula-java ## Running Tabula from source (for developers) 1. Download JRuby. You can install it from its website, or using tools like `rvm` or `rbenv`. Note that as of Tabula 1.1.0 (7875582becb2799b65586d5680782cafd399bb33), Tabula uses the JRuby 9000 series (i.e. JRuby 9.1.5.0). 2. Download Tabula and install the Ruby dependencies. (Note: if using `rvm` or `rbenv`, ensure that JRuby is being used. ~~~ git clone git://github.com/tabulapdf/tabula.git cd tabula gem install bundler -v 1.17.3 bundle install jruby -S jbundle install ~~~ **Then, start the development server:** jruby -G -r jbundler -S rackup (If you get encoding errors, set the `JAVA_OPTS` environment variable to `-Dfile.encoding=utf-8`) The site instance should now be viewable at http://127.0.0.1:9292/ . You can a couple some options when executing the server in this manner: TABULA_DATA_DIR="/tmp/tabula" \ TABULA_DEBUG=1 \ jruby -G -r jbundler -S rackup * `TABULA_DATA_DIR` controls where uploaded data for Tabula is stored. By default, data is stored in the OS-dependent application data directory for the current user. (similar to: `C:\Users\foo\AppData\Roaming\Tabula` on Windows, `~/Library/Application Support/Tabula` on Mac, `~/.tabula` on Linux/UNIX) * `TABULA_DEBUG` prints out extra status data when PDF files are being processed. (`false` by default.) **Alternatively, running the server as a JAR file** Testing in this manner will be closer to testing the "packaged application" version of the app. jruby -G -S rake war java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -jar build/tabula.jar If you intend to develop against an unreleased version of [`tabula-java`](https://github.com/tabulapdf/tabula-java), you need to install its JAR to your local Maven repository. From the directory that contains `tabula-java` source: mvn install:install-file -Dfile=target/tabula--SNAPSHOT.jar -DgroupId=technology.tabula -DartifactId=tabula -Dversion=-SNAPSHOT -Dpackaging=jar -DpomFile=pom.xml Then, adjust the `Jarfile` accordingly. ### Building a packaged application version After performing the above steps ("Running Tabula from source"), you can compile Tabula into a standalone application: **Mac OS X** If you wish to share Tabula with other machines, you will need a codesigning certificate. Our distribution of Tabula uses a self-signed certificate, as noted above. See [this section of build.xml][buildxml_cert] for details. If you will only be running Tabula on the machine you are building it on, you may remove this entire block (lines 44-53). To compile the app: WEBSERVER_VERSION=9.4.31.v20200723 MAVEN_REPO=https://repo1.maven.org/maven2 rake macosx This will result in a portable "tabula_mac.zip" archive (inside the `build` directory) for Mac OS X users. Note that the Mac version bundles Java with the Tabula app. This results in a 98MB zip file, versus the 30MB zip file for other platforms, but allows users to run Tabula without having to worry about [Java version incompatibilities](https://github.com/tabulapdf/tabula/issues/237). [buildxml_cert]: https://github.com/tabulapdf/tabula/blob/master/build.xml#L44-53 **Windows** You can build .exe files for the Windows target on any platform. Download a [3.1.X (beta) copy of Launch4J][launch4j]. Unzip it into the Tabula repo so that "launch4j" (with subdirectories "bin", etc.) is in the repository root. (If you're building on a 64bit Linux, you may need to install 32bit libs like, in Ubuntu `sudo apt-get install lib32z1 lib32ncurses5`) Then: WEBSERVER_VERSION=9.4.31.v20200723 MAVEN_REPO=https://repo1.maven.org/maven2 rake windows This will result in a portable "tabula_win.zip" archive (inside the `build` directory) for Mac OS X users. --- If you have issues, you can try building manually. (These commands are for OS X/Linux and may need to be adjusted for Windows users.) # (from the root directory of the repo) WEBSERVER_VERSION=9.4.31.v20200723 MAVEN_REPO=https://repo1.maven.org/maven2 rake war cd launch4j ant -f ../build.xml windows A "tabula.exe" file will be generated in "build/windows". To run, the exe file needs "tabula.jar" (contained in "build") in the same directory. You can create a .zip archive by doing: # (from the root directory of the repo) cd build/windows mkdir tabula cp tabula.exe ./tabula/ cp ../tabula.jar ./tabula/ zip -r9 tabula_win.zip tabula rm -fr tabula [launch4j]: http://sourceforge.net/projects/launch4j/files/launch4j-3/3.1.0-beta1/ ## Contributing Interested in helping out? We'd love to have your help! You can help by: - [Reporting a bug](https://github.com/tabulapdf/tabula/issues). - Adding or editing documentation. - Contributing code via a Pull Request from ideas or bugs listed in the [Enhancements](https://github.com/tabulapdf/tabula/labels/enhancement) section of the issues. [see `CONTRIBUTING.md`](CONTRIBUTING.md) - Spreading the word about Tabula to people who might be able to benefit from using it. ### Backers You can also support our continued work on Tabula with a one-time or monthly donation [on OpenCollective](https://opencollective.com/tabulapdf#support). Organizations who use Tabula can also [sponsor the project](https://opencollective.com/tabulapdf#support) for acknowledgement on [our official site](http://tabula.technology/) and this README. Tabula is made possible in part through the generosity of our users and through grants from the Knight Foundation and the Shuttleworth Foundation. Special thanks to all the users and organizations that support Tabula! The John S. and James L. Knight Foundation The Shuttleworth Foundation More acknowledgments can be found in [`AUTHORS.md`](AUTHORS.md). ================================================ FILE: Rakefile ================================================ require 'fileutils' require 'warbler' ########## java jar compilation ########## Warbler::Task.new("war", Warbler::Config.new { |config| config.features = %w(executable) config.jar_name = 'build/tabula' config.jar_extension = 'jar' config.webserver = "jetty" config.webxml.jruby.compat.version = "1.9" config.webxml.jruby.rack.logging = "stderr" config.dirs = ['lib', 'webapp'] config.override_gem_home = false config.init_contents << StringIO.new("\nGem.clear_paths\nGem.path\n\n") } ) # version we're building def build_version ENV['TABULA_VERSION'] || "rev#{`git rev-list --max-count=1 HEAD`.strip}" end def invoke_ant(*args) IO.popen("ant #{args.join(' ')}") { |f| yield f } end ########## distribution bundles ########## task :create_version_file do |t| puts "Creating version file (#{build_version})..." tabula_dir = File.expand_path(File.dirname(__FILE__)) rb_file = <<-eos $TABULA_VERSION = "#{build_version}" eos File.open(File.join(tabula_dir, 'webapp', 'tabula_version.rb'), 'wb') do |f| f.write rb_file end end task :delete_version_file do |t| tabula_dir = File.expand_path(File.dirname(__FILE__)) FileUtils.rm(File.join(tabula_dir, 'webapp', 'tabula_version.rb')) end task :jardist => [:create_version_file, :war] do |t| tabula_dir = File.expand_path(File.dirname(__FILE__)) build_dir = File.join(tabula_dir, "build") dist_dir = File.join(build_dir, "jardist", "tabula") if File.exist?(File.join(build_dir, "jardist")) FileUtils.rm_rf(File.join(build_dir, "jardist")) end puts "\n======================================================" puts "Building jar zip file bundle..." puts "======================================================\n\n" Dir.mkdir(File.join(build_dir, "jardist")) Dir.mkdir(File.join(build_dir, "jardist", "tabula")) jar_src = File.join(build_dir, "tabula.jar") jar_dst = File.join(dist_dir, "tabula.jar") FileUtils.cp(jar_src, jar_dst) readme_src = File.join(build_dir, "dist-README.txt") readme_dst = File.join(dist_dir, "README.txt") FileUtils.cp(readme_src, readme_dst) lic_src = File.join(build_dir, "dist-LICENSE.txt") lic_dst = File.join(dist_dir, "LICENSE.txt") FileUtils.cp(lic_src, lic_dst) authors_src = File.join(tabula_dir, "AUTHORS.md") authors_dst = File.join(dist_dir, "AUTHORS.txt") FileUtils.cp(authors_src, authors_dst) cd File.join(build_dir, "jardist") output = File.join(build_dir, "tabula-jar-#{build_version}.zip") if File.exists?(output) File.delete(output) end IO.popen("zip -r9 #{output} tabula") { |f| f.each { |line| puts line } } FileUtils.rm_rf(dist_dir) puts "\n======================================================" puts "Zip file saved to #{output}" puts "======================================================\n\n" end task :macosx => [:create_version_file, :war] do |t| tabula_dir = File.expand_path(File.dirname(__FILE__)) build_dir = File.join(tabula_dir, "build") dist_dir = File.join(build_dir, "mac", "tabula") cd File.join(tabula_dir) if File.exist?(File.join(build_dir, "mac")) FileUtils.rm_rf(File.join(build_dir, "mac")) end puts "\n======================================================" puts "Building Mac OS X app..." puts "======================================================\n\n" invoke_ant("-Dfull_version=#{build_version}", "-v", "macbundle") { |f| f.each { |line| puts line } } puts "\n======================================================" puts "Creating zip file bundle..." puts "======================================================\n\n" Dir.mkdir(dist_dir) app_src = File.join(build_dir, "mac", "Tabula.app") app_dst = File.join(dist_dir, "Tabula.app") FileUtils.mv(app_src, app_dst) readme_src = File.join(build_dir, "dist-README.txt") readme_dst = File.join(dist_dir, "README.txt") FileUtils.cp(readme_src, readme_dst) lic_src = File.join(build_dir, "dist-LICENSE.txt") lic_dst = File.join(dist_dir, "LICENSE.txt") FileUtils.cp(lic_src, lic_dst) authors_src = File.join(tabula_dir, "AUTHORS.md") authors_dst = File.join(dist_dir, "AUTHORS.txt") FileUtils.cp(authors_src, authors_dst) cd File.join(build_dir, "mac") output = File.join(build_dir, "tabula-mac-#{build_version}.zip") if File.exists?(output) File.delete(output) end IO.popen("zip -r9 #{output} tabula") { |f| f.each { |line| puts line } } FileUtils.rm_rf(dist_dir) puts "\n======================================================" puts "Zip file saved to #{output}" puts "======================================================\n\n" end task :windows => [:create_version_file, :war] do |t| tabula_dir = File.expand_path(File.dirname(__FILE__)) build_dir = File.join(tabula_dir, "build") dist_dir = File.join(build_dir, "windows", "tabula") if File.exist?(File.join(build_dir, "windows")) FileUtils.rm_rf(File.join(build_dir, "windows")) end cd File.join(tabula_dir) puts "\n======================================================" puts "Building Windows executable..." puts "======================================================\n\n" # exe files REALLY need x.x.x.x otherwise the compile fails. if build_version.start_with?('rev') win_build_version = '0.0.0.0' else win_build_version = build_version while win_build_version.split('.').length < 4 win_build_version = "#{win_build_version}.0" end end cd File.join(File.expand_path(File.dirname(__FILE__)), "launch4j") invoke_ant("-Dfull_version=#{win_build_version}", "-f", "../build.xml", "windows") { |f| f.each { |line| puts line } } puts "\n======================================================" puts "Creating zip file bundle..." puts "======================================================\n\n" Dir.mkdir(dist_dir) app_src = File.join(build_dir, "windows", "tabula.exe") app_dst = File.join(dist_dir, "tabula.exe") FileUtils.mv(app_src, app_dst) jar_src = File.join(build_dir, "tabula.jar") jar_dst = File.join(dist_dir, "tabula.jar") FileUtils.cp(jar_src, jar_dst) readme_src = File.join(build_dir, "dist-README.txt") readme_dst = File.join(dist_dir, "README.txt") FileUtils.cp(readme_src, readme_dst) lic_src = File.join(build_dir, "dist-LICENSE.txt") lic_dst = File.join(dist_dir, "LICENSE.txt") FileUtils.cp(lic_src, lic_dst) authors_src = File.join(tabula_dir, "AUTHORS.md") authors_dst = File.join(dist_dir, "AUTHORS.txt") FileUtils.cp(authors_src, authors_dst) cd File.join(build_dir, "windows") output = File.join(build_dir, "tabula-win-#{build_version}.zip") if File.exists?(output) File.delete(output) end IO.popen("zip -r9 #{output} tabula") { |f| f.each { |line| puts line } } FileUtils.rm_rf(dist_dir) puts "\n======================================================" puts "Zip file saved to #{output}" puts "======================================================\n\n" end task :build_all_platforms => [:create_version_file, :war] do |t| ['jardist', 'macosx', 'windows'].each do |platform| Rake::Task[platform].execute puts end end # delete version file after build ['jardist', 'macosx', 'windows'].each do |t| puts "Deleting version file." Rake::Task[t.intern].enhance { Rake::Task['delete_version_file'.intern].invoke } end ================================================ FILE: build/dist-LICENSE.txt ================================================ tabula and tabula-extractor Copyright (C) 2012-2020 Manuel Aristarán Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /*****************************************************************************/ tabula-extractor -> pdfbox This product includes software (target/pdfbox-app-1.8.0.jar) developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0). /*****************************************************************************/ tabula-extractor -> ext/lsd.c LSD - Line Segment Detector on digital images This code is part of the following publication and was subject to peer review: "LSD: a Line Segment Detector" by Rafael Grompone von Gioi, Jeremie Jakubowicz, Jean-Michel Morel, and Gregory Randall, Image Processing On Line, 2012. DOI:10.5201/ipol.2012.gjmr-lsd http://dx.doi.org/10.5201/ipol.2012.gjmr-lsd Copyright (c) 2007-2011 rafael grompone von gioi This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Additional permission under GNU GPL version 3 section 7 If you modify this Program, or any covered work, by linking or combining it with Tabula (or a modified version of that library), containing parts covered by the terms of "MIT License", the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of Tabula used as well as that of the covered work. ================================================ FILE: build/dist-README.txt ================================================ # Tabula Tabula helps you liberate data tables trapped inside PDF files. * The latest downloads and documentation are always available at: http://tabula.technology/ * Read more about Tabula on OpenNews Source: https://source.opennews.org/en-US/articles/introducing-tabula/ * See the GitHub project for source code, technical info, and more: https://github.com/tabulapdf/tabula * Find a bug? Report it on GitHub: https://github.com/tabulapdf/tabula/issues © 2012-2020 Manuel Aristarán. Available under MIT License. See `AUTHORS.txt` and `LICENSE.txt`. --- ## Using Tabula First, make sure you have a recent copy of Java installed. You can download Java at https://www.java.com/download/ . Tabula requires a Java Runtime Environment compatible with Java 6 or Java 7. ### Windows (tabula-win.zip) Open tabula.exe and a browser should automatically open to http://127.0.0.1:8080/ . If not, open your web browser of choice and visit that URL. ### Mac OS X (tabula-mac.zip) Open the Tabula app and a browser should automatically open to http://127.0.0.1:8080/ . If not, open your web browser of choice and visit that URL. ### JAR file for Linux/Other (tabula-jar.zip) Open a terminal window, and `cd` to inside this `tabula` directory, then run the following command java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -jar tabula.jar Then, manually open your web browser to http://127.0.0.1:8080/ to access the Tabula interface. Tabula binds to port 8080 by default. You can change it with the `warbler.port` option; for example, if you want to use port 9999: java -Dfile.encoding=utf-8 -Xms256M -Xmx1024M -Dwarbler.port=9999 -jar tabula.jar (You can enable the old "automatically open browser" behavior by using the `-Dtabula.openBrowser=true` option.) ================================================ FILE: build.xml ================================================ tabula.jar -Dfile.encoding=utf-8 -Dwarbler.port=8080 -Dtabula.openBrowser=true ================================================ FILE: config.rb ================================================ require 'compass/import-once/activate' # Require any additional compass plugins here. require 'bootstrap-sass' # Set this to the root of your project when deployed: http_path = "webapp/" css_dir = "webapp/static/css" sass_dir = "webapp/static/sass" images_dir = "webapp/static/img" javascripts_dir = "webapp/static/js" # You can select your preferred output style here (can be overridden via the command line): # output_style = :expanded or :nested or :compact or :compressed # To enable relative paths to assets via compass helper functions. Uncomment: # relative_assets = true # To disable debugging comments that display the original location of your selectors. Uncomment: line_comments = false # If you prefer the indented syntax, you might want to regenerate this # project again passing --syntax sass, or you can uncomment this: # preferred_syntax = :sass # and then run: # sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass ================================================ FILE: config.ru ================================================ # encoding: UTF-8 require 'rubygems' require 'bundler' Bundler.require # Disable LittleCMS when running in JVM >= 1.8 # https://pdfbox.apache.org/2.0/getting-started.html jvmajor, jvminor = java.lang.System.getProperty('java.specification.version').split('.') if !jvminor.nil? && jvminor.to_i >= 8 java.lang.System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider") end require_relative './webapp/tabula_settings.rb' require_relative './webapp/tabula_web.rb' potential_root_uri_without_slashes = (defined?($servlet_context) ? $servlet_context.getContextPath : ENV["ROOT_URI"]) if potential_root_uri_without_slashes.nil? || potential_root_uri_without_slashes == '' ROOT_URI = '/' else ROOT_URI = (potential_root_uri_without_slashes[0] == "/" ? '' : '/') + potential_root_uri_without_slashes + (potential_root_uri_without_slashes[-1] == "/" ? '' : '/') end puts "running under #{ROOT_URI} as root URI" map ROOT_URI do run Cuba end if "#{$PROGRAM_NAME}".include?("tabula.jar") # only do this if running as jar or app. (if "rackup", we don't # actually use 8080 by default.) require 'java' # don't do "java_import java.net.URI" -- it conflicts with Ruby URI and # makes Cuba/Rack really really upset. just call "java.*" classes # directly. port = java.lang.Integer.getInteger('warbler.port', 8080) url = "http://127.0.0.1:#{port}" puts "============================================================" puts url puts "============================================================" # Open browser after slight delay. (The server may take a while to actually # serve HTTP, so we are trying to avoid a "Could Not Connect To Server".) uri = java.net.URI.new(url) sleep 0.5 puts "should we open browser?" puts "java.lang.Boolean.getBoolean('tabula.openBrowser'): #{java.lang.Boolean.getBoolean('tabula.openBrowser')}" have_desktop = false if java.lang.Boolean.getBoolean('tabula.openBrowser') puts "java.awt.Desktop.isDesktopSupported: #{java.awt.Desktop.isDesktopSupported}" if java.awt.Desktop.isDesktopSupported begin desktop = java.awt.Desktop.getDesktop() rescue puts "java.awt.Desktop.getDesktop(): no" desktop = nil else puts "java.awt.Desktop.getDesktop(): yes" have_desktop = true end end end # if running as a jar or app, automatically open the user's web browser if # the system supports it. if have_desktop puts "\n======================================================" puts "Launching web browser to #{url}\n\n" begin desktop.browse(uri) rescue puts "Unable to launch your web browser, you will have to" puts "manually open it to the above URL." else puts "If it does not open in 10 seconds, you may manually open" puts "a web browser to the above URL." end puts "When you're done using the Tabula interface, you may" puts "return to this window and press \"Control-C\" to close it." puts "======================================================\n\n" else puts "\n======================================================" puts "Server now listening at: #{url}\n\n" puts "You may now open a web browser to the above URL." puts "When you're done using the Tabula interface, you may" puts "return to this window and press \"Control-C\" to close it." puts "======================================================\n\n" end end ================================================ FILE: docker-compose.yml ================================================ version: '3.3' services: web: &web build: context: . command: "jruby -G -r jbundler -S rackup -p 9292 -o 0.0.0.0 config.ru" volumes: - .:/app - bundle:/usr/local/bundle ports: - 9292:9292 volumes: bundle: ================================================ FILE: lib/tabula_java_wrapper.rb ================================================ java_import org.apache.pdfbox.pdmodel.PDDocument java_import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial class Java::TechnologyTabula::Table attr_accessor :spec_index def to_csv sb = java.lang.StringBuilder.new Java::TechnologyTabulaWriters.CSVWriter.new.write(sb, self) sb.toString end def to_tsv sb = java.lang.StringBuilder.new Java::TechnologyTabulaWriters.TSVWriter.new.write(sb, self) sb.toString end def to_json(*a) sb = java.lang.StringBuilder.new Java::TechnologyTabulaWriters.JSONWriter.new.write(sb, self) sb.toString end end module Tabula def Tabula.extract_tables(pdf_path, specs, options={}) options = { :password => '', :detect_ruling_lines => true, :vertical_rulings => [], :extraction_method => "guess", }.merge(options) specs.each_with_index{|spec, i| spec["spec_index"] = i } specs = specs.group_by { |s| s['page'] } pages = specs.keys.sort extractor = Extraction::ObjectExtractor.new(pdf_path, options[:password]) sea = Java::TechnologyTabulaExtractors.SpreadsheetExtractionAlgorithm.new bea = Java::TechnologyTabulaExtractors.BasicExtractionAlgorithm.new Enumerator.new do |y| extractor.extract(pages.map { |p| p.to_java(:int) }).each do |page| specs[page.getPageNumber].each do |spec| if ["spreadsheet", "original", "basic", "stream", "lattice"].include?(spec['extraction_method']) use_spreadsheet_extraction_method = (spec['extraction_method'] == "spreadsheet" || spec['extraction_method'] == "lattice" ) else # guess use_spreadsheet_extraction_method = sea.isTabular(page) end area = page.getArea(spec['y1'], spec['x1'], spec['y2'], spec['x2']) table_extractor = use_spreadsheet_extraction_method ? sea : bea table_extractor.extract(area).each { |table| table.spec_index = spec["spec_index"]; y.yield table } end end; extractor.close! end end module Extraction def Extraction.openPDF(pdf_filename, password='') raise Errno::ENOENT unless File.exists?(pdf_filename) PDDocument.load(java.io.File.new(pdf_filename)) end class ObjectExtractor < Java::TechnologyTabula.ObjectExtractor alias_method :close!, :close # TODO: the +pages+ constructor argument does not make sense # now that we have +extract_page+ and +extract_pages+ def initialize(pdf_filename, pages=[1], password='', options={}) raise Errno::ENOENT unless File.exists?(pdf_filename) @pdf_filename = pdf_filename @document = Extraction.openPDF(pdf_filename, password) super(@document) end def page_count @document.get_number_of_pages end end class PagesInfoExtractor < ObjectExtractor def pages Enumerator.new do |y| self.extract.each do |page| y.yield({ :width => page.getWidth, :height => page.getHeight, :number => page.getPageNumber, :rotation => page.getRotation.to_i, :hasText => page.hasText }) end end end end end end ================================================ FILE: lib/tabula_job_executor/executor.rb ================================================ require 'java' java_import java.util.concurrent.ThreadPoolExecutor java_import java.util.concurrent.TimeUnit java_import java.util.concurrent.LinkedBlockingQueue require 'jruby/synchronized' require 'securerandom' require 'singleton' module Tabula class NoTextDataException < IOError; end module Background class JobExecutor < java.util.concurrent.ThreadPoolExecutor include Singleton attr_reader :jobs, :futures_jobs def initialize @jobs = Hash.new.extend(JRuby::Synchronized) @futures_jobs = Hash.new.extend(JRuby::Synchronized) super(3, # core pool size 5, # max pool size 300, # keep idle threads 5 minutes TimeUnit::SECONDS, LinkedBlockingQueue.new) at_exit do self.shutdown self.shutdownNow end end def afterExecute(runnable, throwable) super(runnable, throwable) if throwable.nil? and runnable.instance_of?(Java::JavaUtilConcurrent::FutureTask) begin if runnable.isDone runnable.get # 'get' the Future, so it rethrows exceptions if any end rescue Java::JavaUtilConcurrent::ExecutionException => e throwable = e rescue Java::JavaUtilConcurrent::CancellationException => e throwable = e.getCause rescue Java::JavaLang::InterruptedException => e Java::JavaLang::Thread.currentThread.interrupt end if throwable.nil? # task finished OK @futures_jobs[runnable].completed else throwable.printStackTrace(java.lang.System.out) # finished with exception throwable.printStackTrace # XXX TODO better exception logging @futures_jobs[runnable].failed(throwable.toString) end end end def submit(job) @jobs[job.uuid] = job future = super(job) @futures_jobs[future] = job end class << self def get(uuid) instance.jobs[uuid] end def get_by_batch(uuid) instance.jobs.select { |k, j| j.options[:batch] == uuid } end end end class Job include java.util.concurrent.Callable attr_accessor :options, :status attr_reader :uuid def initialize(options={}) @uuid = SecureRandom.uuid @status = {'num' => 0 } self.options = options end def [](k) self.options[k] end def name "#{self.class.name}(#{options.inspect unless options.empty?})" end def call self.status.merge!({ 'status' => 'working', 'started_on' => Time.now }) perform @uuid end def [](k) options[k] end def at(num, total, *messages) self.status.merge!({ 'status' => 'working', 'num' => num, 'total' => total, 'messages' => messages }) end def queued self.status.merge!({ 'status' => 'queued', 'queued_on' => Time.now }) end def warn(*warnings) self.status.merge!({ 'warnings' => warnings }) end def failed(*messages) self.status.merge!({ 'status' => 'failed', 'messages' => messages}) end def completed self.status.merge!({ 'status' => 'completed', 'completed_on' => Time.now }) end def pct_complete case status['status'] when 'completed' then 100 when 'queued' then 0 else t = (status['total'] == 0 || status['total'].nil?) ? 1 : status['total'] (((status['num'] || 0).to_f / t.to_f) * 100).to_i end end def message self.status['messages'] end alias_method :message?, :message def warning self.status['warnings'] end alias_method :warning?, :warning STATUSES = %w{queued working completed failed killed}.freeze STATUSES.each do |status| define_method("#{status}?") do self.status['status'] === status end end class << self def create(options) job = self.new(options) JobExecutor.instance.submit(job) job.uuid end end end end end if __FILE__ == $0 class K < Tabula::Background::Job def perform options[:start].upto(options[:end]) do |i| puts "I'm #{@uuid}: #{i}/#{options[:end]}" at(i, options[:end]) sleep 1 end @uuid end end class J < Tabula::Background::Job def perform options[:start].upto(options[:end]) do |i| puts "I'm #{@uuid}: #{i}/#{options[:end]}" at(i, options[:end]) raise 'caca' sleep 1 end end end j1 = K.create(:start => 1, :end => 20) j2 = K.create(:start => 25, :end => 40) j3 = J.create(:start => 1, :end => 6) Thread.new do loop { puts "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" # puts "STATUS OF J1 IN EXECUTOR: #{Tabula::Background::JobExecutor.get(j1)}" # puts "STATUS OF J2 IN EXECUTOR: #{Tabula::Background::JobExecutor.get(j2)}" # puts "STATUS OF J3 IN EXECUTOR: #{Tabula::Background::JobExecutor.get(j3)}" puts Tabula::Background::JobExecutor.instance.futures_jobs.inspect sleep 1 } end end ================================================ FILE: lib/tabula_job_executor/jobs/detect_tables.rb ================================================ require 'java' require_relative '../executor.rb' class DetectTablesJob < Tabula::Background::Job include Observable def perform filepath = options[:filepath] document_id = options[:id] page_areas_by_page = [] begin extractor = Tabula::Extraction::ObjectExtractor.new(filepath, :all) page_count = extractor.page_count nda = Java::TechnologyTabulaDetectors::NurminenDetectionAlgorithm.new extractor.extract.each do |page| page_index = page.getPageNumber at( (page_count + page_index) / 2, page_count, "auto-detecting tables...") #starting at 50%... changed areas = nda.detect(page) page_areas_by_page << areas.map { |rect| [ rect.getLeft, rect.getTop, rect.getWidth, rect.getHeight ] } end rescue Java::JavaLang::Exception => e warn("Table auto-detect failed. You may need to select tables manually.") ensure extractor.close! end Tabula::Workspace.instance.add_file(page_areas_by_page.to_json, document_id, 'tables.json') at(100, 100, "complete") return nil end end ================================================ FILE: lib/tabula_job_executor/jobs/generate_document_data.rb ================================================ require 'json' require 'jruby/synchronized' require_relative '../executor.rb' class GenerateDocumentDataJob < Tabula::Background::Job include JRuby::Synchronized # args: (:filename, :id) def perform filepath = options[:filepath] original_filename = options[:original_filename] id = options[:id] # return some status to browser at(1, 100, "opening workspace...") doc = { 'original_filename' => original_filename, 'id' => id, 'time' => Time.now.to_i, 'page_count' => '?', 'size' => File.size(filepath), 'thumbnail_sizes' => options[:thumbnail_sizes] } at(5, 100, "analyzing PDF text...") extractor = Tabula::Extraction::PagesInfoExtractor.new(filepath) page_data = extractor.pages.to_a doc['page_count'] = page_data.size unless page_data.any? { |pd| pd[:hasText] } at(0, 100, "No text data found") raise Tabula::NoTextDataException, "no text data found" end Tabula::Workspace.instance.add_document(doc, page_data) at(100, 100, "complete") extractor.close! return nil end end ================================================ FILE: lib/tabula_job_executor/jobs/generate_thumbnails.rb ================================================ require_relative '../executor.rb' require_relative '../../thumbnail_generator.rb' class GenerateThumbnailJob < Tabula::Background::Job # args: (:file, :output_dir, :thumbnail_sizes, :page_index_job_uuid) def perform file_id = options[:file_id] upload_id = self.uuid filepath = options[:filepath] output_dir = options[:output_dir] thumbnail_sizes = options[:thumbnail_sizes] generator = PDFBoxThumbnailGenerator.new(filepath, output_dir, file_id, thumbnail_sizes) generator.add_observer(self, :at) generator.generate_thumbnails! end end ================================================ FILE: lib/tabula_workspace.rb ================================================ require 'jruby/synchronized' require 'singleton' module Tabula class Workspace include JRuby::Synchronized include Singleton STARTING_VALUE = {"pdfs" => [], "templates" => [], "version" => 2} def initialize(data_dir=TabulaSettings.getDataDir) unless File.directory?(data_dir) raise "DOCUMENTS_BASEPATH does not exist or is not a directory." end @data_dir = data_dir @workspace_path = File.join(@data_dir, "pdfs", "workspace.json") @workspace = STARTING_VALUE if !File.exists?(@workspace_path) FileUtils.mkdir_p(File.join(@data_dir, "pdfs")) end end def add_document(document, pages) read_workspace! @workspace["pdfs"].unshift(document) add_file(pages.to_json, document['id'], 'pages.json') flush_workspace! end def delete_document(document_id) read_workspace! @workspace["pdfs"].delete_if { |d| d['id'] == document_id } flush_workspace! FileUtils.rm_rf(get_document_dir(document_id)) end def delete_page(document_id, page_number) # TODO raise "Not Implemented" end def get_document_metadata(document_id) read_workspace! @workspace["pdfs"].find { |d| d['id'] == document_id } end def get_document_pages(document_id) JSON.parse(File.join(get_document_dir(document_id), 'pages.json').read) end def get_document_path(document_id) File.join(get_document_dir(document_id), 'document.pdf') end def list_documents read_workspace! @workspace["pdfs"] end def get_data_dir() @data_dir end def add_file(contents, document_id, filename) p = get_document_dir(document_id) File.open(File.join(p, filename), 'w') do |f| f.write contents end end def move_file(path, document_id, filename) FileUtils.mv(path, File.join(get_document_dir(document_id), filename)) end def copy_file(path, document_id, filename) FileUtils.cp_r(path, File.join(get_document_dir(document_id), filename)) end def list_templates read_workspace! @workspace["templates"] end def get_template_metadata(template_id) read_workspace! @workspace["templates"].find { |d| d['id'] == template_id } end def get_template_body(template_id) puts File.join(get_templates_dir, "#{template_id}.tabula-template.json") open(File.join(get_templates_dir, "#{template_id}.tabula-template.json"), 'r'){|f| f.read } end def add_template(template_metadata) read_workspace! # write template metadata to workspace @workspace["templates"].insert(0,{ "name" => template_metadata["name"].gsub(".tabula-template.json", ""), "selection_count" => template_metadata["selection_count"], "page_count" => template_metadata["page_count"], "time" => template_metadata["time"], "id" => template_metadata["id"] }) # write template file to disk write_template_file(template_metadata) flush_workspace! end def replace_template_metadata(template_id, template_metadata) read_workspace! idx = @workspace["templates"].index{|t| t["id"] == template_id} @workspace["templates"][idx] = template_metadata.select{|k,_| ["name", "selection_count", "page_count", "time", "id"].include?(k) } flush_workspace! end def delete_template(template_id) read_workspace! @workspace["templates"].delete_if { |t| t['id'] == template_id } flush_workspace! File.delete(File.join(get_templates_dir, "#{template_id}.tabula-template.json")) end private def write_template_file(template_metadata) template_name = template_metadata["name"] template_id = Digest::SHA1.hexdigest(Time.now.to_s + template_name) # just SHA1 of time isn't unique with multiple uploads template_filename = template_id + ".tabula-template.json" open(File.join(get_templates_dir, template_filename), 'w'){|f| f << JSON.dump(template_metadata["template"])} end def get_templates_dir p = File.join(@data_dir, 'templates') if !File.directory?(p) FileUtils.mkdir_p(p) end p end def get_document_dir(document_id) p = File.join(@data_dir, 'pdfs', document_id) if !File.directory?(p) FileUtils.mkdir_p(p) end p end def read_workspace! return STARTING_VALUE unless File.exists?(@workspace_path) File.open(@workspace_path) do |f| @workspace = JSON.parse(f.read) end # what if the already-existing workspace is v1? i.e. if it's just an array? # then we'll make it the new kind, seamlessly. if @workspace.is_a? Array @workspace = {"pdfs" => @workspace, "templates" => [], "version" => 2} flush_workspace! end @workspace end def flush_workspace! File.open(@workspace_path, 'w') do |f| f.write @workspace.to_json end end end end ================================================ FILE: lib/thumbnail_generator.rb ================================================ # coding: utf-8 require 'java' require 'observer' java_import javax.imageio.ImageIO java_import java.awt.image.BufferedImage java_import java.awt.Image java_import java.io.ByteArrayOutputStream java_import org.apache.pdfbox.pdmodel.PDDocument java_import org.apache.pdfbox.rendering.PDFRenderer class AbstractThumbnailGenerator include Observable def initialize(pdf_filename, output_directory, sizes=[2048, 560]) raise Errno::ENOENT unless File.directory?(output_directory) raise ArgumentError if sizes.empty? @sizes = sizes.sort.reverse @output_directory = output_directory @pdf_filename = pdf_filename end def generate_thumbnails! raise 'NotImplemented' end end class PDFBoxThumbnailGenerator < AbstractThumbnailGenerator def initialize(pdf_filename, output_directory, document_id, sizes=[2048, 560]) super(pdf_filename, output_directory, sizes) @sizes = sizes @pdf_document = PDDocument.load(java.io.File.new(pdf_filename)) @document_id = document_id end def generate_thumbnails! total_pages = @pdf_document.getNumberOfPages renderer = PDFRenderer.new(@pdf_document) total_pages.times do |pi| image = renderer.renderImageWithDPI(pi, 75) imageWidth = image.getWidth.to_f imageHeight = image.getHeight.to_f @sizes.each do |size| scale = size / imageWidth bi = BufferedImage.new(size, (imageHeight * scale).round, image.getType) bi.getGraphics.drawImage(image.getScaledInstance(size, (imageHeight * scale).round, Image::SCALE_SMOOTH), 0, 0, nil) sio = StringIO.new out = sio.to_outputstream ImageIO.write(bi, 'png', out) Tabula::Workspace.instance.add_file(sio.string, @document_id, "document_#{size}_#{pi+1}.png") end changed notify_observers(pi+1, total_pages, "generating page thumbnails…") end @pdf_document.close end end ## # use /usr/bin/mudraw for faster thumbnail generation # useful for hosted instances of Tabula class MUDrawThumbnailGenerator < AbstractThumbnailGenerator def initialize(pdf_filename, output_directory, sizes=[2048, 560], mudraw='/usr/local/bin/mudraw') super(pdf_filename, output_directory, sizes) @mudraw = mudraw end def generate_thumbnails! @sizes.each_with_index do |size, i| out = File.join(@output_directory, "document_#{size}_%d.png") `#{@mudraw} -o "#{out}" -w #{size} "#{@pdf_filename}"` changed notify_observers(i+1, @sizes.length, "generating page thumbnails...") end end end ================================================ FILE: webapp/index.html ================================================ Tabula
================================================ FILE: webapp/static/css/_bootstrap-variables.scss ================================================ // Override Bootstrap variables here (defaults from bootstrap-sass v3.3.1.0): // When true, asset path helpers are used, otherwise the regular CSS `url()` is used. // When there no function is defined, `fn('')` is parsed as string that equals the right hand side // NB: in Sass 3.3 there is a native function: function-exists(twbs-font-path) // $bootstrap-sass-asset-helper: (twbs-font-path("") != unquote('twbs-font-path("")')) // // Variables // -------------------------------------------------- //== Colors // //## Gray and brand colors for use across Bootstrap. // $gray-base: #000 // $gray-darker: lighten($gray-base, 13.5%) // #222 // $gray-dark: lighten($gray-base, 20%) // #333 // $gray: lighten($gray-base, 33.5%) // #555 // $gray-light: lighten($gray-base, 46.7%) // #777 // $gray-lighter: lighten($gray-base, 93.5%) // #eee // $brand-primary: darken(#428bca, 6.5%) // $brand-success: #5cb85c // $brand-info: #5bc0de // $brand-warning: #f0ad4e // $brand-danger: #d9534f //== Scaffolding // //## Settings for some of the most global styles. //** Background color for ``. // $body-bg: #fff //** Global text color on ``. // $text-color: $gray-dark //** Global textual link color. // $link-color: $brand-primary //** Link hover color set via `darken()` function. // $link-hover-color: darken($link-color, 15%) //** Link hover decoration. // $link-hover-decoration: underline //== Typography // //## Font, line-height, and color for body text, headings, and more. // $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif // $font-family-serif: Georgia, "Times New Roman", Times, serif //** Default monospace fonts for ``, ``, and `
`.
// $font-family-monospace:   Menlo, Monaco, Consolas, "Courier New", monospace
// $font-family-base:        $font-family-sans-serif

// $font-size-base:          14px
// $font-size-large:         ceil(($font-size-base * 1.25)) // ~18px
// $font-size-small:         ceil(($font-size-base * 0.85)) // ~12px

// $font-size-h1:            floor(($font-size-base * 2.6)) // ~36px
// $font-size-h2:            floor(($font-size-base * 2.15)) // ~30px
// $font-size-h3:            ceil(($font-size-base * 1.7)) // ~24px
// $font-size-h4:            ceil(($font-size-base * 1.25)) // ~18px
// $font-size-h5:            $font-size-base
// $font-size-h6:            ceil(($font-size-base * 0.85)) // ~12px

//** Unit-less `line-height` for use in components like buttons.
// $line-height-base:        1.428571429 // 20/14
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
// $line-height-computed:    floor(($font-size-base * $line-height-base)) // ~20px

//** By default, this inherits from the ``.
// $headings-font-family:    inherit
// $headings-font-weight:    500
// $headings-line-height:    1.1
// $headings-color:          inherit

//== Iconography
//
//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.

//** Load fonts from this directory.

// [converter] Asset helpers such as Sprockets and Node.js Mincer do not resolve relative paths
// $icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/")

//** File name for all font files.
// $icon-font-name:          "glyphicons-halflings-regular"
//** Element ID within SVG icon file.
// $icon-font-svg-id:        "glyphicons_halflingsregular"

//== Components
//
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).

// $padding-base-vertical:     6px
// $padding-base-horizontal:   12px

// $padding-large-vertical:    10px
// $padding-large-horizontal:  16px

// $padding-small-vertical:    5px
// $padding-small-horizontal:  10px

// $padding-xs-vertical:       1px
// $padding-xs-horizontal:     5px

// $line-height-large:         1.33
// $line-height-small:         1.5

// $border-radius-base:        4px
// $border-radius-large:       6px
// $border-radius-small:       3px

//** Global color for active items (e.g., navs or dropdowns).
// $component-active-color:    #fff
//** Global background color for active items (e.g., navs or dropdowns).
// $component-active-bg:       $brand-primary

//** Width of the `border` for generating carets that indicator dropdowns.
// $caret-width-base:          4px
//** Carets increase slightly in size for larger components.
// $caret-width-large:         5px

//== Tables
//
//## Customizes the `.table` component with basic values, each used across all table variations.

//** Padding for ``s and ``s.
// $table-cell-padding:            8px
//** Padding for cells in `.table-condensed`.
// $table-condensed-cell-padding:  5px

//** Default background color used for all tables.
// $table-bg:                      transparent
//** Background color used for `.table-striped`.
// $table-bg-accent:               #f9f9f9
//** Background color used for `.table-hover`.
// $table-bg-hover:                #f5f5f5
// $table-bg-active:               $table-bg-hover

//** Border color for table and cell borders.
// $table-border-color:            #ddd

//== Buttons
//
//## For each of Bootstrap's buttons, define text, background and border color.

// $btn-font-weight:                normal

// $btn-default-color:              #333
// $btn-default-bg:                 #fff
// $btn-default-border:             #ccc

// $btn-primary-color:              #fff
// $btn-primary-bg:                 $brand-primary
// $btn-primary-border:             darken($btn-primary-bg, 5%)

// $btn-success-color:              #fff
// $btn-success-bg:                 $brand-success
// $btn-success-border:             darken($btn-success-bg, 5%)

// $btn-info-color:                 #fff
// $btn-info-bg:                    $brand-info
// $btn-info-border:                darken($btn-info-bg, 5%)

// $btn-warning-color:              #fff
// $btn-warning-bg:                 $brand-warning
// $btn-warning-border:             darken($btn-warning-bg, 5%)

// $btn-danger-color:               #fff
// $btn-danger-bg:                  $brand-danger
// $btn-danger-border:              darken($btn-danger-bg, 5%)

// $btn-link-disabled-color:        $gray-light

//== Forms
//
//##

//** `` background color
// $input-bg:                       #fff
//** `` background color
// $input-bg-disabled:              $gray-lighter

//** Text color for ``s
// $input-color:                    $gray
//** `` border color
// $input-border:                   #ccc

// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
//** Default `.form-control` border radius
// $input-border-radius:            $border-radius-base
//** Large `.form-control` border radius
// $input-border-radius-large:      $border-radius-large
//** Small `.form-control` border radius
// $input-border-radius-small:      $border-radius-small

//** Border color for inputs on focus
// $input-border-focus:             #66afe9

//** Placeholder text color
// $input-color-placeholder:        #999

//** Default `.form-control` height
// $input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 2)
//** Large `.form-control` height
// $input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2)
//** Small `.form-control` height
// $input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2)

// $legend-color:                   $gray-dark
// $legend-border-color:            #e5e5e5

//** Background color for textual input addons
// $input-group-addon-bg:           $gray-lighter
//** Border color for textual input addons
// $input-group-addon-border-color: $input-border

//** Disabled cursor for form controls and buttons.
// $cursor-disabled:                not-allowed

//== Dropdowns
//
//## Dropdown menu container and contents.

//** Background for the dropdown menu.
// $dropdown-bg:                    #fff
//** Dropdown menu `border-color`.
// $dropdown-border:                rgba(0,0,0,.15)
//** Dropdown menu `border-color` **for IE8**.
// $dropdown-fallback-border:       #ccc
//** Divider color for between dropdown items.
// $dropdown-divider-bg:            #e5e5e5

//** Dropdown link text color.
// $dropdown-link-color:            $gray-dark
//** Hover color for dropdown links.
// $dropdown-link-hover-color:      darken($gray-dark, 5%)
//** Hover background for dropdown links.
// $dropdown-link-hover-bg:         #f5f5f5

//** Active dropdown menu item text color.
// $dropdown-link-active-color:     $component-active-color
//** Active dropdown menu item background color.
// $dropdown-link-active-bg:        $component-active-bg

//** Disabled dropdown menu item background color.
// $dropdown-link-disabled-color:   $gray-light

//** Text color for headers within dropdown menus.
// $dropdown-header-color:          $gray-light

//** Deprecated `$dropdown-caret-color` as of v3.1.0
// $dropdown-caret-color:           #000

//-- Z-index master list
//
// Warning: Avoid customizing these values. They're used for a bird's eye view
// of components dependent on the z-axis and are designed to all work together.
//
// Note: These variables are not generated into the Customizer.

// $zindex-navbar:            1000
// $zindex-dropdown:          1000
// $zindex-popover:           1060
// $zindex-tooltip:           1070
// $zindex-navbar-fixed:      1030
// $zindex-modal:             1040

//== Media queries breakpoints
//
//## Define the breakpoints at which your layout will change, adapting to different screen sizes.

// Extra small screen / phone
//** Deprecated `$screen-xs` as of v3.0.1
// $screen-xs:                  480px
//** Deprecated `$screen-xs-min` as of v3.2.0
// $screen-xs-min:              $screen-xs
//** Deprecated `$screen-phone` as of v3.0.1
// $screen-phone:               $screen-xs-min

// Small screen / tablet
//** Deprecated `$screen-sm` as of v3.0.1
// $screen-sm:                  768px
// $screen-sm-min:              $screen-sm
//** Deprecated `$screen-tablet` as of v3.0.1
// $screen-tablet:              $screen-sm-min

// Medium screen / desktop
//** Deprecated `$screen-md` as of v3.0.1
// $screen-md:                  992px
// $screen-md-min:              $screen-md
//** Deprecated `$screen-desktop` as of v3.0.1
// $screen-desktop:             $screen-md-min

// Large screen / wide desktop
//** Deprecated `$screen-lg` as of v3.0.1
// $screen-lg:                  1200px
// $screen-lg-min:              $screen-lg
//** Deprecated `$screen-lg-desktop` as of v3.0.1
// $screen-lg-desktop:          $screen-lg-min

// So media queries don't overlap when required, provide a maximum
// $screen-xs-max:              ($screen-sm-min - 1)
// $screen-sm-max:              ($screen-md-min - 1)
// $screen-md-max:              ($screen-lg-min - 1)

//== Grid system
//
//## Define your custom responsive grid.

//** Number of columns in the grid.
// $grid-columns:              12
//** Padding between columns. Gets divided in half for the left and right.
// $grid-gutter-width:         30px
// Navbar collapse
//** Point at which the navbar becomes uncollapsed.
// $grid-float-breakpoint:     $screen-sm-min
//** Point at which the navbar begins collapsing.
// $grid-float-breakpoint-max: ($grid-float-breakpoint - 1)

//== Container sizes
//
//## Define the maximum width of `.container` for different screen sizes.

// Small screen / tablet
// $container-tablet:             (720px + $grid-gutter-width)
//** For `$screen-sm-min` and up.
// $container-sm:                 $container-tablet

// Medium screen / desktop
// $container-desktop:            (940px + $grid-gutter-width)
//** For `$screen-md-min` and up.
// $container-md:                 $container-desktop

// Large screen / wide desktop
// $container-large-desktop:      (1140px + $grid-gutter-width)
//** For `$screen-lg-min` and up.
// $container-lg:                 $container-large-desktop

//== Navbar
//
//##

// Basics of a navbar
// $navbar-height:                    50px
// $navbar-margin-bottom:             $line-height-computed
// $navbar-border-radius:             $border-radius-base
// $navbar-padding-horizontal:        floor(($grid-gutter-width / 2))
// $navbar-padding-vertical:          (($navbar-height - $line-height-computed) / 2)
// $navbar-collapse-max-height:       340px

// $navbar-default-color:             #777
// $navbar-default-bg:                #f8f8f8
// $navbar-default-border:            darken($navbar-default-bg, 6.5%)

// Navbar links
// $navbar-default-link-color:                #777
// $navbar-default-link-hover-color:          #333
// $navbar-default-link-hover-bg:             transparent
// $navbar-default-link-active-color:         #555
// $navbar-default-link-active-bg:            darken($navbar-default-bg, 6.5%)
// $navbar-default-link-disabled-color:       #ccc
// $navbar-default-link-disabled-bg:          transparent

// Navbar brand label
// $navbar-default-brand-color:               $navbar-default-link-color
// $navbar-default-brand-hover-color:         darken($navbar-default-brand-color, 10%)
// $navbar-default-brand-hover-bg:            transparent

// Navbar toggle
// $navbar-default-toggle-hover-bg:           #ddd
// $navbar-default-toggle-icon-bar-bg:        #888
// $navbar-default-toggle-border-color:       #ddd

// Inverted navbar
// Reset inverted navbar basics
// $navbar-inverse-color:                      lighten($gray-light, 15%)
// $navbar-inverse-bg:                         #222
// $navbar-inverse-border:                     darken($navbar-inverse-bg, 10%)

// Inverted navbar links
// $navbar-inverse-link-color:                 lighten($gray-light, 15%)
// $navbar-inverse-link-hover-color:           #fff
// $navbar-inverse-link-hover-bg:              transparent
// $navbar-inverse-link-active-color:          $navbar-inverse-link-hover-color
// $navbar-inverse-link-active-bg:             darken($navbar-inverse-bg, 10%)
// $navbar-inverse-link-disabled-color:        #444
// $navbar-inverse-link-disabled-bg:           transparent

// Inverted navbar brand label
// $navbar-inverse-brand-color:                $navbar-inverse-link-color
// $navbar-inverse-brand-hover-color:          #fff
// $navbar-inverse-brand-hover-bg:             transparent

// Inverted navbar toggle
// $navbar-inverse-toggle-hover-bg:            #333
// $navbar-inverse-toggle-icon-bar-bg:         #fff
// $navbar-inverse-toggle-border-color:        #333

//== Navs
//
//##

//=== Shared nav styles
// $nav-link-padding:                          10px 15px
// $nav-link-hover-bg:                         $gray-lighter

// $nav-disabled-link-color:                   $gray-light
// $nav-disabled-link-hover-color:             $gray-light

//== Tabs
// $nav-tabs-border-color:                     #ddd

// $nav-tabs-link-hover-border-color:          $gray-lighter

// $nav-tabs-active-link-hover-bg:             $body-bg
// $nav-tabs-active-link-hover-color:          $gray
// $nav-tabs-active-link-hover-border-color:   #ddd

// $nav-tabs-justified-link-border-color:            #ddd
// $nav-tabs-justified-active-link-border-color:     $body-bg

//== Pills
// $nav-pills-border-radius:                   $border-radius-base
// $nav-pills-active-link-hover-bg:            $component-active-bg
// $nav-pills-active-link-hover-color:         $component-active-color

//== Pagination
//
//##

// $pagination-color:                     $link-color
// $pagination-bg:                        #fff
// $pagination-border:                    #ddd

// $pagination-hover-color:               $link-hover-color
// $pagination-hover-bg:                  $gray-lighter
// $pagination-hover-border:              #ddd

// $pagination-active-color:              #fff
// $pagination-active-bg:                 $brand-primary
// $pagination-active-border:             $brand-primary

// $pagination-disabled-color:            $gray-light
// $pagination-disabled-bg:               #fff
// $pagination-disabled-border:           #ddd

//== Pager
//
//##

// $pager-bg:                             $pagination-bg
// $pager-border:                         $pagination-border
// $pager-border-radius:                  15px

// $pager-hover-bg:                       $pagination-hover-bg

// $pager-active-bg:                      $pagination-active-bg
// $pager-active-color:                   $pagination-active-color

// $pager-disabled-color:                 $pagination-disabled-color

//== Jumbotron
//
//##

// $jumbotron-padding:              30px
// $jumbotron-color:                inherit
// $jumbotron-bg:                   $gray-lighter
// $jumbotron-heading-color:        inherit
// $jumbotron-font-size:            ceil(($font-size-base * 1.5))

//== Form states and alerts
//
//## Define colors for form feedback states and, by default, alerts.

// $state-success-text:             #3c763d
// $state-success-bg:               #dff0d8
// $state-success-border:           darken(adjust-hue($state-success-bg, -10), 5%)

// $state-info-text:                #31708f
// $state-info-bg:                  #d9edf7
// $state-info-border:              darken(adjust-hue($state-info-bg, -10), 7%)

// $state-warning-text:             #8a6d3b
// $state-warning-bg:               #fcf8e3
// $state-warning-border:           darken(adjust-hue($state-warning-bg, -10), 5%)

// $state-danger-text:              #a94442
// $state-danger-bg:                #f2dede
// $state-danger-border:            darken(adjust-hue($state-danger-bg, -10), 5%)

//== Tooltips
//
//##

//** Tooltip max width
// $tooltip-max-width:           200px
//** Tooltip text color
// $tooltip-color:               #fff
//** Tooltip background color
// $tooltip-bg:                  #000
// $tooltip-opacity:             .9

//** Tooltip arrow width
// $tooltip-arrow-width:         5px
//** Tooltip arrow color
// $tooltip-arrow-color:         $tooltip-bg

//== Popovers
//
//##

//** Popover body background color
// $popover-bg:                          #fff
//** Popover maximum width
// $popover-max-width:                   276px
//** Popover border color
// $popover-border-color:                rgba(0,0,0,.2)
//** Popover fallback border color
// $popover-fallback-border-color:       #ccc

//** Popover title background color
// $popover-title-bg:                    darken($popover-bg, 3%)

//** Popover arrow width
// $popover-arrow-width:                 10px
//** Popover arrow color
// $popover-arrow-color:                 $popover-bg

//** Popover outer arrow width
// $popover-arrow-outer-width:           ($popover-arrow-width + 1)
//** Popover outer arrow color
// $popover-arrow-outer-color:           fade_in($popover-border-color, 0.05)
//** Popover outer arrow fallback color
// $popover-arrow-outer-fallback-color:  darken($popover-fallback-border-color, 20%)

//== Labels
//
//##

//** Default label background color
// $label-default-bg:            $gray-light
//** Primary label background color
// $label-primary-bg:            $brand-primary
//** Success label background color
// $label-success-bg:            $brand-success
//** Info label background color
// $label-info-bg:               $brand-info
//** Warning label background color
// $label-warning-bg:            $brand-warning
//** Danger label background color
// $label-danger-bg:             $brand-danger

//** Default label text color
// $label-color:                 #fff
//** Default text color of a linked label
// $label-link-hover-color:      #fff

//== Modals
//
//##

//** Padding applied to the modal body
// $modal-inner-padding:         15px

//** Padding applied to the modal title
// $modal-title-padding:         15px
//** Modal title line-height
// $modal-title-line-height:     $line-height-base

//** Background color of modal content area
// $modal-content-bg:                             #fff
//** Modal content border color
// $modal-content-border-color:                   rgba(0,0,0,.2)
//** Modal content border color **for IE8**
// $modal-content-fallback-border-color:          #999

//** Modal backdrop background color
// $modal-backdrop-bg:           #000
//** Modal backdrop opacity
// $modal-backdrop-opacity:      .5
//** Modal header border color
// $modal-header-border-color:   #e5e5e5
//** Modal footer border color
// $modal-footer-border-color:   $modal-header-border-color

// $modal-lg:                    900px
// $modal-md:                    600px
// $modal-sm:                    300px

//== Alerts
//
//## Define alert colors, border radius, and padding.

// $alert-padding:               15px
// $alert-border-radius:         $border-radius-base
// $alert-link-font-weight:      bold

// $alert-success-bg:            $state-success-bg
// $alert-success-text:          $state-success-text
// $alert-success-border:        $state-success-border

// $alert-info-bg:               $state-info-bg
// $alert-info-text:             $state-info-text
// $alert-info-border:           $state-info-border

// $alert-warning-bg:            $state-warning-bg
// $alert-warning-text:          $state-warning-text
// $alert-warning-border:        $state-warning-border

// $alert-danger-bg:             $state-danger-bg
// $alert-danger-text:           $state-danger-text
// $alert-danger-border:         $state-danger-border

//== Progress bars
//
//##

//** Background color of the whole progress component
// $progress-bg:                 #f5f5f5
//** Progress bar text color
// $progress-bar-color:          #fff
//** Variable for setting rounded corners on progress bar.
// $progress-border-radius:      $border-radius-base

//** Default progress bar color
// $progress-bar-bg:             $brand-primary
//** Success progress bar color
// $progress-bar-success-bg:     $brand-success
//** Warning progress bar color
// $progress-bar-warning-bg:     $brand-warning
//** Danger progress bar color
// $progress-bar-danger-bg:      $brand-danger
//** Info progress bar color
// $progress-bar-info-bg:        $brand-info

//== List group
//
//##

//** Background color on `.list-group-item`
// $list-group-bg:                 #fff
//** `.list-group-item` border color
// $list-group-border:             #ddd
//** List group border radius
// $list-group-border-radius:      $border-radius-base

//** Background color of single list items on hover
// $list-group-hover-bg:           #f5f5f5
//** Text color of active list items
// $list-group-active-color:       $component-active-color
//** Background color of active list items
// $list-group-active-bg:          $component-active-bg
//** Border color of active list elements
// $list-group-active-border:      $list-group-active-bg
//** Text color for content within active list items
// $list-group-active-text-color:  lighten($list-group-active-bg, 40%)

//** Text color of disabled list items
// $list-group-disabled-color:      $gray-light
//** Background color of disabled list items
// $list-group-disabled-bg:         $gray-lighter
//** Text color for content within disabled list items
// $list-group-disabled-text-color: $list-group-disabled-color

// $list-group-link-color:         #555
// $list-group-link-hover-color:   $list-group-link-color
// $list-group-link-heading-color: #333

//== Panels
//
//##

// $panel-bg:                    #fff
// $panel-body-padding:          15px
// $panel-heading-padding:       10px 15px
// $panel-footer-padding:        $panel-heading-padding
// $panel-border-radius:         $border-radius-base

//** Border color for elements within panels
// $panel-inner-border:          #ddd
// $panel-footer-bg:             #f5f5f5

// $panel-default-text:          $gray-dark
// $panel-default-border:        #ddd
// $panel-default-heading-bg:    #f5f5f5

// $panel-primary-text:          #fff
// $panel-primary-border:        $brand-primary
// $panel-primary-heading-bg:    $brand-primary

// $panel-success-text:          $state-success-text
// $panel-success-border:        $state-success-border
// $panel-success-heading-bg:    $state-success-bg

// $panel-info-text:             $state-info-text
// $panel-info-border:           $state-info-border
// $panel-info-heading-bg:       $state-info-bg

// $panel-warning-text:          $state-warning-text
// $panel-warning-border:        $state-warning-border
// $panel-warning-heading-bg:    $state-warning-bg

// $panel-danger-text:           $state-danger-text
// $panel-danger-border:         $state-danger-border
// $panel-danger-heading-bg:     $state-danger-bg

//== Thumbnails
//
//##

//** Padding around the thumbnail image
// $thumbnail-padding:           4px
//** Thumbnail background color
// $thumbnail-bg:                $body-bg
//** Thumbnail border color
// $thumbnail-border:            #ddd
//** Thumbnail border radius
// $thumbnail-border-radius:     $border-radius-base

//** Custom text color for thumbnail captions
// $thumbnail-caption-color:     $text-color
//** Padding around the thumbnail caption
// $thumbnail-caption-padding:   9px

//== Wells
//
//##

// $well-bg:                     #f5f5f5
// $well-border:                 darken($well-bg, 7%)

//== Badges
//
//##

// $badge-color:                 #fff
//** Linked badge text color on hover
// $badge-link-hover-color:      #fff
// $badge-bg:                    $gray-light

//** Badge text color in active nav link
// $badge-active-color:          $link-color
//** Badge background color in active nav link
// $badge-active-bg:             #fff

// $badge-font-weight:           bold
// $badge-line-height:           1
// $badge-border-radius:         10px

//== Breadcrumbs
//
//##

// $breadcrumb-padding-vertical:   8px
// $breadcrumb-padding-horizontal: 15px
//** Breadcrumb background color
// $breadcrumb-bg:                 #f5f5f5
//** Breadcrumb text color
// $breadcrumb-color:              #ccc
//** Text color of current page in the breadcrumb
// $breadcrumb-active-color:       $gray-light
//** Textual separator for between breadcrumb elements
// $breadcrumb-separator:          "/"

//== Carousel
//
//##

// $carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6)

// $carousel-control-color:                      #fff
// $carousel-control-width:                      15%
// $carousel-control-opacity:                    .5
// $carousel-control-font-size:                  20px

// $carousel-indicator-active-bg:                #fff
// $carousel-indicator-border-color:             #fff

// $carousel-caption-color:                      #fff

//== Close
//
//##

// $close-font-weight:           bold
// $close-color:                 #000
// $close-text-shadow:           0 1px 0 #fff

//== Code
//
//##

// $code-color:                  #c7254e
// $code-bg:                     #f9f2f4

// $kbd-color:                   #fff
// $kbd-bg:                      #333

// $pre-bg:                      #f5f5f5
// $pre-color:                   $gray-dark
// $pre-border-color:            #ccc
// $pre-scrollable-max-height:   340px

//== Type
//
//##

//** Horizontal offset for forms and lists.
// $component-offset-horizontal: 180px
//** Text muted color
// $text-muted:                  $gray-light
//** Abbreviations and acronyms border color
// $abbr-border-color:           $gray-light
//** Headings small color
// $headings-small-color:        $gray-light
//** Blockquote small color
// $blockquote-small-color:      $gray-light
//** Blockquote font size
// $blockquote-font-size:        ($font-size-base * 1.25)
//** Blockquote border color
// $blockquote-border-color:     $gray-lighter
//** Page header border color
// $page-header-border-color:    $gray-lighter
//** Width of horizontal description list titles
// $dl-horizontal-offset:        $component-offset-horizontal
//** Horizontal line color.
// $hr-border:                   $gray-lighter


================================================
FILE: webapp/static/css/selectors.css
================================================
.thumbnail-list li div.selection-show {
  position: absolute;
  border: 1px dashed red;
  display: none;
  pointer-events: none;
}

/* selections */
.repeat-lassos-group {
  position: absolute;
  right: -185px;
  bottom: -35px;
}

/* rectangularSelector.js classes */
.selection-box, .table-region {
  position: absolute;
  border: 1px dashed rgba(255, 87, 0, 0.8);
  background: rgba(255, 87, 0, 0.2);
  box-sizing: border-box;
}
.selection-box:hover, .table-region:hover {
  cursor: pointer;
}

.selection-box {
  z-index: 42;
  width: 0;
  height: 0;
  visibility: hidden;
}

.table-region {
  top: 0;
  left: 0;
  z-index: 21;
}

div.table-region .resize-handle {
  position: absolute;
}

div.table-region .n-border {
  width: calc(100% - 10px);
  top: -5px;
  left: 5px;
  height: 10px;
}

div.table-region .s-border {
  width: calc(100% - 10px);
  bottom: -5px;
  left: 5px;
  height: 10px;
}

div.table-region .w-border {
  height: calc(100% - 10px);
  left: -5px;
  top: 5px;
  width: 10px;
}

div.table-region .e-border {
  height: calc(100% - 10px);
  top: 5px;
  right: -5px;
  width: 10px;
}

div.table-region .nw-border {
  width: 10px;
  height: 10px;
  top: -5px;
  left: -5px;
}

div.table-region .ne-border {
  width: 10px;
  height: 10px;
  top: -5px;
  right: -5px;
}

div.table-region .sw-border {
  width: 10px;
  height: 10px;
  bottom: -5px;
  left: -5px;
}

div.table-region .se-border {
  width: 10px;
  height: 10px;
  bottom: -5px;
  right: -5px;
}

div.table-region .n-border:hover {
  cursor: n-resize;
}

div.table-region .nw-border:hover {
  cursor: nw-resize;
}

div.table-region .ne-border:hover {
  cursor: ne-resize;
}

div.table-region .s-border:hover {
  cursor: s-resize;
}

div.table-region .sw-border:hover {
  cursor: sw-resize;
}

div.table-region .se-border:hover {
  cursor: se-resize;
}

div.table-region .w-border:hover {
  cursor: w-resize;
}

div.table-region .e-border:hover {
  cursor: e-resize;
}

div.table-region button[name=close] {
  font-weight: bold;
  border: 0;
  background-color: transparent;
  padding: 0;
  font-size: 20px;
  position: relative;
  top: -25px;
  left: 100%;
  margin-left: 5px;
}

div.table-region button[name=close]:hover {
  color: red;
}


================================================
FILE: webapp/static/css/styles.css
================================================
@charset "UTF-8";
/*!
 * WARNING: Don't edit this file by hand! Instead, you should be using Compass.
 * Edit the file in webapp/static/sass/styles.scss (or webapp/static/sass/selectors.scss)
 * Then, run `$ compass watch` to automatically re-compile the scss file into "normal" CSS on save.
 * Alternatively, run `$ compass compile` to re-compile the SCSS once.
 */
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
html {
  font-family: sans-serif;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
  display: block;
}

audio,
canvas,
progress,
video {
  display: inline-block;
  vertical-align: baseline;
}

audio:not([controls]) {
  display: none;
  height: 0;
}

[hidden],
template {
  display: none;
}

a {
  background: transparent;
}

a:active,
a:hover {
  outline: 0;
}

abbr[title] {
  border-bottom: 1px dotted;
}

b,
strong {
  font-weight: bold;
}

dfn {
  font-style: italic;
}

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

mark {
  background: #ff0;
  color: #000;
}

small {
  font-size: 80%;
}

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

img {
  border: 0;
}

svg:not(:root) {
  overflow: hidden;
}

figure {
  margin: 1em 40px;
}

hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

pre {
  overflow: auto;
}

code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

button,
input,
optgroup,
select,
textarea {
  color: inherit;
  font: inherit;
  margin: 0;
}

button {
  overflow: visible;
}

button,
select {
  text-transform: none;
}

button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
  -webkit-appearance: button;
  cursor: pointer;
}

button[disabled],
html input[disabled] {
  cursor: default;
}

button::-moz-focus-inner,
input::-moz-focus-inner {
  border: 0;
  padding: 0;
}

input {
  line-height: normal;
}

input[type="checkbox"],
input[type="radio"] {
  box-sizing: border-box;
  padding: 0;
}

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

input[type="search"] {
  -webkit-appearance: textfield;
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box;
  box-sizing: content-box;
}

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

fieldset {
  border: 1px solid #c0c0c0;
  margin: 0 2px;
  padding: 0.35em 0.625em 0.75em;
}

legend {
  border: 0;
  padding: 0;
}

textarea {
  overflow: auto;
}

optgroup {
  font-weight: bold;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

td,
th {
  padding: 0;
}

@media print {
  * {
    text-shadow: none !important;
    color: #000 !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) ")";
  }

  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;
  }

  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }

  h2,
  h3 {
    page-break-after: avoid;
  }

  select {
    background: #fff !important;
  }

  .navbar {
    display: none;
  }

  .table td,
  .table th {
    background-color: #fff !important;
  }

  .btn > .caret,
  .dropup > .btn > .caret {
    border-top-color: #000 !important;
  }

  .label {
    border: 1px solid #000;
  }

  .table {
    border-collapse: collapse !important;
  }

  .table-bordered th,
  .table-bordered td {
    border: 1px solid #ddd !important;
  }
}
@font-face {
  font-family: 'Glyphicons Halflings';
  src: url(webapp/fonts/bootstrap/glyphicons-halflings-regular.eot);
  src: url(webapp/fonts/bootstrap/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"), url(webapp/fonts/bootstrap/glyphicons-halflings-regular.woff) format("woff"), url(webapp/fonts/bootstrap/glyphicons-halflings-regular.ttf) format("truetype"), url(webapp/fonts/bootstrap/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg");
}
.glyphicon {
  position: relative;
  top: 1px;
  display: inline-block;
  font-family: 'Glyphicons Halflings';
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.glyphicon-asterisk:before {
  content: "\2a";
}

.glyphicon-plus:before {
  content: "\2b";
}

.glyphicon-euro:before {
  content: "\20ac";
}

.glyphicon-minus:before {
  content: "\2212";
}

.glyphicon-cloud:before {
  content: "\2601";
}

.glyphicon-envelope:before {
  content: "\2709";
}

.glyphicon-pencil:before {
  content: "\270f";
}

.glyphicon-glass:before {
  content: "\e001";
}

.glyphicon-music:before {
  content: "\e002";
}

.glyphicon-search:before {
  content: "\e003";
}

.glyphicon-heart:before {
  content: "\e005";
}

.glyphicon-star:before {
  content: "\e006";
}

.glyphicon-star-empty:before {
  content: "\e007";
}

.glyphicon-user:before {
  content: "\e008";
}

.glyphicon-film:before {
  content: "\e009";
}

.glyphicon-th-large:before {
  content: "\e010";
}

.glyphicon-th:before {
  content: "\e011";
}

.glyphicon-th-list:before {
  content: "\e012";
}

.glyphicon-ok:before {
  content: "\e013";
}

.glyphicon-remove:before {
  content: "\e014";
}

.glyphicon-zoom-in:before {
  content: "\e015";
}

.glyphicon-zoom-out:before {
  content: "\e016";
}

.glyphicon-off:before {
  content: "\e017";
}

.glyphicon-signal:before {
  content: "\e018";
}

.glyphicon-cog:before {
  content: "\e019";
}

.glyphicon-trash:before {
  content: "\e020";
}

.glyphicon-home:before {
  content: "\e021";
}

.glyphicon-file:before {
  content: "\e022";
}

.glyphicon-time:before {
  content: "\e023";
}

.glyphicon-road:before {
  content: "\e024";
}

.glyphicon-download-alt:before {
  content: "\e025";
}

.glyphicon-download:before {
  content: "\e026";
}

.glyphicon-upload:before {
  content: "\e027";
}

.glyphicon-inbox:before {
  content: "\e028";
}

.glyphicon-play-circle:before {
  content: "\e029";
}

.glyphicon-repeat:before {
  content: "\e030";
}

.glyphicon-refresh:before {
  content: "\e031";
}

.glyphicon-list-alt:before {
  content: "\e032";
}

.glyphicon-lock:before {
  content: "\e033";
}

.glyphicon-flag:before {
  content: "\e034";
}

.glyphicon-headphones:before {
  content: "\e035";
}

.glyphicon-volume-off:before {
  content: "\e036";
}

.glyphicon-volume-down:before {
  content: "\e037";
}

.glyphicon-volume-up:before {
  content: "\e038";
}

.glyphicon-qrcode:before {
  content: "\e039";
}

.glyphicon-barcode:before {
  content: "\e040";
}

.glyphicon-tag:before {
  content: "\e041";
}

.glyphicon-tags:before {
  content: "\e042";
}

.glyphicon-book:before {
  content: "\e043";
}

.glyphicon-bookmark:before {
  content: "\e044";
}

.glyphicon-print:before {
  content: "\e045";
}

.glyphicon-camera:before {
  content: "\e046";
}

.glyphicon-font:before {
  content: "\e047";
}

.glyphicon-bold:before {
  content: "\e048";
}

.glyphicon-italic:before {
  content: "\e049";
}

.glyphicon-text-height:before {
  content: "\e050";
}

.glyphicon-text-width:before {
  content: "\e051";
}

.glyphicon-align-left:before {
  content: "\e052";
}

.glyphicon-align-center:before {
  content: "\e053";
}

.glyphicon-align-right:before {
  content: "\e054";
}

.glyphicon-align-justify:before {
  content: "\e055";
}

.glyphicon-list:before {
  content: "\e056";
}

.glyphicon-indent-left:before {
  content: "\e057";
}

.glyphicon-indent-right:before {
  content: "\e058";
}

.glyphicon-facetime-video:before {
  content: "\e059";
}

.glyphicon-picture:before {
  content: "\e060";
}

.glyphicon-map-marker:before {
  content: "\e062";
}

.glyphicon-adjust:before {
  content: "\e063";
}

.glyphicon-tint:before {
  content: "\e064";
}

.glyphicon-edit:before {
  content: "\e065";
}

.glyphicon-share:before {
  content: "\e066";
}

.glyphicon-check:before {
  content: "\e067";
}

.glyphicon-move:before {
  content: "\e068";
}

.glyphicon-step-backward:before {
  content: "\e069";
}

.glyphicon-fast-backward:before {
  content: "\e070";
}

.glyphicon-backward:before {
  content: "\e071";
}

.glyphicon-play:before {
  content: "\e072";
}

.glyphicon-pause:before {
  content: "\e073";
}

.glyphicon-stop:before {
  content: "\e074";
}

.glyphicon-forward:before {
  content: "\e075";
}

.glyphicon-fast-forward:before {
  content: "\e076";
}

.glyphicon-step-forward:before {
  content: "\e077";
}

.glyphicon-eject:before {
  content: "\e078";
}

.glyphicon-chevron-left:before {
  content: "\e079";
}

.glyphicon-chevron-right:before {
  content: "\e080";
}

.glyphicon-plus-sign:before {
  content: "\e081";
}

.glyphicon-minus-sign:before {
  content: "\e082";
}

.glyphicon-remove-sign:before {
  content: "\e083";
}

.glyphicon-ok-sign:before {
  content: "\e084";
}

.glyphicon-question-sign:before {
  content: "\e085";
}

.glyphicon-info-sign:before {
  content: "\e086";
}

.glyphicon-screenshot:before {
  content: "\e087";
}

.glyphicon-remove-circle:before {
  content: "\e088";
}

.glyphicon-ok-circle:before {
  content: "\e089";
}

.glyphicon-ban-circle:before {
  content: "\e090";
}

.glyphicon-arrow-left:before {
  content: "\e091";
}

.glyphicon-arrow-right:before {
  content: "\e092";
}

.glyphicon-arrow-up:before {
  content: "\e093";
}

.glyphicon-arrow-down:before {
  content: "\e094";
}

.glyphicon-share-alt:before {
  content: "\e095";
}

.glyphicon-resize-full:before {
  content: "\e096";
}

.glyphicon-resize-small:before {
  content: "\e097";
}

.glyphicon-exclamation-sign:before {
  content: "\e101";
}

.glyphicon-gift:before {
  content: "\e102";
}

.glyphicon-leaf:before {
  content: "\e103";
}

.glyphicon-fire:before {
  content: "\e104";
}

.glyphicon-eye-open:before {
  content: "\e105";
}

.glyphicon-eye-close:before {
  content: "\e106";
}

.glyphicon-warning-sign:before {
  content: "\e107";
}

.glyphicon-plane:before {
  content: "\e108";
}

.glyphicon-calendar:before {
  content: "\e109";
}

.glyphicon-random:before {
  content: "\e110";
}

.glyphicon-comment:before {
  content: "\e111";
}

.glyphicon-magnet:before {
  content: "\e112";
}

.glyphicon-chevron-up:before {
  content: "\e113";
}

.glyphicon-chevron-down:before {
  content: "\e114";
}

.glyphicon-retweet:before {
  content: "\e115";
}

.glyphicon-shopping-cart:before {
  content: "\e116";
}

.glyphicon-folder-close:before {
  content: "\e117";
}

.glyphicon-folder-open:before {
  content: "\e118";
}

.glyphicon-resize-vertical:before {
  content: "\e119";
}

.glyphicon-resize-horizontal:before {
  content: "\e120";
}

.glyphicon-hdd:before {
  content: "\e121";
}

.glyphicon-bullhorn:before {
  content: "\e122";
}

.glyphicon-bell:before {
  content: "\e123";
}

.glyphicon-certificate:before {
  content: "\e124";
}

.glyphicon-thumbs-up:before {
  content: "\e125";
}

.glyphicon-thumbs-down:before {
  content: "\e126";
}

.glyphicon-hand-right:before {
  content: "\e127";
}

.glyphicon-hand-left:before {
  content: "\e128";
}

.glyphicon-hand-up:before {
  content: "\e129";
}

.glyphicon-hand-down:before {
  content: "\e130";
}

.glyphicon-circle-arrow-right:before {
  content: "\e131";
}

.glyphicon-circle-arrow-left:before {
  content: "\e132";
}

.glyphicon-circle-arrow-up:before {
  content: "\e133";
}

.glyphicon-circle-arrow-down:before {
  content: "\e134";
}

.glyphicon-globe:before {
  content: "\e135";
}

.glyphicon-wrench:before {
  content: "\e136";
}

.glyphicon-tasks:before {
  content: "\e137";
}

.glyphicon-filter:before {
  content: "\e138";
}

.glyphicon-briefcase:before {
  content: "\e139";
}

.glyphicon-fullscreen:before {
  content: "\e140";
}

.glyphicon-dashboard:before {
  content: "\e141";
}

.glyphicon-paperclip:before {
  content: "\e142";
}

.glyphicon-heart-empty:before {
  content: "\e143";
}

.glyphicon-link:before {
  content: "\e144";
}

.glyphicon-phone:before {
  content: "\e145";
}

.glyphicon-pushpin:before {
  content: "\e146";
}

.glyphicon-usd:before {
  content: "\e148";
}

.glyphicon-gbp:before {
  content: "\e149";
}

.glyphicon-sort:before {
  content: "\e150";
}

.glyphicon-sort-by-alphabet:before {
  content: "\e151";
}

.glyphicon-sort-by-alphabet-alt:before {
  content: "\e152";
}

.glyphicon-sort-by-order:before {
  content: "\e153";
}

.glyphicon-sort-by-order-alt:before {
  content: "\e154";
}

.glyphicon-sort-by-attributes:before {
  content: "\e155";
}

.glyphicon-sort-by-attributes-alt:before {
  content: "\e156";
}

.glyphicon-unchecked:before {
  content: "\e157";
}

.glyphicon-expand:before {
  content: "\e158";
}

.glyphicon-collapse-down:before {
  content: "\e159";
}

.glyphicon-collapse-up:before {
  content: "\e160";
}

.glyphicon-log-in:before {
  content: "\e161";
}

.glyphicon-flash:before {
  content: "\e162";
}

.glyphicon-log-out:before {
  content: "\e163";
}

.glyphicon-new-window:before {
  content: "\e164";
}

.glyphicon-record:before {
  content: "\e165";
}

.glyphicon-save:before {
  content: "\e166";
}

.glyphicon-open:before {
  content: "\e167";
}

.glyphicon-saved:before {
  content: "\e168";
}

.glyphicon-import:before {
  content: "\e169";
}

.glyphicon-export:before {
  content: "\e170";
}

.glyphicon-send:before {
  content: "\e171";
}

.glyphicon-floppy-disk:before {
  content: "\e172";
}

.glyphicon-floppy-saved:before {
  content: "\e173";
}

.glyphicon-floppy-remove:before {
  content: "\e174";
}

.glyphicon-floppy-save:before {
  content: "\e175";
}

.glyphicon-floppy-open:before {
  content: "\e176";
}

.glyphicon-credit-card:before {
  content: "\e177";
}

.glyphicon-transfer:before {
  content: "\e178";
}

.glyphicon-cutlery:before {
  content: "\e179";
}

.glyphicon-header:before {
  content: "\e180";
}

.glyphicon-compressed:before {
  content: "\e181";
}

.glyphicon-earphone:before {
  content: "\e182";
}

.glyphicon-phone-alt:before {
  content: "\e183";
}

.glyphicon-tower:before {
  content: "\e184";
}

.glyphicon-stats:before {
  content: "\e185";
}

.glyphicon-sd-video:before {
  content: "\e186";
}

.glyphicon-hd-video:before {
  content: "\e187";
}

.glyphicon-subtitles:before {
  content: "\e188";
}

.glyphicon-sound-stereo:before {
  content: "\e189";
}

.glyphicon-sound-dolby:before {
  content: "\e190";
}

.glyphicon-sound-5-1:before {
  content: "\e191";
}

.glyphicon-sound-6-1:before {
  content: "\e192";
}

.glyphicon-sound-7-1:before {
  content: "\e193";
}

.glyphicon-copyright-mark:before {
  content: "\e194";
}

.glyphicon-registration-mark:before {
  content: "\e195";
}

.glyphicon-cloud-download:before {
  content: "\e197";
}

.glyphicon-cloud-upload:before {
  content: "\e198";
}

.glyphicon-tree-conifer:before {
  content: "\e199";
}

.glyphicon-tree-deciduous:before {
  content: "\e200";
}

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

*:before,
*:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

html {
  font-size: 10px;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.428571429;
  color: #333333;
  background-color: #fff;
}

input,
button,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
}

a {
  color: #428bca;
  text-decoration: none;
}
a:hover, a:focus {
  color: #2a6496;
  text-decoration: underline;
}
a:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

figure {
  margin: 0;
}

img {
  vertical-align: middle;
}

.img-responsive {
  display: block;
  width: 100% \9;
  max-width: 100%;
  height: auto;
}

.img-rounded {
  border-radius: 6px;
}

.img-thumbnail {
  padding: 4px;
  line-height: 1.428571429;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  -webkit-transition: all 0.2s ease-in-out;
  -o-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
  display: inline-block;
  width: 100% \9;
  max-width: 100%;
  height: auto;
}

.img-circle {
  border-radius: 50%;
}

hr {
  margin-top: 20px;
  margin-bottom: 20px;
  border: 0;
  border-top: 1px solid #eeeeee;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

.sr-only-focusable:active, .sr-only-focusable:focus {
  position: static;
  width: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  clip: auto;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: inherit;
  font-weight: 500;
  line-height: 1.1;
  color: inherit;
}
h1 small,
h1 .small, h2 small,
h2 .small, h3 small,
h3 .small, h4 small,
h4 .small, h5 small,
h5 .small, h6 small,
h6 .small,
.h1 small,
.h1 .small, .h2 small,
.h2 .small, .h3 small,
.h3 .small, .h4 small,
.h4 .small, .h5 small,
.h5 .small, .h6 small,
.h6 .small {
  font-weight: normal;
  line-height: 1;
  color: #777777;
}

h1, .h1,
h2, .h2,
h3, .h3 {
  margin-top: 20px;
  margin-bottom: 10px;
}
h1 small,
h1 .small, .h1 small,
.h1 .small,
h2 small,
h2 .small, .h2 small,
.h2 .small,
h3 small,
h3 .small, .h3 small,
.h3 .small {
  font-size: 65%;
}

h4, .h4,
h5, .h5,
h6, .h6 {
  margin-top: 10px;
  margin-bottom: 10px;
}
h4 small,
h4 .small, .h4 small,
.h4 .small,
h5 small,
h5 .small, .h5 small,
.h5 .small,
h6 small,
h6 .small, .h6 small,
.h6 .small {
  font-size: 75%;
}

h1, .h1 {
  font-size: 36px;
}

h2, .h2 {
  font-size: 30px;
}

h3, .h3 {
  font-size: 24px;
}

h4, .h4 {
  font-size: 18px;
}

h5, .h5 {
  font-size: 14px;
}

h6, .h6 {
  font-size: 12px;
}

p {
  margin: 0 0 10px;
}

.lead {
  margin-bottom: 20px;
  font-size: 16px;
  font-weight: 300;
  line-height: 1.4;
}
@media (min-width: 768px) {
  .lead {
    font-size: 21px;
  }
}

small,
.small {
  font-size: 85%;
}

cite {
  font-style: normal;
}

mark,
.mark {
  background-color: #fcf8e3;
  padding: .2em;
}

.text-left {
  text-align: left;
}

.text-right {
  text-align: right;
}

.text-center {
  text-align: center;
}

.text-justify {
  text-align: justify;
}

.text-nowrap {
  white-space: nowrap;
}

.text-lowercase {
  text-transform: lowercase;
}

.text-uppercase {
  text-transform: uppercase;
}

.text-capitalize {
  text-transform: capitalize;
}

.text-muted {
  color: #777777;
}

.text-primary {
  color: #428bca;
}

a.text-primary:hover {
  color: #3071a9;
}

.text-success {
  color: #3c763d;
}

a.text-success:hover {
  color: #2b542c;
}

.text-info {
  color: #31708f;
}

a.text-info:hover {
  color: #245269;
}

.text-warning {
  color: #8a6d3b;
}

a.text-warning:hover {
  color: #66512c;
}

.text-danger {
  color: #a94442;
}

a.text-danger:hover {
  color: #843534;
}

.bg-primary {
  color: #fff;
}

.bg-primary {
  background-color: #428bca;
}

a.bg-primary:hover {
  background-color: #3071a9;
}

.bg-success {
  background-color: #dff0d8;
}

a.bg-success:hover {
  background-color: #c1e2b3;
}

.bg-info {
  background-color: #d9edf7;
}

a.bg-info:hover {
  background-color: #afd9ee;
}

.bg-warning {
  background-color: #fcf8e3;
}

a.bg-warning:hover {
  background-color: #f7ecb5;
}

.bg-danger {
  background-color: #f2dede;
}

a.bg-danger:hover {
  background-color: #e4b9b9;
}

.page-header {
  padding-bottom: 9px;
  margin: 40px 0 20px;
  border-bottom: 1px solid #eeeeee;
}

ul,
ol {
  margin-top: 0;
  margin-bottom: 10px;
}
ul ul,
ul ol,
ol ul,
ol ol {
  margin-bottom: 0;
}

.list-unstyled, .list-inline {
  padding-left: 0;
  list-style: none;
}

.list-inline {
  margin-left: -5px;
}
.list-inline > li {
  display: inline-block;
  padding-left: 5px;
  padding-right: 5px;
}

dl {
  margin-top: 0;
  margin-bottom: 20px;
}

dt,
dd {
  line-height: 1.428571429;
}

dt {
  font-weight: bold;
}

dd {
  margin-left: 0;
}

.dl-horizontal dd:before, .dl-horizontal dd:after {
  content: " ";
  display: table;
}
.dl-horizontal dd:after {
  clear: both;
}
@media (min-width: 768px) {
  .dl-horizontal dt {
    float: left;
    width: 160px;
    clear: left;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .dl-horizontal dd {
    margin-left: 180px;
  }
}

abbr[title],
abbr[data-original-title] {
  cursor: help;
  border-bottom: 1px dotted #777777;
}

.initialism {
  font-size: 90%;
  text-transform: uppercase;
}

blockquote {
  padding: 10px 20px;
  margin: 0 0 20px;
  font-size: 17.5px;
  border-left: 5px solid #eeeeee;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
  margin-bottom: 0;
}
blockquote footer,
blockquote small,
blockquote .small {
  display: block;
  font-size: 80%;
  line-height: 1.428571429;
  color: #777777;
}
blockquote footer:before,
blockquote small:before,
blockquote .small:before {
  content: '\2014 \00A0';
}

.blockquote-reverse,
blockquote.pull-right {
  padding-right: 15px;
  padding-left: 0;
  border-right: 5px solid #eeeeee;
  border-left: 0;
  text-align: right;
}
.blockquote-reverse footer:before,
.blockquote-reverse small:before,
.blockquote-reverse .small:before,
blockquote.pull-right footer:before,
blockquote.pull-right small:before,
blockquote.pull-right .small:before {
  content: '';
}
.blockquote-reverse footer:after,
.blockquote-reverse small:after,
.blockquote-reverse .small:after,
blockquote.pull-right footer:after,
blockquote.pull-right small:after,
blockquote.pull-right .small:after {
  content: '\00A0 \2014';
}

blockquote:before,
blockquote:after {
  content: "";
}

address {
  margin-bottom: 20px;
  font-style: normal;
  line-height: 1.428571429;
}

code,
kbd,
pre,
samp {
  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}

code {
  padding: 2px 4px;
  font-size: 90%;
  color: #c7254e;
  background-color: #f9f2f4;
  border-radius: 4px;
}

kbd {
  padding: 2px 4px;
  font-size: 90%;
  color: #fff;
  background-color: #333;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);
}
kbd kbd {
  padding: 0;
  font-size: 100%;
  box-shadow: none;
}

pre {
  display: block;
  padding: 9.5px;
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.428571429;
  word-break: break-all;
  word-wrap: break-word;
  color: #333333;
  background-color: #f5f5f5;
  border: 1px solid #ccc;
  border-radius: 4px;
}
pre code {
  padding: 0;
  font-size: inherit;
  color: inherit;
  white-space: pre-wrap;
  background-color: transparent;
  border-radius: 0;
}

.pre-scrollable {
  max-height: 340px;
  overflow-y: scroll;
}

.container {
  margin-right: auto;
  margin-left: auto;
  padding-left: 15px;
  padding-right: 15px;
}
.container:before, .container:after {
  content: " ";
  display: table;
}
.container:after {
  clear: both;
}
@media (min-width: 768px) {
  .container {
    width: 750px;
  }
}
@media (min-width: 992px) {
  .container {
    width: 970px;
  }
}
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

.container-fluid {
  margin-right: auto;
  margin-left: auto;
  padding-left: 15px;
  padding-right: 15px;
}
.container-fluid:before, .container-fluid:after {
  content: " ";
  display: table;
}
.container-fluid:after {
  clear: both;
}

.row {
  margin-left: -15px;
  margin-right: -15px;
}
.row:before, .row:after {
  content: " ";
  display: table;
}
.row:after {
  clear: both;
}

.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
  position: relative;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
}

.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
  float: left;
}

.col-xs-1 {
  width: 8.3333333333%;
}

.col-xs-2 {
  width: 16.6666666667%;
}

.col-xs-3 {
  width: 25%;
}

.col-xs-4 {
  width: 33.3333333333%;
}

.col-xs-5 {
  width: 41.6666666667%;
}

.col-xs-6 {
  width: 50%;
}

.col-xs-7 {
  width: 58.3333333333%;
}

.col-xs-8 {
  width: 66.6666666667%;
}

.col-xs-9 {
  width: 75%;
}

.col-xs-10 {
  width: 83.3333333333%;
}

.col-xs-11 {
  width: 91.6666666667%;
}

.col-xs-12 {
  width: 100%;
}

.col-xs-pull-0 {
  right: auto;
}

.col-xs-pull-1 {
  right: 8.3333333333%;
}

.col-xs-pull-2 {
  right: 16.6666666667%;
}

.col-xs-pull-3 {
  right: 25%;
}

.col-xs-pull-4 {
  right: 33.3333333333%;
}

.col-xs-pull-5 {
  right: 41.6666666667%;
}

.col-xs-pull-6 {
  right: 50%;
}

.col-xs-pull-7 {
  right: 58.3333333333%;
}

.col-xs-pull-8 {
  right: 66.6666666667%;
}

.col-xs-pull-9 {
  right: 75%;
}

.col-xs-pull-10 {
  right: 83.3333333333%;
}

.col-xs-pull-11 {
  right: 91.6666666667%;
}

.col-xs-pull-12 {
  right: 100%;
}

.col-xs-push-0 {
  left: auto;
}

.col-xs-push-1 {
  left: 8.3333333333%;
}

.col-xs-push-2 {
  left: 16.6666666667%;
}

.col-xs-push-3 {
  left: 25%;
}

.col-xs-push-4 {
  left: 33.3333333333%;
}

.col-xs-push-5 {
  left: 41.6666666667%;
}

.col-xs-push-6 {
  left: 50%;
}

.col-xs-push-7 {
  left: 58.3333333333%;
}

.col-xs-push-8 {
  left: 66.6666666667%;
}

.col-xs-push-9 {
  left: 75%;
}

.col-xs-push-10 {
  left: 83.3333333333%;
}

.col-xs-push-11 {
  left: 91.6666666667%;
}

.col-xs-push-12 {
  left: 100%;
}

.col-xs-offset-0 {
  margin-left: 0%;
}

.col-xs-offset-1 {
  margin-left: 8.3333333333%;
}

.col-xs-offset-2 {
  margin-left: 16.6666666667%;
}

.col-xs-offset-3 {
  margin-left: 25%;
}

.col-xs-offset-4 {
  margin-left: 33.3333333333%;
}

.col-xs-offset-5 {
  margin-left: 41.6666666667%;
}

.col-xs-offset-6 {
  margin-left: 50%;
}

.col-xs-offset-7 {
  margin-left: 58.3333333333%;
}

.col-xs-offset-8 {
  margin-left: 66.6666666667%;
}

.col-xs-offset-9 {
  margin-left: 75%;
}

.col-xs-offset-10 {
  margin-left: 83.3333333333%;
}

.col-xs-offset-11 {
  margin-left: 91.6666666667%;
}

.col-xs-offset-12 {
  margin-left: 100%;
}

@media (min-width: 768px) {
  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
    float: left;
  }

  .col-sm-1 {
    width: 8.3333333333%;
  }

  .col-sm-2 {
    width: 16.6666666667%;
  }

  .col-sm-3 {
    width: 25%;
  }

  .col-sm-4 {
    width: 33.3333333333%;
  }

  .col-sm-5 {
    width: 41.6666666667%;
  }

  .col-sm-6 {
    width: 50%;
  }

  .col-sm-7 {
    width: 58.3333333333%;
  }

  .col-sm-8 {
    width: 66.6666666667%;
  }

  .col-sm-9 {
    width: 75%;
  }

  .col-sm-10 {
    width: 83.3333333333%;
  }

  .col-sm-11 {
    width: 91.6666666667%;
  }

  .col-sm-12 {
    width: 100%;
  }

  .col-sm-pull-0 {
    right: auto;
  }

  .col-sm-pull-1 {
    right: 8.3333333333%;
  }

  .col-sm-pull-2 {
    right: 16.6666666667%;
  }

  .col-sm-pull-3 {
    right: 25%;
  }

  .col-sm-pull-4 {
    right: 33.3333333333%;
  }

  .col-sm-pull-5 {
    right: 41.6666666667%;
  }

  .col-sm-pull-6 {
    right: 50%;
  }

  .col-sm-pull-7 {
    right: 58.3333333333%;
  }

  .col-sm-pull-8 {
    right: 66.6666666667%;
  }

  .col-sm-pull-9 {
    right: 75%;
  }

  .col-sm-pull-10 {
    right: 83.3333333333%;
  }

  .col-sm-pull-11 {
    right: 91.6666666667%;
  }

  .col-sm-pull-12 {
    right: 100%;
  }

  .col-sm-push-0 {
    left: auto;
  }

  .col-sm-push-1 {
    left: 8.3333333333%;
  }

  .col-sm-push-2 {
    left: 16.6666666667%;
  }

  .col-sm-push-3 {
    left: 25%;
  }

  .col-sm-push-4 {
    left: 33.3333333333%;
  }

  .col-sm-push-5 {
    left: 41.6666666667%;
  }

  .col-sm-push-6 {
    left: 50%;
  }

  .col-sm-push-7 {
    left: 58.3333333333%;
  }

  .col-sm-push-8 {
    left: 66.6666666667%;
  }

  .col-sm-push-9 {
    left: 75%;
  }

  .col-sm-push-10 {
    left: 83.3333333333%;
  }

  .col-sm-push-11 {
    left: 91.6666666667%;
  }

  .col-sm-push-12 {
    left: 100%;
  }

  .col-sm-offset-0 {
    margin-left: 0%;
  }

  .col-sm-offset-1 {
    margin-left: 8.3333333333%;
  }

  .col-sm-offset-2 {
    margin-left: 16.6666666667%;
  }

  .col-sm-offset-3 {
    margin-left: 25%;
  }

  .col-sm-offset-4 {
    margin-left: 33.3333333333%;
  }

  .col-sm-offset-5 {
    margin-left: 41.6666666667%;
  }

  .col-sm-offset-6 {
    margin-left: 50%;
  }

  .col-sm-offset-7 {
    margin-left: 58.3333333333%;
  }

  .col-sm-offset-8 {
    margin-left: 66.6666666667%;
  }

  .col-sm-offset-9 {
    margin-left: 75%;
  }

  .col-sm-offset-10 {
    margin-left: 83.3333333333%;
  }

  .col-sm-offset-11 {
    margin-left: 91.6666666667%;
  }

  .col-sm-offset-12 {
    margin-left: 100%;
  }
}
@media (min-width: 992px) {
  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
    float: left;
  }

  .col-md-1 {
    width: 8.3333333333%;
  }

  .col-md-2 {
    width: 16.6666666667%;
  }

  .col-md-3 {
    width: 25%;
  }

  .col-md-4 {
    width: 33.3333333333%;
  }

  .col-md-5 {
    width: 41.6666666667%;
  }

  .col-md-6 {
    width: 50%;
  }

  .col-md-7 {
    width: 58.3333333333%;
  }

  .col-md-8 {
    width: 66.6666666667%;
  }

  .col-md-9 {
    width: 75%;
  }

  .col-md-10 {
    width: 83.3333333333%;
  }

  .col-md-11 {
    width: 91.6666666667%;
  }

  .col-md-12 {
    width: 100%;
  }

  .col-md-pull-0 {
    right: auto;
  }

  .col-md-pull-1 {
    right: 8.3333333333%;
  }

  .col-md-pull-2 {
    right: 16.6666666667%;
  }

  .col-md-pull-3 {
    right: 25%;
  }

  .col-md-pull-4 {
    right: 33.3333333333%;
  }

  .col-md-pull-5 {
    right: 41.6666666667%;
  }

  .col-md-pull-6 {
    right: 50%;
  }

  .col-md-pull-7 {
    right: 58.3333333333%;
  }

  .col-md-pull-8 {
    right: 66.6666666667%;
  }

  .col-md-pull-9 {
    right: 75%;
  }

  .col-md-pull-10 {
    right: 83.3333333333%;
  }

  .col-md-pull-11 {
    right: 91.6666666667%;
  }

  .col-md-pull-12 {
    right: 100%;
  }

  .col-md-push-0 {
    left: auto;
  }

  .col-md-push-1 {
    left: 8.3333333333%;
  }

  .col-md-push-2 {
    left: 16.6666666667%;
  }

  .col-md-push-3 {
    left: 25%;
  }

  .col-md-push-4 {
    left: 33.3333333333%;
  }

  .col-md-push-5 {
    left: 41.6666666667%;
  }

  .col-md-push-6 {
    left: 50%;
  }

  .col-md-push-7 {
    left: 58.3333333333%;
  }

  .col-md-push-8 {
    left: 66.6666666667%;
  }

  .col-md-push-9 {
    left: 75%;
  }

  .col-md-push-10 {
    left: 83.3333333333%;
  }

  .col-md-push-11 {
    left: 91.6666666667%;
  }

  .col-md-push-12 {
    left: 100%;
  }

  .col-md-offset-0 {
    margin-left: 0%;
  }

  .col-md-offset-1 {
    margin-left: 8.3333333333%;
  }

  .col-md-offset-2 {
    margin-left: 16.6666666667%;
  }

  .col-md-offset-3 {
    margin-left: 25%;
  }

  .col-md-offset-4 {
    margin-left: 33.3333333333%;
  }

  .col-md-offset-5 {
    margin-left: 41.6666666667%;
  }

  .col-md-offset-6 {
    margin-left: 50%;
  }

  .col-md-offset-7 {
    margin-left: 58.3333333333%;
  }

  .col-md-offset-8 {
    margin-left: 66.6666666667%;
  }

  .col-md-offset-9 {
    margin-left: 75%;
  }

  .col-md-offset-10 {
    margin-left: 83.3333333333%;
  }

  .col-md-offset-11 {
    margin-left: 91.6666666667%;
  }

  .col-md-offset-12 {
    margin-left: 100%;
  }
}
@media (min-width: 1200px) {
  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
    float: left;
  }

  .col-lg-1 {
    width: 8.3333333333%;
  }

  .col-lg-2 {
    width: 16.6666666667%;
  }

  .col-lg-3 {
    width: 25%;
  }

  .col-lg-4 {
    width: 33.3333333333%;
  }

  .col-lg-5 {
    width: 41.6666666667%;
  }

  .col-lg-6 {
    width: 50%;
  }

  .col-lg-7 {
    width: 58.3333333333%;
  }

  .col-lg-8 {
    width: 66.6666666667%;
  }

  .col-lg-9 {
    width: 75%;
  }

  .col-lg-10 {
    width: 83.3333333333%;
  }

  .col-lg-11 {
    width: 91.6666666667%;
  }

  .col-lg-12 {
    width: 100%;
  }

  .col-lg-pull-0 {
    right: auto;
  }

  .col-lg-pull-1 {
    right: 8.3333333333%;
  }

  .col-lg-pull-2 {
    right: 16.6666666667%;
  }

  .col-lg-pull-3 {
    right: 25%;
  }

  .col-lg-pull-4 {
    right: 33.3333333333%;
  }

  .col-lg-pull-5 {
    right: 41.6666666667%;
  }

  .col-lg-pull-6 {
    right: 50%;
  }

  .col-lg-pull-7 {
    right: 58.3333333333%;
  }

  .col-lg-pull-8 {
    right: 66.6666666667%;
  }

  .col-lg-pull-9 {
    right: 75%;
  }

  .col-lg-pull-10 {
    right: 83.3333333333%;
  }

  .col-lg-pull-11 {
    right: 91.6666666667%;
  }

  .col-lg-pull-12 {
    right: 100%;
  }

  .col-lg-push-0 {
    left: auto;
  }

  .col-lg-push-1 {
    left: 8.3333333333%;
  }

  .col-lg-push-2 {
    left: 16.6666666667%;
  }

  .col-lg-push-3 {
    left: 25%;
  }

  .col-lg-push-4 {
    left: 33.3333333333%;
  }

  .col-lg-push-5 {
    left: 41.6666666667%;
  }

  .col-lg-push-6 {
    left: 50%;
  }

  .col-lg-push-7 {
    left: 58.3333333333%;
  }

  .col-lg-push-8 {
    left: 66.6666666667%;
  }

  .col-lg-push-9 {
    left: 75%;
  }

  .col-lg-push-10 {
    left: 83.3333333333%;
  }

  .col-lg-push-11 {
    left: 91.6666666667%;
  }

  .col-lg-push-12 {
    left: 100%;
  }

  .col-lg-offset-0 {
    margin-left: 0%;
  }

  .col-lg-offset-1 {
    margin-left: 8.3333333333%;
  }

  .col-lg-offset-2 {
    margin-left: 16.6666666667%;
  }

  .col-lg-offset-3 {
    margin-left: 25%;
  }

  .col-lg-offset-4 {
    margin-left: 33.3333333333%;
  }

  .col-lg-offset-5 {
    margin-left: 41.6666666667%;
  }

  .col-lg-offset-6 {
    margin-left: 50%;
  }

  .col-lg-offset-7 {
    margin-left: 58.3333333333%;
  }

  .col-lg-offset-8 {
    margin-left: 66.6666666667%;
  }

  .col-lg-offset-9 {
    margin-left: 75%;
  }

  .col-lg-offset-10 {
    margin-left: 83.3333333333%;
  }

  .col-lg-offset-11 {
    margin-left: 91.6666666667%;
  }

  .col-lg-offset-12 {
    margin-left: 100%;
  }
}
table {
  background-color: transparent;
}

th {
  text-align: left;
}

.table {
  width: 100%;
  max-width: 100%;
  margin-bottom: 20px;
}
.table > thead > tr > th,
.table > thead > tr > td,
.table > tbody > tr > th,
.table > tbody > tr > td,
.table > tfoot > tr > th,
.table > tfoot > tr > td {
  padding: 8px;
  line-height: 1.428571429;
  vertical-align: top;
  border-top: 1px solid #ddd;
}
.table > thead > tr > th {
  vertical-align: bottom;
  border-bottom: 2px solid #ddd;
}
.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 #ddd;
}
.table .table {
  background-color: #fff;
}

.table-condensed > thead > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > th,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > th,
.table-condensed > tfoot > tr > td {
  padding: 5px;
}

.table-bordered {
  border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > th,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > th,
.table-bordered > tfoot > tr > td {
  border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
  border-bottom-width: 2px;
}

.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 col[class*="col-"] {
  position: static;
  float: none;
  display: table-column;
}

table td[class*="col-"],
table th[class*="col-"] {
  position: static;
  float: none;
  display: table-cell;
}

.table > thead > tr > td.active,
.table > thead > tr > th.active, .table > thead > tr.active > td, .table > thead > tr.active > th,
.table > tbody > tr > td.active,
.table > tbody > tr > th.active,
.table > tbody > tr.active > td,
.table > tbody > tr.active > th,
.table > tfoot > tr > td.active,
.table > tfoot > tr > th.active,
.table > tfoot > tr.active > td,
.table > tfoot > tr.active > th {
  background-color: #f5f5f5;
}

.table-hover > tbody > tr > td.active:hover,
.table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th {
  background-color: #e8e8e8;
}

.table > thead > tr > td.success,
.table > thead > tr > th.success, .table > thead > tr.success > td, .table > thead > tr.success > th,
.table > tbody > tr > td.success,
.table > tbody > tr > th.success,
.table > tbody > tr.success > td,
.table > tbody > tr.success > th,
.table > tfoot > tr > td.success,
.table > tfoot > tr > th.success,
.table > tfoot > tr.success > td,
.table > tfoot > tr.success > th {
  background-color: #dff0d8;
}

.table-hover > tbody > tr > td.success:hover,
.table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th {
  background-color: #d0e9c6;
}

.table > thead > tr > td.info,
.table > thead > tr > th.info, .table > thead > tr.info > td, .table > thead > tr.info > th,
.table > tbody > tr > td.info,
.table > tbody > tr > th.info,
.table > tbody > tr.info > td,
.table > tbody > tr.info > th,
.table > tfoot > tr > td.info,
.table > tfoot > tr > th.info,
.table > tfoot > tr.info > td,
.table > tfoot > tr.info > th {
  background-color: #d9edf7;
}

.table-hover > tbody > tr > td.info:hover,
.table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th {
  background-color: #c4e3f3;
}

.table > thead > tr > td.warning,
.table > thead > tr > th.warning, .table > thead > tr.warning > td, .table > thead > tr.warning > th,
.table > tbody > tr > td.warning,
.table > tbody > tr > th.warning,
.table > tbody > tr.warning > td,
.table > tbody > tr.warning > th,
.table > tfoot > tr > td.warning,
.table > tfoot > tr > th.warning,
.table > tfoot > tr.warning > td,
.table > tfoot > tr.warning > th {
  background-color: #fcf8e3;
}

.table-hover > tbody > tr > td.warning:hover,
.table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th {
  background-color: #faf2cc;
}

.table > thead > tr > td.danger,
.table > thead > tr > th.danger, .table > thead > tr.danger > td, .table > thead > tr.danger > th,
.table > tbody > tr > td.danger,
.table > tbody > tr > th.danger,
.table > tbody > tr.danger > td,
.table > tbody > tr.danger > th,
.table > tfoot > tr > td.danger,
.table > tfoot > tr > th.danger,
.table > tfoot > tr.danger > td,
.table > tfoot > tr.danger > th {
  background-color: #f2dede;
}

.table-hover > tbody > tr > td.danger:hover,
.table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th {
  background-color: #ebcccc;
}

@media screen and (max-width: 767px) {
  .table-responsive {
    width: 100%;
    margin-bottom: 15px;
    overflow-y: hidden;
    overflow-x: auto;
    -ms-overflow-style: -ms-autohiding-scrollbar;
    border: 1px solid #ddd;
    -webkit-overflow-scrolling: touch;
  }
  .table-responsive > .table {
    margin-bottom: 0;
  }
  .table-responsive > .table > thead > tr > th,
  .table-responsive > .table > thead > tr > td,
  .table-responsive > .table > tbody > tr > th,
  .table-responsive > .table > tbody > tr > td,
  .table-responsive > .table > tfoot > tr > th,
  .table-responsive > .table > tfoot > tr > td {
    white-space: nowrap;
  }
  .table-responsive > .table-bordered {
    border: 0;
  }
  .table-responsive > .table-bordered > thead > tr > th:first-child,
  .table-responsive > .table-bordered > thead > tr > td:first-child,
  .table-responsive > .table-bordered > tbody > tr > th:first-child,
  .table-responsive > .table-bordered > tbody > tr > td:first-child,
  .table-responsive > .table-bordered > tfoot > tr > th:first-child,
  .table-responsive > .table-bordered > tfoot > tr > td:first-child {
    border-left: 0;
  }
  .table-responsive > .table-bordered > thead > tr > th:last-child,
  .table-responsive > .table-bordered > thead > tr > td:last-child,
  .table-responsive > .table-bordered > tbody > tr > th:last-child,
  .table-responsive > .table-bordered > tbody > tr > td:last-child,
  .table-responsive > .table-bordered > tfoot > tr > th:last-child,
  .table-responsive > .table-bordered > tfoot > tr > td:last-child {
    border-right: 0;
  }
  .table-responsive > .table-bordered > tbody > tr:last-child > th,
  .table-responsive > .table-bordered > tbody > tr:last-child > td,
  .table-responsive > .table-bordered > tfoot > tr:last-child > th,
  .table-responsive > .table-bordered > tfoot > tr:last-child > td {
    border-bottom: 0;
  }
}

fieldset {
  padding: 0;
  margin: 0;
  border: 0;
  min-width: 0;
}

legend {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: 20px;
  font-size: 21px;
  line-height: inherit;
  color: #333333;
  border: 0;
  border-bottom: 1px solid #e5e5e5;
}

label {
  display: inline-block;
  max-width: 100%;
  margin-bottom: 5px;
  font-weight: bold;
}

input[type="search"] {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

input[type="radio"],
input[type="checkbox"] {
  margin: 4px 0 0;
  margin-top: 1px \9;
  line-height: normal;
}

input[type="file"] {
  display: block;
}

input[type="range"] {
  display: block;
  width: 100%;
}

select[multiple],
select[size] {
  height: auto;
}

input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

output {
  display: block;
  padding-top: 7px;
  font-size: 14px;
  line-height: 1.428571429;
  color: #555555;
}

.form-control {
  display: block;
  width: 100%;
  height: 34px;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.428571429;
  color: #555555;
  background-color: #fff;
  background-image: none;
  border: 1px solid #ccc;
  border-radius: 4px;
  -webkit-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-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}
.form-control:focus {
  border-color: #66afe9;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.form-control::-moz-placeholder {
  color: #777777;
  opacity: 1;
}
.form-control:-ms-input-placeholder {
  color: #777777;
}
.form-control::-webkit-input-placeholder {
  color: #777777;
}
.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
  cursor: not-allowed;
  background-color: #eeeeee;
  opacity: 1;
}

textarea.form-control {
  height: auto;
}

input[type="search"] {
  -webkit-appearance: none;
}

input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
  line-height: 34px;
  line-height: 1.428571429 \0;
}
input[type="date"].input-sm, .form-horizontal .form-group-sm input[type="date"].form-control, .input-group-sm > input[type="date"].form-control,
.input-group-sm > input[type="date"].input-group-addon,
.input-group-sm > .input-group-btn > input[type="date"].btn,
input[type="time"].input-sm,
.form-horizontal .form-group-sm input[type="time"].form-control,
.input-group-sm > input[type="time"].form-control,
.input-group-sm > input[type="time"].input-group-addon,
.input-group-sm > .input-group-btn > input[type="time"].btn,
input[type="datetime-local"].input-sm,
.form-horizontal .form-group-sm input[type="datetime-local"].form-control,
.input-group-sm > input[type="datetime-local"].form-control,
.input-group-sm > input[type="datetime-local"].input-group-addon,
.input-group-sm > .input-group-btn > input[type="datetime-local"].btn,
input[type="month"].input-sm,
.form-horizontal .form-group-sm input[type="month"].form-control,
.input-group-sm > input[type="month"].form-control,
.input-group-sm > input[type="month"].input-group-addon,
.input-group-sm > .input-group-btn > input[type="month"].btn {
  line-height: 30px;
}
input[type="date"].input-lg, .form-horizontal .form-group-lg input[type="date"].form-control, .input-group-lg > input[type="date"].form-control,
.input-group-lg > input[type="date"].input-group-addon,
.input-group-lg > .input-group-btn > input[type="date"].btn,
input[type="time"].input-lg,
.form-horizontal .form-group-lg input[type="time"].form-control,
.input-group-lg > input[type="time"].form-control,
.input-group-lg > input[type="time"].input-group-addon,
.input-group-lg > .input-group-btn > input[type="time"].btn,
input[type="datetime-local"].input-lg,
.form-horizontal .form-group-lg input[type="datetime-local"].form-control,
.input-group-lg > input[type="datetime-local"].form-control,
.input-group-lg > input[type="datetime-local"].input-group-addon,
.input-group-lg > .input-group-btn > input[type="datetime-local"].btn,
input[type="month"].input-lg,
.form-horizontal .form-group-lg input[type="month"].form-control,
.input-group-lg > input[type="month"].form-control,
.input-group-lg > input[type="month"].input-group-addon,
.input-group-lg > .input-group-btn > input[type="month"].btn {
  line-height: 46px;
}

.form-group {
  margin-bottom: 15px;
}

.radio,
.checkbox {
  position: relative;
  display: block;
  min-height: 20px;
  margin-top: 10px;
  margin-bottom: 10px;
}
.radio label,
.checkbox label {
  padding-left: 20px;
  margin-bottom: 0;
  font-weight: normal;
  cursor: pointer;
}

.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
  position: absolute;
  margin-left: -20px;
  margin-top: 4px \9;
}

.radio + .radio,
.checkbox + .checkbox {
  margin-top: -5px;
}

.radio-inline,
.checkbox-inline {
  display: inline-block;
  padding-left: 20px;
  margin-bottom: 0;
  vertical-align: middle;
  font-weight: normal;
  cursor: pointer;
}

.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
  margin-top: 0;
  margin-left: 10px;
}

input[type="radio"][disabled], input[type="radio"].disabled, fieldset[disabled] input[type="radio"],
input[type="checkbox"][disabled],
input[type="checkbox"].disabled, fieldset[disabled]
input[type="checkbox"] {
  cursor: not-allowed;
}

.radio-inline.disabled, fieldset[disabled] .radio-inline,
.checkbox-inline.disabled, fieldset[disabled]
.checkbox-inline {
  cursor: not-allowed;
}

.radio.disabled label, fieldset[disabled] .radio label,
.checkbox.disabled label, fieldset[disabled]
.checkbox label {
  cursor: not-allowed;
}

.form-control-static {
  padding-top: 7px;
  padding-bottom: 7px;
  margin-bottom: 0;
}
.form-control-static.input-lg, .form-horizontal .form-group-lg .form-control-static.form-control, .input-group-lg > .form-control-static.form-control,
.input-group-lg > .form-control-static.input-group-addon,
.input-group-lg > .input-group-btn > .form-control-static.btn, .form-control-static.input-sm, .form-horizontal .form-group-sm .form-control-static.form-control, .input-group-sm > .form-control-static.form-control,
.input-group-sm > .form-control-static.input-group-addon,
.input-group-sm > .input-group-btn > .form-control-static.btn {
  padding-left: 0;
  padding-right: 0;
}

.input-sm, .form-horizontal .form-group-sm .form-control, .input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
  height: 30px;
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}

select.input-sm, .form-horizontal .form-group-sm select.form-control, .input-group-sm > select.form-control,
.input-group-sm > select.input-group-addon,
.input-group-sm > .input-group-btn > select.btn {
  height: 30px;
  line-height: 30px;
}

textarea.input-sm, .form-horizontal .form-group-sm textarea.form-control, .input-group-sm > textarea.form-control,
.input-group-sm > textarea.input-group-addon,
.input-group-sm > .input-group-btn > textarea.btn,
select[multiple].input-sm,
.form-horizontal .form-group-sm select[multiple].form-control,
.input-group-sm > select[multiple].form-control,
.input-group-sm > select[multiple].input-group-addon,
.input-group-sm > .input-group-btn > select[multiple].btn {
  height: auto;
}

.input-lg, .form-horizontal .form-group-lg .form-control, .input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
  height: 46px;
  padding: 10px 16px;
  font-size: 18px;
  line-height: 1.33;
  border-radius: 6px;
}

select.input-lg, .form-horizontal .form-group-lg select.form-control, .input-group-lg > select.form-control,
.input-group-lg > select.input-group-addon,
.input-group-lg > .input-group-btn > select.btn {
  height: 46px;
  line-height: 46px;
}

textarea.input-lg, .form-horizontal .form-group-lg textarea.form-control, .input-group-lg > textarea.form-control,
.input-group-lg > textarea.input-group-addon,
.input-group-lg > .input-group-btn > textarea.btn,
select[multiple].input-lg,
.form-horizontal .form-group-lg select[multiple].form-control,
.input-group-lg > select[multiple].form-control,
.input-group-lg > select[multiple].input-group-addon,
.input-group-lg > .input-group-btn > select[multiple].btn {
  height: auto;
}

.has-feedback {
  position: relative;
}
.has-feedback .form-control {
  padding-right: 42.5px;
}

.form-control-feedback {
  position: absolute;
  top: 25px;
  right: 0;
  z-index: 2;
  display: block;
  width: 34px;
  height: 34px;
  line-height: 34px;
  text-align: center;
}

.input-lg + .form-control-feedback, .form-horizontal .form-group-lg .form-control + .form-control-feedback, .input-group-lg > .form-control + .form-control-feedback,
.input-group-lg > .input-group-addon + .form-control-feedback,
.input-group-lg > .input-group-btn > .btn + .form-control-feedback {
  width: 46px;
  height: 46px;
  line-height: 46px;
}

.input-sm + .form-control-feedback, .form-horizontal .form-group-sm .form-control + .form-control-feedback, .input-group-sm > .form-control + .form-control-feedback,
.input-group-sm > .input-group-addon + .form-control-feedback,
.input-group-sm > .input-group-btn > .btn + .form-control-feedback {
  width: 30px;
  height: 30px;
  line-height: 30px;
}

.has-success .help-block,
.has-success .control-label,
.has-success .radio,
.has-success .checkbox,
.has-success .radio-inline,
.has-success .checkbox-inline {
  color: #3c763d;
}
.has-success .form-control {
  border-color: #3c763d;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-success .form-control:focus {
  border-color: #2b542c;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
}
.has-success .input-group-addon {
  color: #3c763d;
  border-color: #3c763d;
  background-color: #dff0d8;
}
.has-success .form-control-feedback {
  color: #3c763d;
}

.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
.has-warning .checkbox,
.has-warning .radio-inline,
.has-warning .checkbox-inline {
  color: #8a6d3b;
}
.has-warning .form-control {
  border-color: #8a6d3b;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-warning .form-control:focus {
  border-color: #66512c;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
}
.has-warning .input-group-addon {
  color: #8a6d3b;
  border-color: #8a6d3b;
  background-color: #fcf8e3;
}
.has-warning .form-control-feedback {
  color: #8a6d3b;
}

.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline {
  color: #a94442;
}
.has-error .form-control {
  border-color: #a94442;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.has-error .form-control:focus {
  border-color: #843534;
  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
}
.has-error .input-group-addon {
  color: #a94442;
  border-color: #a94442;
  background-color: #f2dede;
}
.has-error .form-control-feedback {
  color: #a94442;
}

.has-feedback label.sr-only ~ .form-control-feedback {
  top: 0;
}

.help-block {
  display: block;
  margin-top: 5px;
  margin-bottom: 10px;
  color: #737373;
}

@media (min-width: 768px) {
  .form-inline .form-group, .navbar-form .form-group {
    display: inline-block;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .form-control, .navbar-form .form-control {
    display: inline-block;
    width: auto;
    vertical-align: middle;
  }
  .form-inline .input-group, .navbar-form .input-group {
    display: inline-table;
    vertical-align: middle;
  }
  .form-inline .input-group .input-group-addon, .navbar-form .input-group .input-group-addon,
  .form-inline .input-group .input-group-btn,
  .navbar-form .input-group .input-group-btn,
  .form-inline .input-group .form-control,
  .navbar-form .input-group .form-control {
    width: auto;
  }
  .form-inline .input-group > .form-control, .navbar-form .input-group > .form-control {
    width: 100%;
  }
  .form-inline .control-label, .navbar-form .control-label {
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .radio, .navbar-form .radio,
  .form-inline .checkbox,
  .navbar-form .checkbox {
    display: inline-block;
    margin-top: 0;
    margin-bottom: 0;
    vertical-align: middle;
  }
  .form-inline .radio label, .navbar-form .radio label,
  .form-inline .checkbox label,
  .navbar-form .checkbox label {
    padding-left: 0;
  }
  .form-inline .radio input[type="radio"], .navbar-form .radio input[type="radio"],
  .form-inline .checkbox input[type="checkbox"],
  .navbar-form .checkbox input[type="checkbox"] {
    position: relative;
    margin-left: 0;
  }
  .form-inline .has-feedback .form-control-feedback, .navbar-form .has-feedback .form-control-feedback {
    top: 0;
  }
}

.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 7px;
}
.form-horizontal .radio,
.form-horizontal .checkbox {
  min-height: 27px;
}
.form-horizontal .form-group {
  margin-left: -15px;
  margin-right: -15px;
}
.form-horizontal .form-group:before, .form-horizontal .form-group:after {
  content: " ";
  display: table;
}
.form-horizontal .form-group:after {
  clear: both;
}
@media (min-width: 768px) {
  .form-horizontal .control-label {
    text-align: right;
    margin-bottom: 0;
    padding-top: 7px;
  }
}
.form-horizontal .has-feedback .form-control-feedback {
  top: 0;
  right: 15px;
}
@media (min-width: 768px) {
  .form-horizontal .form-group-lg .control-label {
    padding-top: 14.3px;
  }
}
@media (min-width: 768px) {
  .form-horizontal .form-group-sm .control-label {
    padding-top: 6px;
  }
}

.btn {
  display: inline-block;
  margin-bottom: 0;
  font-weight: normal;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  background-image: none;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 12px;
  font-size: 14px;
  line-height: 1.428571429;
  border-radius: 4px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.btn:focus, .btn:active:focus, .btn.active:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}
.btn:hover, .btn:focus {
  color: #333;
  text-decoration: none;
}
.btn:active, .btn.active {
  outline: 0;
  background-image: none;
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn.disabled, .btn[disabled], fieldset[disabled] .btn {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.65;
  filter: alpha(opacity=65);
  -webkit-box-shadow: none;
  box-shadow: none;
}

.btn-default {
  color: #333;
  background-color: #fff;
  border-color: #ccc;
}
.btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open > .btn-default.dropdown-toggle {
  color: #333;
  background-color: #e6e6e6;
  border-color: #adadad;
}
.btn-default:active, .btn-default.active, .open > .btn-default.dropdown-toggle {
  background-image: none;
}
.btn-default.disabled, .btn-default.disabled:hover, .btn-default.disabled:focus, .btn-default.disabled:active, .btn-default.disabled.active, .btn-default[disabled], .btn-default[disabled]:hover, .btn-default[disabled]:focus, .btn-default[disabled]:active, .btn-default[disabled].active, fieldset[disabled] .btn-default, fieldset[disabled] .btn-default:hover, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default:active, fieldset[disabled] .btn-default.active {
  background-color: #fff;
  border-color: #ccc;
}
.btn-default .badge {
  color: #fff;
  background-color: #333;
}

.btn-primary {
  color: #fff;
  background-color: #428bca;
  border-color: #357ebd;
}
.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle {
  color: #fff;
  background-color: #3071a9;
  border-color: #285e8e;
}
.btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle {
  background-image: none;
}
.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active {
  background-color: #428bca;
  border-color: #357ebd;
}
.btn-primary .badge {
  color: #428bca;
  background-color: #fff;
}

.btn-success {
  color: #fff;
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle {
  color: #fff;
  background-color: #449d44;
  border-color: #398439;
}
.btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle {
  background-image: none;
}
.btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled]:active, .btn-success[disabled].active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active {
  background-color: #5cb85c;
  border-color: #4cae4c;
}
.btn-success .badge {
  color: #5cb85c;
  background-color: #fff;
}

.btn-info {
  color: #fff;
  background-color: #5bc0de;
  border-color: #46b8da;
}
.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle {
  color: #fff;
  background-color: #31b0d5;
  border-color: #269abc;
}
.btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle {
  background-image: none;
}
.btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled]:active, .btn-info[disabled].active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active {
  background-color: #5bc0de;
  border-color: #46b8da;
}
.btn-info .badge {
  color: #5bc0de;
  background-color: #fff;
}

.btn-warning {
  color: #fff;
  background-color: #f0ad4e;
  border-color: #eea236;
}
.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle {
  color: #fff;
  background-color: #ec971f;
  border-color: #d58512;
}
.btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle {
  background-image: none;
}
.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active {
  background-color: #f0ad4e;
  border-color: #eea236;
}
.btn-warning .badge {
  color: #f0ad4e;
  background-color: #fff;
}

.btn-danger {
  color: #fff;
  background-color: #d9534f;
  border-color: #d43f3a;
}
.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle {
  color: #fff;
  background-color: #c9302c;
  border-color: #ac2925;
}
.btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle {
  background-image: none;
}
.btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active {
  background-color: #d9534f;
  border-color: #d43f3a;
}
.btn-danger .badge {
  color: #d9534f;
  background-color: #fff;
}

.btn-link {
  color: #428bca;
  font-weight: normal;
  cursor: pointer;
  border-radius: 0;
}
.btn-link, .btn-link:active, .btn-link[disabled], fieldset[disabled] .btn-link {
  background-color: transparent;
  -webkit-box-shadow: none;
  box-shadow: none;
}
.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active {
  border-color: transparent;
}
.btn-link:hover, .btn-link:focus {
  color: #2a6496;
  text-decoration: underline;
  background-color: transparent;
}
.btn-link[disabled]:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:hover, fieldset[disabled] .btn-link:focus {
  color: #777777;
  text-decoration: none;
}

.btn-lg, .btn-group-lg > .btn {
  padding: 10px 16px;
  font-size: 18px;
  line-height: 1.33;
  border-radius: 6px;
}

.btn-sm, .btn-group-sm > .btn {
  padding: 5px 10px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}

.btn-xs, .btn-group-xs > .btn {
  padding: 1px 5px;
  font-size: 12px;
  line-height: 1.5;
  border-radius: 3px;
}

.btn-block {
  display: block;
  width: 100%;
}

.btn-block + .btn-block {
  margin-top: 5px;
}

input[type="submit"].btn-block,
input[type="reset"].btn-block,
input[type="button"].btn-block {
  width: 100%;
}

.fade {
  opacity: 0;
  -webkit-transition: opacity 0.15s linear;
  -o-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
}
.fade.in {
  opacity: 1;
}

.collapse {
  display: none;
}
.collapse.in {
  display: block;
}

tr.collapse.in {
  display: table-row;
}

tbody.collapse.in {
  display: table-row-group;
}

.collapsing {
  position: relative;
  height: 0;
  overflow: hidden;
  -webkit-transition: height 0.35s ease;
  -o-transition: height 0.35s ease;
  transition: height 0.35s ease;
}

.caret {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  vertical-align: middle;
  border-top: 4px solid;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}

.dropdown {
  position: relative;
}

.dropdown-toggle:focus {
  outline: 0;
}

.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;
  font-size: 14px;
  text-align: left;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 4px;
  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  background-clip: padding-box;
}
.dropdown-menu.pull-right {
  right: 0;
  left: auto;
}
.dropdown-menu .divider {
  height: 1px;
  margin: 9px 0;
  overflow: hidden;
  background-color: #e5e5e5;
}
.dropdown-menu > li > a {
  display: block;
  padding: 3px 20px;
  clear: both;
  font-weight: normal;
  line-height: 1.428571429;
  color: #333333;
  white-space: nowrap;
}

.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus {
  text-decoration: none;
  color: #262626;
  background-color: #f5f5f5;
}

.dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus {
  color: #fff;
  text-decoration: none;
  outline: 0;
  background-color: #428bca;
}

.dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus {
  color: #777777;
}

.dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus {
  text-decoration: none;
  background-color: transparent;
  background-image: none;
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  cursor: not-allowed;
}

.open > .dropdown-menu {
  display: block;
}
.open > a {
  outline: 0;
}

.dropdown-menu-right {
  left: auto;
  right: 0;
}

.dropdown-menu-left {
  left: 0;
  right: auto;
}

.dropdown-header {
  display: block;
  padding: 3px 20px;
  font-size: 12px;
  line-height: 1.428571429;
  color: #777777;
  white-space: nowrap;
}

.dropdown-backdrop {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: 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;
  content: "";
}
.dropup .dropdown-menu,
.navbar-fixed-bottom .dropdown .dropdown-menu {
  top: auto;
  bottom: 100%;
  margin-bottom: 1px;
}

@media (min-width: 768px) {
  .navbar-right .dropdown-menu {
    right: 0;
    left: auto;
  }
  .navbar-right .dropdown-menu-left {
    left: 0;
    right: auto;
  }
}
.btn-group,
.btn-group-vertical {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}
.btn-group > .btn,
.btn-group-vertical > .btn {
  position: relative;
  float: left;
}
.btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,
.btn-group-vertical > .btn:hover,
.btn-group-vertical > .btn:focus,
.btn-group-vertical > .btn:active,
.btn-group-vertical > .btn.active {
  z-index: 2;
}
.btn-group > .btn:focus,
.btn-group-vertical > .btn:focus {
  outline: 0;
}

.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
.btn-group .btn-group + .btn,
.btn-group .btn-group + .btn-group {
  margin-left: -1px;
}

.btn-toolbar {
  margin-left: -5px;
}
.btn-toolbar:before, .btn-toolbar:after {
  content: " ";
  display: table;
}
.btn-toolbar:after {
  clear: both;
}
.btn-toolbar .btn-group,
.btn-toolbar .input-group {
  float: left;
}
.btn-toolbar > .btn,
.btn-toolbar > .btn-group,
.btn-toolbar > .input-group {
  margin-left: 5px;
}

.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
  border-radius: 0;
}

.btn-group > .btn:first-child {
  margin-left: 0;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}

.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}

.btn-group > .btn-group {
  float: left;
}

.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}

.btn-group > .btn-group:first-child > .btn:last-child,
.btn-group > .btn-group:first-child > .dropdown-toggle {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}

.btn-group > .btn-group:last-child > .btn:first-child {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}

.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
  outline: 0;
}

.btn-group > .btn + .dropdown-toggle {
  padding-left: 8px;
  padding-right: 8px;
}

.btn-group > .btn-lg + .dropdown-toggle, .btn-group-lg.btn-group > .btn + .dropdown-toggle {
  padding-left: 12px;
  padding-right: 12px;
}

.btn-group.open .dropdown-toggle {
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}
.btn-group.open .dropdown-toggle.btn-link {
  -webkit-box-shadow: none;
  box-shadow: none;
}

.btn .caret {
  margin-left: 0;
}

.btn-lg .caret, .btn-group-lg > .btn .caret {
  border-width: 5px 5px 0;
  border-bottom-width: 0;
}

.dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret {
  border-width: 0 5px 5px;
}

.btn-group-vertical > .btn,
.btn-group-vertical > .btn-group,
.btn-group-vertical > .btn-group > .btn {
  display: block;
  float: none;
  width: 100%;
  max-width: 100%;
}
.btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after {
  content: " ";
  display: table;
}
.btn-group-vertical > .btn-group:after {
  clear: both;
}
.btn-group-vertical > .btn-group > .btn {
  float: none;
}
.btn-group-vertical > .btn + .btn,
.btn-group-vertical > .btn + .btn-group,
.btn-group-vertical > .btn-group + .btn,
.btn-group-vertical > .btn-group + .btn-group {
  margin-top: -1px;
  margin-left: 0;
}

.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
  border-radius: 0;
}
.btn-group-vertical > .btn:first-child:not(:last-child) {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn:last-child:not(:first-child) {
  border-bottom-left-radius: 4px;
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}

.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
  border-radius: 0;
}

.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}

.btn-group-justified {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
}
.btn-group-justified > .btn,
.btn-group-justified > .btn-group {
  float: none;
  display: table-cell;
  width: 1%;
}
.btn-group-justified > .btn-group .btn {
  width: 100%;
}
.btn-group-justified > .btn-group .dropdown-menu {
  left: auto;
}

[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
  position: absolute;
  z-index: -1;
  opacity: 0;
  filter: alpha(opacity=0);
}

.input-group {
  position: relative;
  display: table;
  border-collapse: separate;
}
.input-group[class*="col-"] {
  float: none;
  padding-left: 0;
  padding-right: 0;
}
.input-group .form-control {
  position: relative;
  z-index: 2;
  float: left;
  width: 100%;
  margin-bottom: 0;
}

.input-group-addon,
.input-group-btn,
.input-group .form-control {
  display: table-cell;
}
.input-group-addon:not(:first-child):not(:last-child),
.input-group-btn:not(:first-child):not(:last-child),
.input-group .form-control:not(:first-child):not(:last-child) {
  border-radius: 0;
}

.input-group-addon,
.input-group-btn {
  width: 1%;
  white-space: nowrap;
  vertical-align: middle;
}

.input-group-addon {
  padding: 6px 12px;
  font-size: 14px;
  font-weight: normal;
  line-height: 1;
  color: #555555;
  text-align: center;
  background-color: #eeeeee;
  border: 1px solid #ccc;
  border-radius: 4px;
}
.input-group-addon.input-sm, .form-horizontal .form-group-sm .input-group-addon.form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .input-group-addon.btn {
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 3px;
}
.input-group-addon.input-lg, .form-horizontal .form-group-lg .input-group-addon.form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .input-group-addon.btn {
  padding: 10px 16px;
  font-size: 18px;
  border-radius: 6px;
}
.input-group-addon input[type="radio"],
.input-group-addon input[type="checkbox"] {
  margin-top: 0;
}

.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
  border-bottom-right-radius: 0;
  border-top-right-radius: 0;
}

.input-group-addon:first-child {
  border-right: 0;
}

.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}

.input-group-addon:last-child {
  border-left: 0;
}

.input-group-btn {
  position: relative;
  font-size: 0;
  white-space: nowrap;
}
.input-group-btn > .btn {
  position: relative;
}
.input-group-btn > .btn + .btn {
  margin-left: -1px;
}
.input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active {
  z-index: 2;
}
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group {
  margin-right: -1px;
}
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group {
  margin-left: -1px;
}

.nav {
  margin-bottom: 0;
  padding-left: 0;
  list-style: none;
}
.nav:before, .nav:after {
  content: " ";
  display: table;
}
.nav:after {
  clear: both;
}
.nav > li {
  position: relative;
  display: block;
}
.nav > li > a {
  position: relative;
  display: block;
  padding: 10px 15px;
}
.nav > li > a:hover, .nav > li > a:focus {
  text-decoration: none;
  background-color: #eeeeee;
}
.nav > li.disabled > a {
  color: #777777;
}
.nav > li.disabled > a:hover, .nav > li.disabled > a:focus {
  color: #777777;
  text-decoration: none;
  background-color: transparent;
  cursor: not-allowed;
}
.nav .open > a, .nav .open > a:hover, .nav .open > a:focus {
  background-color: #eeeeee;
  border-color: #428bca;
}
.nav .nav-divider {
  height: 1px;
  margin: 9px 0;
  overflow: hidden;
  background-color: #e5e5e5;
}
.nav > li > a > img {
  max-width: none;
}

.nav-tabs {
  border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
  float: left;
  margin-bottom: -1px;
}
.nav-tabs > li > a {
  margin-right: 2px;
  line-height: 1.428571429;
  border: 1px solid transparent;
  border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
  border-color: #eeeeee #eeeeee #ddd;
}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
  color: #555555;
  background-color: #fff;
  border: 1px solid #ddd;
  border-bottom-color: transparent;
  cursor: default;
}

.nav-pills > li {
  float: left;
}
.nav-pills > li > a {
  border-radius: 4px;
}
.nav-pills > li + li {
  margin-left: 2px;
}
.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {
  color: #fff;
  background-color: #428bca;
}

.nav-stacked > li {
  float: none;
}
.nav-stacked > li + li {
  margin-top: 2px;
  margin-left: 0;
}

.nav-justified, .nav-tabs.nav-justified {
  width: 100%;
}
.nav-justified > li, .nav-tabs.nav-justified > li {
  float: none;
}
.nav-justified > li > a, .nav-tabs.nav-justified > li > a {
  text-align: center;
  margin-bottom: 5px;
}
.nav-justified > .dropdown .dropdown-menu {
  top: auto;
  left: auto;
}
@media (min-width: 768px) {
  .nav-justified > li, .nav-tabs.nav-justified > li {
    display: table-cell;
    width: 1%;
  }
  .nav-justified > li > a, .nav-tabs.nav-justified > li > a {
    margin-bottom: 0;
  }
}

.nav-tabs-justified, .nav-tabs.nav-justified {
  border-bottom: 0;
}
.nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a {
  margin-right: 0;
  border-radius: 4px;
}
.nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus,
.nav-tabs.nav-justified > .active > a:focus {
  border: 1px solid #ddd;
}
@media (min-width: 768px) {
  .nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a {
    border-bottom: 1px solid #ddd;
    border-radius: 4px 4px 0 0;
  }
  .nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a,
  .nav-tabs-justified > .active > a:hover,
  .nav-tabs.nav-justified > .active > a:hover,
  .nav-tabs-justified > .active > a:focus,
  .nav-tabs.nav-justified > .active > a:focus {
    border-bottom-color: #fff;
  }
}

.tab-content > .tab-pane {
  display: none;
}
.tab-content > .active {
  display: block;
}

.nav-tabs .dropdown-menu {
  margin-top: -1px;
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}

.navbar {
  position: relative;
  min-height: 50px;
  margin-bottom: 20px;
  border: 1px solid transparent;
}
.navbar:before, .navbar:after {
  content: " ";
  display: table;
}
.navbar:after {
  clear: both;
}
@media (min-width: 768px) {
  .navbar {
    border-radius: 4px;
  }
}

.navbar-header:before, .navbar-header:after {
  content: " ";
  display: table;
}
.navbar-header:after {
  clear: both;
}
@media (min-width: 768px) {
  .navbar-header {
    float: left;
  }
}

.navbar-collapse {
  overflow-x: visible;
  padding-right: 15px;
  padding-left: 15px;
  border-top: 1px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
  -webkit-overflow-scrolling: touch;
}
.navbar-collapse:before, .navbar-collapse:after {
  content: " ";
  display: table;
}
.navbar-collapse:after {
  clear: both;
}
.navbar-collapse.in {
  overflow-y: auto;
}
@media (min-width: 768px) {
  .navbar-collapse {
    width: auto;
    border-top: 0;
    box-shadow: none;
  }
  .navbar-collapse.collapse {
    display: block !important;
    height: auto !important;
    padding-bottom: 0;
    overflow: visible !important;
  }
  .navbar-collapse.in {
    overflow-y: visible;
  }
  .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse {
    padding-left: 0;
    padding-right: 0;
  }
}

.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
  max-height: 340px;
}
@media (max-width: 480px) and (orientation: landscape) {
  .navbar-fixed-top .navbar-collapse,
  .navbar-fixed-bottom .navbar-collapse {
    max-height: 200px;
  }
}

.container > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-header,
.container-fluid > .navbar-collapse {
  margin-right: -15px;
  margin-left: -15px;
}
@media (min-width: 768px) {
  .container > .navbar-header,
  .container > .navbar-collapse,
  .container-fluid > .navbar-header,
  .container-fluid > .navbar-collapse {
    margin-right: 0;
    margin-left: 0;
  }
}

.navbar-static-top {
  z-index: 1000;
  border-width: 0 0 1px;
}
@media (min-width: 768px) {
  .navbar-static-top {
    border-radius: 0;
  }
}

.navbar-fixed-top,
.navbar-fixed-bottom {
  position: fixed;
  right: 0;
  left: 0;
  z-index: 1030;
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}
@media (min-width: 768px) {
  .navbar-fixed-top,
  .navbar-fixed-bottom {
    border-radius: 0;
  }
}

.navbar-fixed-top {
  top: 0;
  border-width: 0 0 1px;
}

.navbar-fixed-bottom {
  bottom: 0;
  margin-bottom: 0;
  border-width: 1px 0 0;
}

.navbar-brand {
  float: left;
  padding: 15px 15px;
  font-size: 18px;
  line-height: 20px;
  height: 50px;
}
.navbar-brand:hover, .navbar-brand:focus {
  text-decoration: none;
}
@media (min-width: 768px) {
  .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand {
    margin-left: -15px;
  }
}

.navbar-toggle {
  position: relative;
  float: right;
  margin-right: 15px;
  padding: 9px 10px;
  margin-top: 8px;
  margin-bottom: 8px;
  background-color: transparent;
  background-image: none;
  border: 1px solid transparent;
  border-radius: 4px;
}
.navbar-toggle:focus {
  outline: 0;
}
.navbar-toggle .icon-bar {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
}
.navbar-toggle .icon-bar + .icon-bar {
  margin-top: 4px;
}
@media (min-width: 768px) {
  .navbar-toggle {
    display: none;
  }
}

.navbar-nav {
  margin: 7.5px -15px;
}
.navbar-nav > li > a {
  padding-top: 10px;
  padding-bottom: 10px;
  line-height: 20px;
}
@media (max-width: 767px) {
  .navbar-nav .open .dropdown-menu {
    position: static;
    float: none;
    width: auto;
    margin-top: 0;
    background-color: transparent;
    border: 0;
    box-shadow: none;
  }
  .navbar-nav .open .dropdown-menu > li > a,
  .navbar-nav .open .dropdown-menu .dropdown-header {
    padding: 5px 15px 5px 25px;
  }
  .navbar-nav .open .dropdown-menu > li > a {
    line-height: 20px;
  }
  .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus {
    background-image: none;
  }
}
@media (min-width: 768px) {
  .navbar-nav {
    float: left;
    margin: 0;
  }
  .navbar-nav > li {
    float: left;
  }
  .navbar-nav > li > a {
    padding-top: 15px;
    padding-bottom: 15px;
  }
  .navbar-nav.navbar-right:last-child {
    margin-right: -15px;
  }
}

@media (min-width: 768px) {
  .navbar-left {
    float: left !important;
  }

  .navbar-right {
    float: right !important;
  }
}
.navbar-form {
  margin-left: -15px;
  margin-right: -15px;
  padding: 10px 15px;
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
  margin-top: 8px;
  margin-bottom: 8px;
}
@media (max-width: 767px) {
  .navbar-form .form-group {
    margin-bottom: 5px;
  }
}
@media (min-width: 768px) {
  .navbar-form {
    width: auto;
    border: 0;
    margin-left: 0;
    margin-right: 0;
    padding-top: 0;
    padding-bottom: 0;
    -webkit-box-shadow: none;
    box-shadow: none;
  }
  .navbar-form.navbar-right:last-child {
    margin-right: -15px;
  }
}

.navbar-nav > li > .dropdown-menu {
  margin-top: 0;
  border-top-right-radius: 0;
  border-top-left-radius: 0;
}

.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.navbar-btn {
  margin-top: 8px;
  margin-bottom: 8px;
}
.navbar-btn.btn-sm, .btn-group-sm > .navbar-btn.btn {
  margin-top: 10px;
  margin-bottom: 10px;
}
.navbar-btn.btn-xs, .btn-group-xs > .navbar-btn.btn {
  margin-top: 14px;
  margin-bottom: 14px;
}

.navbar-text {
  margin-top: 15px;
  margin-bottom: 15px;
}
@media (min-width: 768px) {
  .navbar-text {
    float: left;
    margin-left: 15px;
    margin-right: 15px;
  }
  .navbar-text.navbar-right:last-child {
    margin-right: 0;
  }
}

.navbar-default {
  background-color: #f8f8f8;
  border-color: #e7e7e7;
}
.navbar-default .navbar-brand {
  color: #777;
}
.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
  color: #5e5e5e;
  background-color: transparent;
}
.navbar-default .navbar-text {
  color: #777;
}
.navbar-default .navbar-nav > li > a {
  color: #777;
}
.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
  color: #333;
  background-color: transparent;
}
.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
  color: #555;
  background-color: #e7e7e7;
}
.navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus {
  color: #ccc;
  background-color: transparent;
}
.navbar-default .navbar-toggle {
  border-color: #ddd;
}
.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
  background-color: #ddd;
}
.navbar-default .navbar-toggle .icon-bar {
  background-color: #888;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
  border-color: #e7e7e7;
}
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
  background-color: #e7e7e7;
  color: #555;
}
@media (max-width: 767px) {
  .navbar-default .navbar-nav .open .dropdown-menu > li > a {
    color: #777;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
    color: #333;
    background-color: transparent;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
    color: #555;
    background-color: #e7e7e7;
  }
  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {
    color: #ccc;
    background-color: transparent;
  }
}
.navbar-default .navbar-link {
  color: #777;
}
.navbar-default .navbar-link:hover {
  color: #333;
}
.navbar-default .btn-link {
  color: #777;
}
.navbar-default .btn-link:hover, .navbar-default .btn-link:focus {
  color: #333;
}
.navbar-default .btn-link[disabled]:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:hover, fieldset[disabled] .navbar-default .btn-link:focus {
  color: #ccc;
}

.navbar-inverse {
  background-color: #222;
  border-color: #090909;
}
.navbar-inverse .navbar-brand {
  color: #777777;
}
.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus {
  color: #fff;
  background-color: transparent;
}
.navbar-inverse .navbar-text {
  color: #777777;
}
.navbar-inverse .navbar-nav > li > a {
  color: #777777;
}
.navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus {
  color: #fff;
  background-color: transparent;
}
.navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus {
  color: #fff;
  background-color: #090909;
}
.navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus {
  color: #444;
  background-color: transparent;
}
.navbar-inverse .navbar-toggle {
  border-color: #333;
}
.navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus {
  background-color: #333;
}
.navbar-inverse .navbar-toggle .icon-bar {
  background-color: #fff;
}
.navbar-inverse .navbar-collapse,
.navbar-inverse .navbar-form {
  border-color: #101010;
}
.navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus {
  background-color: #090909;
  color: #fff;
}
@media (max-width: 767px) {
  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {
    border-color: #090909;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
    background-color: #090909;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {
    color: #777777;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {
    color: #fff;
    background-color: transparent;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {
    color: #fff;
    background-color: #090909;
  }
  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {
    color: #444;
    background-color: transparent;
  }
}
.navbar-inverse .navbar-link {
  color: #777777;
}
.navbar-inverse .navbar-link:hover {
  color: #fff;
}
.navbar-inverse .btn-link {
  color: #777777;
}
.navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus {
  color: #fff;
}
.navbar-inverse .btn-link[disabled]:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:hover, fieldset[disabled] .navbar-inverse .btn-link:focus {
  color: #444;
}

.breadcrumb {
  padding: 8px 15px;
  margin-bottom: 20px;
  list-style: none;
  background-color: #f5f5f5;
  border-radius: 4px;
}
.breadcrumb > li {
  display: inline-block;
}
.breadcrumb > li + li:before {
  content: "/ ";
  padding: 0 5px;
  color: #ccc;
}
.breadcrumb > .active {
  color: #777777;
}

.pagination {
  display: inline-block;
  padding-left: 0;
  margin: 20px 0;
  border-radius: 4px;
}
.pagination > li {
  display: inline;
}
.pagination > li > a,
.pagination > li > span {
  position: relative;
  float: left;
  padding: 6px 12px;
  line-height: 1.428571429;
  text-decoration: none;
  color: #428bca;
  background-color: #fff;
  border: 1px solid #ddd;
  margin-left: -1px;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
  margin-left: 0;
  border-bottom-left-radius: 4px;
  border-top-left-radius: 4px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
  border-bottom-right-radius: 4px;
  border-top-right-radius: 4px;
}
.pagination > li > a:hover, .pagination > li > a:focus,
.pagination > li > span:hover,
.pagination > li > span:focus {
  color: #2a6496;
  background-color: #eeeeee;
  border-color: #ddd;
}
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus,
.pagination > .active > span,
.pagination > .active > span:hover,
.pagination > .active > span:focus {
  z-index: 2;
  color: #fff;
  background-color: #428bca;
  border-color: #428bca;
  cursor: default;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
  color: #777777;
  background-color: #fff;
  border-color: #ddd;
  cursor: not-allowed;
}

.pagination-lg > li > a,
.pagination-lg > li > span {
  padding: 10px 16px;
  font-size: 18px;
}
.pagination-lg > li:first-child > a,
.pagination-lg > li:first-child > span {
  border-bottom-left-radius: 6px;
  border-top-left-radius: 6px;
}
.pagination-lg > li:last-child > a,
.pagination-lg > li:last-child > span {
  border-bottom-right-radius: 6px;
  border-top-right-radius: 6px;
}

.pagination-sm > li > a,
.pagination-sm > li > span {
  padding: 5px 10px;
  font-size: 12px;
}
.pagination-sm > li:first-child > a,
.pagination-sm > li:first-child > span {
  border-bottom-left-radius: 3px;
  border-top-left-radius: 3px;
}
.pagination-sm > li:last-child > a,
.pagination-sm > li:last-child > span {
  border-bottom-right-radius: 3px;
  border-top-right-radius: 3px;
}

.pager {
  padding-left: 0;
  margin: 20px 0;
  list-style: none;
  text-align: center;
}
.pager:before, .pager:after {
  content: " ";
  display: table;
}
.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;
  border-radius: 15px;
}
.pager li > a:hover,
.pager li > a:focus {
  text-decoration: none;
  background-color: #eeeeee;
}
.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: #777777;
  background-color: #fff;
  cursor: not-allowed;
}

.label {
  display: inline;
  padding: .2em .6em .3em;
  font-size: 75%;
  font-weight: bold;
  line-height: 1;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: .25em;
}
.label:empty {
  display: none;
}
.btn .label {
  position: relative;
  top: -1px;
}

a.label:hover, a.label:focus {
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}

.label-default {
  background-color: #777777;
}
.label-default[href]:hover, .label-default[href]:focus {
  background-color: #5e5e5e;
}

.label-primary {
  background-color: #428bca;
}
.label-primary[href]:hover, .label-primary[href]:focus {
  background-color: #3071a9;
}

.label-success {
  background-color: #5cb85c;
}
.label-success[href]:hover, .label-success[href]:focus {
  background-color: #449d44;
}

.label-info {
  background-color: #5bc0de;
}
.label-info[href]:hover, .label-info[href]:focus {
  background-color: #31b0d5;
}

.label-warning {
  background-color: #f0ad4e;
}
.label-warning[href]:hover, .label-warning[href]:focus {
  background-color: #ec971f;
}

.label-danger {
  background-color: #d9534f;
}
.label-danger[href]:hover, .label-danger[href]:focus {
  background-color: #c9302c;
}

.badge {
  display: inline-block;
  min-width: 10px;
  padding: 3px 7px;
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  line-height: 1;
  vertical-align: baseline;
  white-space: nowrap;
  text-align: center;
  background-color: #777777;
  border-radius: 10px;
}
.badge:empty {
  display: none;
}
.btn .badge {
  position: relative;
  top: -1px;
}
.btn-xs .badge, .btn-group-xs > .btn .badge {
  top: 0;
  padding: 1px 5px;
}
a.list-group-item.active > .badge, .nav-pills > .active > a > .badge {
  color: #428bca;
  background-color: #fff;
}
.nav-pills > li > a > .badge {
  margin-left: 3px;
}

a.badge:hover, a.badge:focus {
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}

.jumbotron {
  padding: 30px;
  margin-bottom: 30px;
  color: inherit;
  background-color: #eeeeee;
}
.jumbotron h1,
.jumbotron .h1 {
  color: inherit;
}
.jumbotron p {
  margin-bottom: 15px;
  font-size: 21px;
  font-weight: 200;
}
.jumbotron > hr {
  border-top-color: #d5d5d5;
}
.container .jumbotron {
  border-radius: 6px;
}
.jumbotron .container {
  max-width: 100%;
}
@media screen and (min-width: 768px) {
  .jumbotron {
    padding-top: 48px;
    padding-bottom: 48px;
  }
  .container .jumbotron {
    padding-left: 60px;
    padding-right: 60px;
  }
  .jumbotron h1,
  .jumbotron .h1 {
    font-size: 63px;
  }
}

.thumbnail {
  display: block;
  padding: 4px;
  margin-bottom: 20px;
  line-height: 1.428571429;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  -webkit-transition: all 0.2s ease-in-out;
  -o-transition: all 0.2s ease-in-out;
  transition: all 0.2s ease-in-out;
}
.thumbnail > img,
.thumbnail a > img {
  display: block;
  width: 100% \9;
  max-width: 100%;
  height: auto;
  margin-left: auto;
  margin-right: auto;
}
.thumbnail .caption {
  padding: 9px;
  color: #333333;
}

a.thumbnail:hover,
a.thumbnail:focus,
a.thumbnail.active {
  border-color: #428bca;
}

.alert {
  padding: 15px;
  margin-bottom: 20px;
  border: 1px solid transparent;
  border-radius: 4px;
}
.alert h4 {
  margin-top: 0;
  color: inherit;
}
.alert .alert-link {
  font-weight: bold;
}
.alert > p,
.alert > ul {
  margin-bottom: 0;
}
.alert > p + p {
  margin-top: 5px;
}

.alert-dismissable,
.alert-dismissible {
  padding-right: 35px;
}
.alert-dismissable .close,
.alert-dismissible .close {
  position: relative;
  top: -2px;
  right: -21px;
  color: inherit;
}

.alert-success {
  background-color: #dff0d8;
  border-color: #d6e9c6;
  color: #3c763d;
}
.alert-success hr {
  border-top-color: #c9e2b3;
}
.alert-success .alert-link {
  color: #2b542c;
}

.alert-info {
  background-color: #d9edf7;
  border-color: #bce8f1;
  color: #31708f;
}
.alert-info hr {
  border-top-color: #a6e1ec;
}
.alert-info .alert-link {
  color: #245269;
}

.alert-warning {
  background-color: #fcf8e3;
  border-color: #faebcc;
  color: #8a6d3b;
}
.alert-warning hr {
  border-top-color: #f7e1b5;
}
.alert-warning .alert-link {
  color: #66512c;
}

.alert-danger {
  background-color: #f2dede;
  border-color: #ebccd1;
  color: #a94442;
}
.alert-danger hr {
  border-top-color: #e4b9c0;
}
.alert-danger .alert-link {
  color: #843534;
}

@-webkit-keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}
@keyframes progress-bar-stripes {
  from {
    background-position: 40px 0;
  }
  to {
    background-position: 0 0;
  }
}
.progress {
  overflow: hidden;
  height: 20px;
  margin-bottom: 20px;
  background-color: #f5f5f5;
  border-radius: 4px;
  -webkit-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;
  line-height: 20px;
  color: #fff;
  text-align: center;
  background-color: #428bca;
  -webkit-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-transition: width 0.6s ease;
  -o-transition: width 0.6s ease;
  transition: width 0.6s ease;
}

.progress-striped .progress-bar,
.progress-bar-striped {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
  background-size: 40px 40px;
}

.progress.active .progress-bar,
.progress-bar.active {
  -webkit-animation: progress-bar-stripes 2s linear infinite;
  -o-animation: progress-bar-stripes 2s linear infinite;
  animation: progress-bar-stripes 2s linear infinite;
}

.progress-bar[aria-valuenow="1"], .progress-bar[aria-valuenow="2"] {
  min-width: 30px;
}
.progress-bar[aria-valuenow="0"] {
  color: #777777;
  min-width: 30px;
  background-color: transparent;
  background-image: none;
  box-shadow: none;
}

.progress-bar-success {
  background-color: #5cb85c;
}
.progress-striped .progress-bar-success {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
}

.progress-bar-info {
  background-color: #5bc0de;
}
.progress-striped .progress-bar-info {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
}

.progress-bar-warning {
  background-color: #f0ad4e;
}
.progress-striped .progress-bar-warning {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
}

.progress-bar-danger {
  background-color: #d9534f;
}
.progress-striped .progress-bar-danger {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
}

.media,
.media-body {
  overflow: hidden;
  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 {
  padding-left: 0;
  list-style: none;
}

.list-group {
  margin-bottom: 20px;
  padding-left: 0;
}

.list-group-item {
  position: relative;
  display: block;
  padding: 10px 15px;
  margin-bottom: -1px;
  background-color: #fff;
  border: 1px solid #ddd;
}
.list-group-item:first-child {
  border-top-right-radius: 4px;
  border-top-left-radius: 4px;
}
.list-group-item:last-child {
  margin-bottom: 0;
  border-bottom-right-radius: 4px;
  border-bottom-left-radius: 4px;
}
.list-group-item > .badge {
  float: right;
}
.list-group-item > .badge + .badge {
  margin-right: 5px;
}

a.list-group-item {
  color: #555;
}
a.list-group-item .list-group-item-heading {
  color: #333;
}
a.list-group-item:hover, a.list-group-item:focus {
  text-decoration: none;
  color: #555;
  background-color: #f5f5f5;
}

.list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus {
  background-color: #eeeeee;
  color: #777777;
}
.list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading {
  color: inherit;
}
.list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text {
  color: #777777;
}
.list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus {
  z-index: 2;
  color: #fff;
  background-color: #428bca;
  border-color: #428bca;
}
.list-group-item.active .list-group-item-heading,
.list-group-item.active .list-group-item-heading > small,
.list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading,
.list-group-item.active:hover .list-group-item-heading > small,
.list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading,
.list-group-item.active:focus .list-group-item-heading > small,
.list-group-item.active:focus .list-group-item-heading > .small {
  color: inherit;
}
.list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text {
  color: #e1edf7;
}

.list-group-item-success {
  color: #3c763d;
  background-color: #dff0d8;
}

a.list-group-item-success {
  color: #3c763d;
}
a.list-group-item-success .list-group-item-heading {
  color: inherit;
}
a.list-group-item-success:hover, a.list-group-item-success:focus {
  color: #3c763d;
  background-color: #d0e9c6;
}
a.list-group-item-success.active, a.list-group-item-success.active:hover, a.list-group-item-success.active:focus {
  color: #fff;
  background-color: #3c763d;
  border-color: #3c763d;
}

.list-group-item-info {
  color: #31708f;
  background-color: #d9edf7;
}

a.list-group-item-info {
  color: #31708f;
}
a.list-group-item-info .list-group-item-heading {
  color: inherit;
}
a.list-group-item-info:hover, a.list-group-item-info:focus {
  color: #31708f;
  background-color: #c4e3f3;
}
a.list-group-item-info.active, a.list-group-item-info.active:hover, a.list-group-item-info.active:focus {
  color: #fff;
  background-color: #31708f;
  border-color: #31708f;
}

.list-group-item-warning {
  color: #8a6d3b;
  background-color: #fcf8e3;
}

a.list-group-item-warning {
  color: #8a6d3b;
}
a.list-group-item-warning .list-group-item-heading {
  color: inherit;
}
a.list-group-item-warning:hover, a.list-group-item-warning:focus {
  color: #8a6d3b;
  background-color: #faf2cc;
}
a.list-group-item-warning.active, a.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus {
  color: #fff;
  background-color: #8a6d3b;
  border-color: #8a6d3b;
}

.list-group-item-danger {
  color: #a94442;
  background-color: #f2dede;
}

a.list-group-item-danger {
  color: #a94442;
}
a.list-group-item-danger .list-group-item-heading {
  color: inherit;
}
a.list-group-item-danger:hover, a.list-group-item-danger:focus {
  color: #a94442;
  background-color: #ebcccc;
}
a.list-group-item-danger.active, a.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus {
  color: #fff;
  background-color: #a94442;
  border-color: #a94442;
}

.list-group-item-heading {
  margin-top: 0;
  margin-bottom: 5px;
}

.list-group-item-text {
  margin-bottom: 0;
  line-height: 1.3;
}

.panel {
  margin-bottom: 20px;
  background-color: #fff;
  border: 1px solid transparent;
  border-radius: 4px;
  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
}

.panel-body {
  padding: 15px;
}
.panel-body:before, .panel-body:after {
  content: " ";
  display: table;
}
.panel-body:after {
  clear: both;
}

.panel-heading {
  padding: 10px 15px;
  border-bottom: 1px solid transparent;
  border-top-right-radius: 3px;
  border-top-left-radius: 3px;
}
.panel-heading > .dropdown .dropdown-toggle {
  color: inherit;
}

.panel-title {
  margin-top: 0;
  margin-bottom: 0;
  font-size: 16px;
  color: inherit;
}
.panel-title > a {
  color: inherit;
}

.panel-footer {
  padding: 10px 15px;
  background-color: #f5f5f5;
  border-top: 1px solid #ddd;
  border-bottom-right-radius: 3px;
  border-bottom-left-radius: 3px;
}

.panel > .list-group {
  margin-bottom: 0;
}
.panel > .list-group .list-group-item {
  border-width: 1px 0;
  border-radius: 0;
}
.panel > .list-group:first-child .list-group-item:first-child {
  border-top: 0;
  border-top-right-radius: 3px;
  border-top-left-radius: 3px;
}
.panel > .list-group:last-child .list-group-item:last-child {
  border-bottom: 0;
  border-bottom-right-radius: 3px;
  border-bottom-left-radius: 3px;
}

.panel-heading + .list-group .list-group-item:first-child {
  border-top-width: 0;
}

.list-group + .panel-footer {
  border-top-width: 0;
}

.panel > .table,
.panel > .table-responsive > .table,
.panel > .panel-collapse > .table {
  margin-bottom: 0;
}
.panel > .table:first-child,
.panel > .table-responsive:first-child > .table:first-child {
  border-top-right-radius: 3px;
  border-top-left-radius: 3px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {
  border-top-left-radius: 3px;
}
.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,
.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {
  border-top-right-radius: 3px;
}
.panel > .table:last-child,
.panel > .table-responsive:last-child > .table:last-child {
  border-bottom-right-radius: 3px;
  border-bottom-left-radius: 3px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {
  border-bottom-left-radius: 3px;
}
.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,
.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {
  border-bottom-right-radius: 3px;
}
.panel > .panel-body + .table,
.panel > .panel-body + .table-responsive {
  border-top: 1px solid #ddd;
}
.panel > .table > tbody:first-child > tr:first-child th,
.panel > .table > tbody:first-child > tr:first-child td {
  border-top: 0;
}
.panel > .table-bordered,
.panel > .table-responsive > .table-bordered {
  border: 0;
}
.panel > .table-bordered > thead > tr > th:first-child,
.panel > .table-bordered > thead > tr > td:first-child,
.panel > .table-bordered > tbody > tr > th:first-child,
.panel > .table-bordered > tbody > tr > td:first-child,
.panel > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-bordered > tfoot > tr > td:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {
  border-left: 0;
}
.panel > .table-bordered > thead > tr > th:last-child,
.panel > .table-bordered > thead > tr > td:last-child,
.panel > .table-bordered > tbody > tr > th:last-child,
.panel > .table-bordered > tbody > tr > td:last-child,
.panel > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-bordered > tfoot > tr > td:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,
.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,
.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {
  border-right: 0;
}
.panel > .table-bordered > thead > tr:first-child > td,
.panel > .table-bordered > thead > tr:first-child > th,
.panel > .table-bordered > tbody > tr:first-child > td,
.panel > .table-bordered > tbody > tr:first-child > th,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,
.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {
  border-bottom: 0;
}
.panel > .table-bordered > tbody > tr:last-child > td,
.panel > .table-bordered > tbody > tr:last-child > th,
.panel > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-bordered > tfoot > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,
.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {
  border-bottom: 0;
}
.panel > .table-responsive {
  border: 0;
  margin-bottom: 0;
}

.panel-group {
  margin-bottom: 20px;
}
.panel-group .panel {
  margin-bottom: 0;
  border-radius: 4px;
}
.panel-group .panel + .panel {
  margin-top: 5px;
}
.panel-group .panel-heading {
  border-bottom: 0;
}
.panel-group .panel-heading + .panel-collapse > .panel-body {
  border-top: 1px solid #ddd;
}
.panel-group .panel-footer {
  border-top: 0;
}
.panel-group .panel-footer + .panel-collapse .panel-body {
  border-bottom: 1px solid #ddd;
}

.panel-default {
  border-color: #ddd;
}
.panel-default > .panel-heading {
  color: #333333;
  background-color: #f5f5f5;
  border-color: #ddd;
}
.panel-default > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #ddd;
}
.panel-default > .panel-heading .badge {
  color: #f5f5f5;
  background-color: #333333;
}
.panel-default > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #ddd;
}

.panel-primary {
  border-color: #428bca;
}
.panel-primary > .panel-heading {
  color: #fff;
  background-color: #428bca;
  border-color: #428bca;
}
.panel-primary > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #428bca;
}
.panel-primary > .panel-heading .badge {
  color: #428bca;
  background-color: #fff;
}
.panel-primary > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #428bca;
}

.panel-success {
  border-color: #d6e9c6;
}
.panel-success > .panel-heading {
  color: #3c763d;
  background-color: #dff0d8;
  border-color: #d6e9c6;
}
.panel-success > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #d6e9c6;
}
.panel-success > .panel-heading .badge {
  color: #dff0d8;
  background-color: #3c763d;
}
.panel-success > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #d6e9c6;
}

.panel-info {
  border-color: #bce8f1;
}
.panel-info > .panel-heading {
  color: #31708f;
  background-color: #d9edf7;
  border-color: #bce8f1;
}
.panel-info > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #bce8f1;
}
.panel-info > .panel-heading .badge {
  color: #d9edf7;
  background-color: #31708f;
}
.panel-info > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #bce8f1;
}

.panel-warning {
  border-color: #faebcc;
}
.panel-warning > .panel-heading {
  color: #8a6d3b;
  background-color: #fcf8e3;
  border-color: #faebcc;
}
.panel-warning > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #faebcc;
}
.panel-warning > .panel-heading .badge {
  color: #fcf8e3;
  background-color: #8a6d3b;
}
.panel-warning > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #faebcc;
}

.panel-danger {
  border-color: #ebccd1;
}
.panel-danger > .panel-heading {
  color: #a94442;
  background-color: #f2dede;
  border-color: #ebccd1;
}
.panel-danger > .panel-heading + .panel-collapse > .panel-body {
  border-top-color: #ebccd1;
}
.panel-danger > .panel-heading .badge {
  color: #f2dede;
  background-color: #a94442;
}
.panel-danger > .panel-footer + .panel-collapse > .panel-body {
  border-bottom-color: #ebccd1;
}

.embed-responsive {
  position: relative;
  display: block;
  height: 0;
  padding: 0;
  overflow: hidden;
}
.embed-responsive .embed-responsive-item,
.embed-responsive iframe,
.embed-responsive embed,
.embed-responsive object {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  height: 100%;
  width: 100%;
  border: 0;
}
.embed-responsive.embed-responsive-16by9 {
  padding-bottom: 56.25%;
}
.embed-responsive.embed-responsive-4by3 {
  padding-bottom: 75%;
}

.well {
  min-height: 20px;
  padding: 19px;
  margin-bottom: 20px;
  background-color: #f5f5f5;
  border: 1px solid #e3e3e3;
  border-radius: 4px;
  -webkit-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-lg {
  padding: 24px;
  border-radius: 6px;
}

.well-sm {
  padding: 9px;
  border-radius: 3px;
}

.close {
  float: right;
  font-size: 21px;
  font-weight: bold;
  line-height: 1;
  color: #000;
  text-shadow: 0 1px 0 #fff;
  opacity: 0.2;
  filter: alpha(opacity=20);
}
.close:hover, .close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
  opacity: 0.5;
  filter: alpha(opacity=50);
}

button.close {
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
}

.modal-open {
  overflow: hidden;
}

.modal {
  display: none;
  overflow: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1050;
  -webkit-overflow-scrolling: touch;
  outline: 0;
}
.modal.fade .modal-dialog {
  -webkit-transform: translate3d(0, -25%, 0);
  transform: translate3d(0, -25%, 0);
  -webkit-transition: -webkit-transform 0.3s ease-out;
  -moz-transition: -moz-transform 0.3s ease-out;
  -o-transition: -o-transform 0.3s ease-out;
  transition: transform 0.3s ease-out;
}
.modal.in .modal-dialog {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

.modal-open .modal {
  overflow-x: hidden;
  overflow-y: auto;
}

.modal-dialog {
  position: relative;
  width: auto;
  margin: 10px;
}

.modal-content {
  position: relative;
  background-color: #fff;
  border: 1px solid #999;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
  background-clip: padding-box;
  outline: 0;
}

.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040;
  background-color: #000;
}
.modal-backdrop.fade {
  opacity: 0;
  filter: alpha(opacity=0);
}
.modal-backdrop.in {
  opacity: 0.5;
  filter: alpha(opacity=50);
}

.modal-header {
  padding: 15px;
  border-bottom: 1px solid #e5e5e5;
  min-height: 16.428571429px;
}

.modal-header .close {
  margin-top: -2px;
}

.modal-title {
  margin: 0;
  line-height: 1.428571429;
}

.modal-body {
  position: relative;
  padding: 15px;
}

.modal-footer {
  padding: 15px;
  text-align: right;
  border-top: 1px solid #e5e5e5;
}
.modal-footer:before, .modal-footer:after {
  content: " ";
  display: table;
}
.modal-footer:after {
  clear: both;
}
.modal-footer .btn + .btn {
  margin-left: 5px;
  margin-bottom: 0;
}
.modal-footer .btn-group .btn + .btn {
  margin-left: -1px;
}
.modal-footer .btn-block + .btn-block {
  margin-left: 0;
}

.modal-scrollbar-measure {
  position: absolute;
  top: -9999px;
  width: 50px;
  height: 50px;
  overflow: scroll;
}

@media (min-width: 768px) {
  .modal-dialog {
    width: 600px;
    margin: 30px auto;
  }

  .modal-content {
    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
  }

  .modal-sm {
    width: 300px;
  }
}
@media (min-width: 992px) {
  .modal-lg {
    width: 900px;
  }
}
.tooltip {
  position: absolute;
  z-index: 1070;
  display: block;
  visibility: visible;
  font-size: 12px;
  line-height: 1.4;
  opacity: 0;
  filter: alpha(opacity=0);
}
.tooltip.in {
  opacity: 0.9;
  filter: alpha(opacity=90);
}
.tooltip.top {
  margin-top: -3px;
  padding: 5px 0;
}
.tooltip.right {
  margin-left: 3px;
  padding: 0 5px;
}
.tooltip.bottom {
  margin-top: 3px;
  padding: 5px 0;
}
.tooltip.left {
  margin-left: -3px;
  padding: 0 5px;
}

.tooltip-inner {
  max-width: 200px;
  padding: 3px 8px;
  color: #fff;
  text-align: center;
  text-decoration: none;
  background-color: #000;
  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-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.top-left .tooltip-arrow {
  bottom: 0;
  left: 5px;
  border-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.top-right .tooltip-arrow {
  bottom: 0;
  right: 5px;
  border-width: 5px 5px 0;
  border-top-color: #000;
}
.tooltip.right .tooltip-arrow {
  top: 50%;
  left: 0;
  margin-top: -5px;
  border-width: 5px 5px 5px 0;
  border-right-color: #000;
}
.tooltip.left .tooltip-arrow {
  top: 50%;
  right: 0;
  margin-top: -5px;
  border-width: 5px 0 5px 5px;
  border-left-color: #000;
}
.tooltip.bottom .tooltip-arrow {
  top: 0;
  left: 50%;
  margin-left: -5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}
.tooltip.bottom-left .tooltip-arrow {
  top: 0;
  left: 5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}
.tooltip.bottom-right .tooltip-arrow {
  top: 0;
  right: 5px;
  border-width: 0 5px 5px;
  border-bottom-color: #000;
}

.popover {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1060;
  display: none;
  max-width: 276px;
  padding: 1px;
  text-align: left;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid #ccc;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  white-space: normal;
}
.popover.top {
  margin-top: -10px;
}
.popover.right {
  margin-left: 10px;
}
.popover.bottom {
  margin-top: 10px;
}
.popover.left {
  margin-left: -10px;
}

.popover-title {
  margin: 0;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: normal;
  line-height: 18px;
  background-color: #f7f7f7;
  border-bottom: 1px solid #ebebeb;
  border-radius: 5px 5px 0 0;
}

.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 {
  left: 50%;
  margin-left: -11px;
  border-bottom-width: 0;
  border-top-color: #999999;
  border-top-color: rgba(0, 0, 0, 0.25);
  bottom: -11px;
}
.popover.top > .arrow:after {
  content: " ";
  bottom: 1px;
  margin-left: -10px;
  border-bottom-width: 0;
  border-top-color: #fff;
}
.popover.right > .arrow {
  top: 50%;
  left: -11px;
  margin-top: -11px;
  border-left-width: 0;
  border-right-color: #999999;
  border-right-color: rgba(0, 0, 0, 0.25);
}
.popover.right > .arrow:after {
  content: " ";
  left: 1px;
  bottom: -10px;
  border-left-width: 0;
  border-right-color: #fff;
}
.popover.bottom > .arrow {
  left: 50%;
  margin-left: -11px;
  border-top-width: 0;
  border-bottom-color: #999999;
  border-bottom-color: rgba(0, 0, 0, 0.25);
  top: -11px;
}
.popover.bottom > .arrow:after {
  content: " ";
  top: 1px;
  margin-left: -10px;
  border-top-width: 0;
  border-bottom-color: #fff;
}
.popover.left > .arrow {
  top: 50%;
  right: -11px;
  margin-top: -11px;
  border-right-width: 0;
  border-left-color: #999999;
  border-left-color: rgba(0, 0, 0, 0.25);
}
.popover.left > .arrow:after {
  content: " ";
  right: 1px;
  border-right-width: 0;
  border-left-color: #fff;
  bottom: -10px;
}

.carousel {
  position: relative;
}

.carousel-inner {
  position: relative;
  overflow: hidden;
  width: 100%;
}
.carousel-inner > .item {
  display: none;
  position: relative;
  -webkit-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;
  width: 100% \9;
  max-width: 100%;
  height: auto;
  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: 0;
  left: 0;
  bottom: 0;
  width: 15%;
  opacity: 0.5;
  filter: alpha(opacity=50);
  font-size: 20px;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.carousel-control.left {
  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);
}
.carousel-control.right {
  left: auto;
  right: 0;
  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);
}
.carousel-control:hover, .carousel-control:focus {
  outline: 0;
  color: #fff;
  text-decoration: none;
  opacity: 0.9;
  filter: alpha(opacity=90);
}
.carousel-control .icon-prev,
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-left,
.carousel-control .glyphicon-chevron-right {
  position: absolute;
  top: 50%;
  z-index: 5;
  display: inline-block;
}
.carousel-control .icon-prev,
.carousel-control .glyphicon-chevron-left {
  left: 50%;
  margin-left: -10px;
}
.carousel-control .icon-next,
.carousel-control .glyphicon-chevron-right {
  right: 50%;
  margin-right: -10px;
}
.carousel-control .icon-prev,
.carousel-control .icon-next {
  width: 20px;
  height: 20px;
  margin-top: -10px;
  font-family: serif;
}
.carousel-control .icon-prev:before {
  content: '\2039';
}
.carousel-control .icon-next:before {
  content: '\203a';
}

.carousel-indicators {
  position: absolute;
  bottom: 10px;
  left: 50%;
  z-index: 15;
  width: 60%;
  margin-left: -30%;
  padding-left: 0;
  list-style: none;
  text-align: center;
}
.carousel-indicators li {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin: 1px;
  text-indent: -999px;
  border: 1px solid #fff;
  border-radius: 10px;
  cursor: pointer;
  background-color: #000 \9;
  background-color: transparent;
}
.carousel-indicators .active {
  margin: 0;
  width: 12px;
  height: 12px;
  background-color: #fff;
}

.carousel-caption {
  position: absolute;
  left: 15%;
  right: 15%;
  bottom: 20px;
  z-index: 10;
  padding-top: 20px;
  padding-bottom: 20px;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
.carousel-caption .btn {
  text-shadow: none;
}

@media screen and (min-width: 768px) {
  .carousel-control .glyphicon-chevron-left,
  .carousel-control .glyphicon-chevron-right,
  .carousel-control .icon-prev,
  .carousel-control .icon-next {
    width: 30px;
    height: 30px;
    margin-top: -15px;
    font-size: 30px;
  }
  .carousel-control .glyphicon-chevron-left,
  .carousel-control .icon-prev {
    margin-left: -15px;
  }
  .carousel-control .glyphicon-chevron-right,
  .carousel-control .icon-next {
    margin-right: -15px;
  }

  .carousel-caption {
    left: 20%;
    right: 20%;
    padding-bottom: 30px;
  }

  .carousel-indicators {
    bottom: 20px;
  }
}
.clearfix:before, .clearfix:after {
  content: " ";
  display: table;
}
.clearfix:after {
  clear: both;
}

.center-block {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.pull-right {
  float: right !important;
}

.pull-left {
  float: left !important;
}

.hide {
  display: none !important;
}

.show {
  display: block !important;
}

.invisible {
  visibility: hidden;
}

.text-hide {
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}

.hidden {
  display: none !important;
  visibility: hidden !important;
}

.affix {
  position: fixed;
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
}

@-ms-viewport {
  width: device-width;
}
.visible-xs, .visible-sm, .visible-md, .visible-lg {
  display: none !important;
}

.visible-xs-block,
.visible-xs-inline,
.visible-xs-inline-block,
.visible-sm-block,
.visible-sm-inline,
.visible-sm-inline-block,
.visible-md-block,
.visible-md-inline,
.visible-md-inline-block,
.visible-lg-block,
.visible-lg-inline,
.visible-lg-inline-block {
  display: none !important;
}

@media (max-width: 767px) {
  .visible-xs {
    display: block !important;
  }

  table.visible-xs {
    display: table;
  }

  tr.visible-xs {
    display: table-row !important;
  }

  th.visible-xs,
  td.visible-xs {
    display: table-cell !important;
  }
}
@media (max-width: 767px) {
  .visible-xs-block {
    display: block !important;
  }
}

@media (max-width: 767px) {
  .visible-xs-inline {
    display: inline !important;
  }
}

@media (max-width: 767px) {
  .visible-xs-inline-block {
    display: inline-block !important;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm {
    display: block !important;
  }

  table.visible-sm {
    display: table;
  }

  tr.visible-sm {
    display: table-row !important;
  }

  th.visible-sm,
  td.visible-sm {
    display: table-cell !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-block {
    display: block !important;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-inline {
    display: inline !important;
  }
}

@media (min-width: 768px) and (max-width: 991px) {
  .visible-sm-inline-block {
    display: inline-block !important;
  }
}

@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md {
    display: block !important;
  }

  table.visible-md {
    display: table;
  }

  tr.visible-md {
    display: table-row !important;
  }

  th.visible-md,
  td.visible-md {
    display: table-cell !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-block {
    display: block !important;
  }
}

@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-inline {
    display: inline !important;
  }
}

@media (min-width: 992px) and (max-width: 1199px) {
  .visible-md-inline-block {
    display: inline-block !important;
  }
}

@media (min-width: 1200px) {
  .visible-lg {
    display: block !important;
  }

  table.visible-lg {
    display: table;
  }

  tr.visible-lg {
    display: table-row !important;
  }

  th.visible-lg,
  td.visible-lg {
    display: table-cell !important;
  }
}
@media (min-width: 1200px) {
  .visible-lg-block {
    display: block !important;
  }
}

@media (min-width: 1200px) {
  .visible-lg-inline {
    display: inline !important;
  }
}

@media (min-width: 1200px) {
  .visible-lg-inline-block {
    display: inline-block !important;
  }
}

@media (max-width: 767px) {
  .hidden-xs {
    display: none !important;
  }
}
@media (min-width: 768px) and (max-width: 991px) {
  .hidden-sm {
    display: none !important;
  }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .hidden-md {
    display: none !important;
  }
}
@media (min-width: 1200px) {
  .hidden-lg {
    display: none !important;
  }
}
.visible-print {
  display: none !important;
}

@media print {
  .visible-print {
    display: block !important;
  }

  table.visible-print {
    display: table;
  }

  tr.visible-print {
    display: table-row !important;
  }

  th.visible-print,
  td.visible-print {
    display: table-cell !important;
  }
}
.visible-print-block {
  display: none !important;
}
@media print {
  .visible-print-block {
    display: block !important;
  }
}

.visible-print-inline {
  display: none !important;
}
@media print {
  .visible-print-inline {
    display: inline !important;
  }
}

.visible-print-inline-block {
  display: none !important;
}
@media print {
  .visible-print-inline-block {
    display: inline-block !important;
  }
}

@media print {
  .hidden-print {
    display: none !important;
  }
}
.btn-default,
.btn-primary,
.btn-success,
.btn-info,
.btn-warning,
.btn-danger {
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
}
.btn-default:active, .btn-default.active,
.btn-primary:active,
.btn-primary.active,
.btn-success:active,
.btn-success.active,
.btn-info:active,
.btn-info.active,
.btn-warning:active,
.btn-warning.active,
.btn-danger:active,
.btn-danger.active {
  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
}

.btn:active, .btn.active {
  background-image: none;
}

.btn-default {
  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
  background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
  background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFE0E0E0', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #dbdbdb;
  text-shadow: 0 1px 0 #fff;
  border-color: #ccc;
}
.btn-default:hover, .btn-default:focus {
  background-color: #e0e0e0;
  background-position: 0 -15px;
}
.btn-default:active, .btn-default.active {
  background-color: #e0e0e0;
  border-color: #dbdbdb;
}
.btn-default:disabled, .btn-default[disabled] {
  background-color: #e0e0e0;
  background-image: none;
}

.btn-primary {
  background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
  background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%);
  background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF428BCA', endColorstr='#FF2D6CA2', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #2b669a;
}
.btn-primary:hover, .btn-primary:focus {
  background-color: #2d6ca2;
  background-position: 0 -15px;
}
.btn-primary:active, .btn-primary.active {
  background-color: #2d6ca2;
  border-color: #2b669a;
}
.btn-primary:disabled, .btn-primary[disabled] {
  background-color: #2d6ca2;
  background-image: none;
}

.btn-success {
  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
  background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
  background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF5CB85C', endColorstr='#FF419641', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #3e8f3e;
}
.btn-success:hover, .btn-success:focus {
  background-color: #419641;
  background-position: 0 -15px;
}
.btn-success:active, .btn-success.active {
  background-color: #419641;
  border-color: #3e8f3e;
}
.btn-success:disabled, .btn-success[disabled] {
  background-color: #419641;
  background-image: none;
}

.btn-info {
  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
  background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
  background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF5BC0DE', endColorstr='#FF2AABD2', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #28a4c9;
}
.btn-info:hover, .btn-info:focus {
  background-color: #2aabd2;
  background-position: 0 -15px;
}
.btn-info:active, .btn-info.active {
  background-color: #2aabd2;
  border-color: #28a4c9;
}
.btn-info:disabled, .btn-info[disabled] {
  background-color: #2aabd2;
  background-image: none;
}

.btn-warning {
  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
  background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
  background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF0AD4E', endColorstr='#FFEB9316', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #e38d13;
}
.btn-warning:hover, .btn-warning:focus {
  background-color: #eb9316;
  background-position: 0 -15px;
}
.btn-warning:active, .btn-warning.active {
  background-color: #eb9316;
  border-color: #e38d13;
}
.btn-warning:disabled, .btn-warning[disabled] {
  background-color: #eb9316;
  background-image: none;
}

.btn-danger {
  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
  background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
  background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFD9534F', endColorstr='#FFC12E2A', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #b92c28;
}
.btn-danger:hover, .btn-danger:focus {
  background-color: #c12e2a;
  background-position: 0 -15px;
}
.btn-danger:active, .btn-danger.active {
  background-color: #c12e2a;
  border-color: #b92c28;
}
.btn-danger:disabled, .btn-danger[disabled] {
  background-color: #c12e2a;
  background-image: none;
}

.thumbnail,
.img-thumbnail {
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
}

.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF5F5F5', endColorstr='#FFE8E8E8', GradientType=0);
  background-color: #e8e8e8;
}

.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
  background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
  background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF428BCA', endColorstr='#FF357EBD', GradientType=0);
  background-color: #357ebd;
}

.navbar-default {
  background-image: -webkit-linear-gradient(top, white 0%, #f8f8f8 100%);
  background-image: -o-linear-gradient(top, white 0%, #f8f8f8 100%);
  background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFF8F8F8', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  border-radius: 4px;
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
}
.navbar-default .navbar-nav > .active > a {
  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
  background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);
  background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEBEBEB', endColorstr='#FFF3F3F3', GradientType=0);
  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
}

.navbar-brand,
.navbar-nav > li > a {
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
}

.navbar-inverse {
  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
  background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
  background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF3C3C3C', endColorstr='#FF222222', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
}
.navbar-inverse .navbar-nav > .active > a {
  background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%);
  background-image: -o-linear-gradient(top, #222 0%, #282828 100%);
  background-image: linear-gradient(to bottom, #222222 0%, #282828 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF222222', endColorstr='#FF282828', GradientType=0);
  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
}
.navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav > li > a {
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}

.navbar-static-top,
.navbar-fixed-top,
.navbar-fixed-bottom {
  border-radius: 0;
}

.alert {
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
}

.alert-success {
  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
  background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
  background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFDFF0D8', endColorstr='#FFC8E5BC', GradientType=0);
  border-color: #b2dba1;
}

.alert-info {
  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
  background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
  background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFD9EDF7', endColorstr='#FFB9DEF0', GradientType=0);
  border-color: #9acfea;
}

.alert-warning {
  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
  background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
  background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFCF8E3', endColorstr='#FFF8EFC0', GradientType=0);
  border-color: #f5e79e;
}

.alert-danger {
  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
  background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
  background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF2DEDE', endColorstr='#FFE7C3C3', GradientType=0);
  border-color: #dca7a7;
}

.progress {
  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
  background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
  background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEBEBEB', endColorstr='#FFF5F5F5', GradientType=0);
}

.progress-bar {
  background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);
  background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%);
  background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF428BCA', endColorstr='#FF3071A9', GradientType=0);
}

.progress-bar-success {
  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
  background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
  background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF5CB85C', endColorstr='#FF449D44', GradientType=0);
}

.progress-bar-info {
  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
  background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
  background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF5BC0DE', endColorstr='#FF31B0D5', GradientType=0);
}

.progress-bar-warning {
  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
  background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
  background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF0AD4E', endColorstr='#FFEC971F', GradientType=0);
}

.progress-bar-danger {
  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
  background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
  background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFD9534F', endColorstr='#FFC9302C', GradientType=0);
}

.progress-bar-striped {
  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: -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%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
}

.list-group {
  border-radius: 4px;
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
}

.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
  text-shadow: 0 -1px 0 #3071a9;
  background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);
  background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%);
  background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF428BCA', endColorstr='#FF3278B3', GradientType=0);
  border-color: #3278b3;
}

.panel {
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.panel-default > .panel-heading {
  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF5F5F5', endColorstr='#FFE8E8E8', GradientType=0);
}

.panel-primary > .panel-heading {
  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);
  background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%);
  background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FF428BCA', endColorstr='#FF357EBD', GradientType=0);
}

.panel-success > .panel-heading {
  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
  background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
  background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFDFF0D8', endColorstr='#FFD0E9C6', GradientType=0);
}

.panel-info > .panel-heading {
  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
  background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
  background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFD9EDF7', endColorstr='#FFC4E3F3', GradientType=0);
}

.panel-warning > .panel-heading {
  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
  background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
  background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFCF8E3', endColorstr='#FFFAF2CC', GradientType=0);
}

.panel-danger > .panel-heading {
  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
  background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
  background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFF2DEDE', endColorstr='#FFEBCCCC', GradientType=0);
}

.well {
  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
  background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
  background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
  background-repeat: repeat-x;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFE8E8E8', endColorstr='#FFF5F5F5', GradientType=0);
  border-color: gainsboro;
  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
}

.thumbnail-list li div.selection-show {
  position: absolute;
  border: 1px dashed red;
  display: none;
  pointer-events: none;
}

/* selections */
.repeat-lassos-group {
  position: absolute;
  right: -185px;
  bottom: -35px;
}

/* rectangularSelector.js classes */
.selection-box, .table-region {
  position: absolute;
  border: 1px dashed rgba(255, 87, 0, 0.8);
  background: rgba(255, 87, 0, 0.2);
  box-sizing: border-box;
}
.selection-box:hover, .table-region:hover {
  cursor: pointer;
}

.selection-box {
  z-index: 42;
  width: 0;
  height: 0;
  visibility: hidden;
}

.table-region {
  top: 0;
  left: 0;
  z-index: 21;
}

div.table-region .resize-handle {
  position: absolute;
}

div.table-region .n-border {
  width: calc(100% - 10px);
  top: -5px;
  left: 5px;
  height: 10px;
}

div.table-region .s-border {
  width: calc(100% - 10px);
  bottom: -5px;
  left: 5px;
  height: 10px;
}

div.table-region .w-border {
  height: calc(100% - 10px);
  left: -5px;
  top: 5px;
  width: 10px;
}

div.table-region .e-border {
  height: calc(100% - 10px);
  top: 5px;
  right: -5px;
  width: 10px;
}

div.table-region .nw-border {
  width: 10px;
  height: 10px;
  top: -5px;
  left: -5px;
}

div.table-region .ne-border {
  width: 10px;
  height: 10px;
  top: -5px;
  right: -5px;
}

div.table-region .sw-border {
  width: 10px;
  height: 10px;
  bottom: -5px;
  left: -5px;
}

div.table-region .se-border {
  width: 10px;
  height: 10px;
  bottom: -5px;
  right: -5px;
}

div.table-region .n-border:hover {
  cursor: n-resize;
}

div.table-region .nw-border:hover {
  cursor: nw-resize;
}

div.table-region .ne-border:hover {
  cursor: ne-resize;
}

div.table-region .s-border:hover {
  cursor: s-resize;
}

div.table-region .sw-border:hover {
  cursor: sw-resize;
}

div.table-region .se-border:hover {
  cursor: se-resize;
}

div.table-region .w-border:hover {
  cursor: w-resize;
}

div.table-region .e-border:hover {
  cursor: e-resize;
}

div.table-region button[name=close] {
  font-weight: bold;
  border: 0;
  background-color: transparent;
  padding: 0;
  font-size: 20px;
  position: relative;
  top: -25px;
  left: 100%;
  margin-left: 5px;
}

div.table-region button[name=close]:hover {
  color: red;
}

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url("glyphicons-halflings-regular.eot");
  src: url("../fonts/bootstrap/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/bootstrap/glyphicons-halflings-regular.woff") format("woff"), url("../fonts/bootstrap/glyphicons-halflings-regular.ttf") format("truetype"), url("../fonts/bootstrap/glyphicons-halflings-regular.svg#webfont") format("svg");
}
body {
  padding-top: 70px;
}

.jumbotron h1 {
  font-size: 2em;
}
.jumbotron h2, .jumbotron h3, .jumbotron h4, .jumbotron h5, .jumbotron h6 {
  font-size: 1.3em;
}
.jumbotron p {
  font-size: 1.3em;
}

.navbar-fixed-top .container {
  width: 95%;
  margin: 0 auto;
}

#navbar .active {
  font-weight: 500;
  color: #333333;
}

.navbar-default a.navbar-brand {
  padding-left: 30px;
  position: relative;
  font-weight: bold;
  color: black;
}
.navbar-default a.navbar-brand::before {
  position: absolute;
  content: "";
  display: block;
  background-image: url("../img/logo.png");
  background-repeat: no-repeat;
  background-size: 25px 30px;
  width: 25px;
  height: 30px;
  left: 0;
  top: 10px;
}

.btn-file {
  position: relative;
  overflow: hidden;
}

.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}

.form-inline .input-group > .form-control, .navbar-form .input-group > .form-control {
  background: white;
  width: 500px;
}

form {
  margin-bottom: 3em;
}

#file-list-container {
  max-height: 500px;
  overflow-y: scroll;
}
#file-list-container .file-list thead tr th {
  text-align: center;
  cursor: pointer;
  position: relative;
  border-right: 1px solid #ddd;
  padding-right: 20px;
}
#file-list-container .file-list thead tr th::before, #file-list-container .file-list thead tr th::after {
  text-align: right;
  width: 11px;
  color: #ddd;
  position: absolute;
  display: block;
  font-family: 'Glyphicons Halflings';
  font-size: .8em;
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
#file-list-container .file-list thead tr th::before {
  content: "\e113";
  right: 3px;
  top: 6px;
}
#file-list-container .file-list thead tr th::after {
  content: "\e114";
  right: 4px;
  bottom: 6px;
}
#file-list-container .file-list thead tr th.headerSortUp::before {
  color: #777777 !important;
}
#file-list-container .file-list thead tr th.headerSortDown:after {
  color: #777777 !important;
}
#file-list-container .file-list thead tr th:first-of-type {
  text-align: left;
}
#file-list-container .file-list thead tr th:nth-child(n+5) {
  cursor: default;
  padding-right: 8px;
}
#file-list-container .file-list thead tr th:nth-child(n+5)::before, #file-list-container .file-list thead tr th:nth-child(n+5)::after {
  content: "";
  display: none;
  position: relative;
}
#file-list-container .file-list tbody tr {
  background: white;
}
#file-list-container .file-list tbody tr:hover {
  background: #d9edf7;
}
#file-list-container .file-list tbody tr td {
  line-height: 2.25;
  text-align: center;
}
#file-list-container .file-list tbody tr td:first-of-type {
  font-weight: bold;
  text-align: left;
}
#file-list-container .file-list tbody tr td a {
  color: #333;
}

.glyphicon-remove {
  color: #777777;
}
.glyphicon-remove:hover {
  color: #d9534f;
}

#sidebar {
  background: #eeeeee;
  width: 195px;
  padding: 1em 0 0;
  height: calc(100% - 51px);
  text-align: center;
  overflow-y: scroll;
  overflow-x: hidden;
  position: fixed;
  left: 0;
  top: 51px;
  z-index: 2;
  -webkit-box-shadow: inset -0.25em 0 0.5em -0.25em rgba(0, 0, 0, 0.1);
  box-shadow: inset -0.25em 0 0.5em -0.25em rgba(0, 0, 0, 0.1);
}
#sidebar h5 {
  border-top: 1px solid #777777;
  padding-top: 1em;
  margin-top: 1em;
}
#sidebar .btn-group button {
  width: 83px;
  margin-bottom: 10px;
}
#sidebar p {
  font-size: .9em;
}
#sidebar .thumbnail-list {
  padding-left: 0px;
}
#sidebar .thumbnail-list .page {
  margin: 0 auto 1.25em;
  display: block;
  width: 90%;
  padding: 1em .5em .5em 1em;
  position: relative;
}
#sidebar .thumbnail-list .page img {
  display: block;
  width: 100%;
}
#sidebar .thumbnail-list .page p {
  margin-top: .25em;
  color: #555555;
  line-height: 1;
}
#sidebar .thumbnail-list .page:hover img {
  cursor: pointer;
  -webkit-box-shadow: 0 0 0 0.1em rgba(0, 0, 0, 0.1);
  box-shadow: 0 0 0 0.1em rgba(0, 0, 0, 0.1);
}
#sidebar .thumbnail-list .page.active img {
  -webkit-box-shadow: 0 0 0 0.1em #5bc0de;
  box-shadow: 0 0 0 0.1em #5bc0de;
}
#sidebar .thumbnail-list .page .remove {
  position: absolute;
  left: -.25em;
  top: 1em;
  height: 1em;
  display: block;
  line-height: 1;
  font-size: 1em;
}
#sidebar .thumbnail-list .page .remove:hover {
  cursor: pointer;
}

#control-panel {
  position: fixed;
  top: 50px;
  left: 195px;
  width: calc(100% - 200px);
  z-index: 101;
  /* gotta be >100, which is the max z-index for selections */
  background: #d9edf7;
  padding: 1em;
  -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.075);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.075);
}
#control-panel button {
  margin-right: 1.25em;
}
#control-panel .filename {
  display: inline-block;
  margin-right: 20px;
  max-width: 270px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#control-panel span.filename {
  vertical-align: middle;
}
#control-panel #template-dropdown-container ul {
  padding-left: 20px;
}
#control-panel #template-dropdown-container button {
  padding-left: 0px;
}
#control-panel #template-dropdown-container ul:first-of-type {
  margin-bottom: 0px;
}
#control-panel #template-dropdown-container li a {
  cursor: pointer;
  color: #333;
}
#control-panel #template-dropdown-templates-list-container li a {
  cursor: pointer;
  color: #333;
}

#notifications-approval-clicky{
  width: 100%;
  padding: 1em 3em;
  position: fixed;
  bottom: 0;
  background: #FFFFE0;
  font-size: 14px;
}
#notifications-approval-clicky #notifications-approval-close {
  position: absolute;
  right: 0;
  top: 0;
}

#main-pane {
  background: #777777;
  padding: 4.25em 2em 2em 2em;
  margin-left: 195px;
  height: 100%;
  width: calc(100% - 200px);
  z-index: 1;
}
#main-pane .pdf-page {
  position: relative;
}
#main-pane .pdf-page .page-number {
  position: absolute;
}
#main-pane .page {
  width: 100%;
  max-width: 800px;
  min-width: 560px;
  -webkit-box-shadow: 0 0 2em rgba(0, 0, 0, 0.4);
  box-shadow: 0 0 2em rgba(0, 0, 0, 0.4);
  position: relative;
  margin: 0 auto;
}
#main-pane .page img {
  margin: 2em 0;
  display: block;
  width: 100%;
  max-width: 800px;
  min-width: 560px;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}
#main-pane .page img:hover {
  cursor: crosshair;
}
#main-pane .selection-box, #main-pane .table-region {
  border: 3px dashed rgba(224, 1, 1, 0.6);
  background: rgba(224, 1, 1, 0.2);
}
#main-pane .selection-box .selection-panel, #main-pane .table-region .selection-panel {
  display: none;
  position: absolute;
  bottom: -2.8em;
  left: 0;
  min-width: 320px;
}
#main-pane .selection-box .selection-panel button:hover, #main-pane .table-region .selection-panel button:hover {
  cursor: pointer;
}
#main-pane .selection-box:hover, #main-pane .table-region:hover {
  cursor: move;
}
#main-pane .selection-box:hover .selection-panel, #main-pane .table-region:hover .selection-panel {
  display: block;
}

body.page-selections {
  padding-top: 50px;
  background: #777777;
}
body.page-selections #main-pane {
  background: #777777;
}

body.page-export {
  padding-top: 50px;
  background: white;
}
body.page-export #sidebar {
  text-align: left;
  padding: .5em;
}
body.page-export #sidebar .lattice.glyphicon {
  color: #ededed;
  background: #666;
  text-shadow: none;
  border: solid #666;
  border-width: 0 0 1px 1px;
}
body.page-export #main-pane {
  background: white;
  padding-top: 5.5em;
}
body.page-export #main-pane #control-panel form {
  display: inline-block;
  margin-bottom: 0;
}
body.page-export #main-pane #control-panel form .form-control {
  width: 100px;
  margin-right: 1em;
  display: inline-block;
}
body.page-export #main-pane #control-panel form .form-control.format {
  width: 130px;
}
body.page-export #main-pane #control-panel form #copy-csv-to-clipboard {
  min-width: 140px;
}
body.page-export #main-pane table {
  margin-top: 2em;
}

.jumbotron.about p {
  font-size: 1.1em;
}

div.spinner {
  top: 10px !important;
}

#progress-container h5 {
  display: inline-block;
  font-size: 1.1em;
  font-weight: bold;
}

#progress-container #message {
  color: #aaa;
}

.autodetect-in-progress .glyphicon-refresh,
#download-data.download-in-progress .glyphicon-refresh {
  animation: 4s linear 0s normal none infinite running spin;
  display: inline-block;
}

@-moz-keyframes spin {
  0% {
    -moz-transform: rotate(0deg);
  }
  100% {
    -moz-transform: rotate(359deg);
  }
}
@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
  }
}
@-o-keyframes spin {
  0% {
    -o-transform: rotate(0deg);
  }
  100% {
    -o-transform: rotate(359deg);
  }
}
@keyframes spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(359deg);
    transform: rotate(359deg);
  }
}
.autodetect-in-progress .glyphicon-flash {
  display: none;
}

.autodetect-finished .glyphicon-flash {
  display: inline;
}

.autodetect-finished .glyphicon-refresh {
  display: none;
}

#download-data.download-in-progress .glyphicon-download {
  display: none;
}
#download-data .glyphicon-download {
  display: inline;
}
#download-data .glyphicon-refresh {
  display: none;
}

.flash {
  -moz-animation: flash 2s ease-out;
  -moz-animation-iteration-count: 1;
  -webkit-animation: flash 2s ease-out;
  -webkit-animation-iteration-count: 1;
  -ms-animation: flash 2s ease-out;
  -ms-animation-iteration-count: 1;
}

@-webkit-keyframes flash {
  0% {
    background-color: none;
  }
  50% {
    background-color: #fbf8b2;
  }
  100% {
    background-color: none;
  }
}
@-moz-keyframes flash {
  0% {
    background-color: none;
  }
  50% {
    background-color: #fbf8b2;
  }
  100% {
    background-color: none;
  }
}
@-ms-keyframes flash {
  0% {
    background-color: none;
  }
  50% {
    background-color: #fbf8b2;
  }
  100% {
    background-color: none;
  }
}
#loading {
  padding-left: 30px;
}
#loading #spinner {
  position: relative;
  top: 6px;
  margin-right: 5px;
}


================================================
FILE: webapp/static/js/debug_pdf_view.js
================================================
Tabula.DebugPDFView = {
    colors: ['#f00', '#0f0', '#00f', '#ffff00', '#FF00FF'],
    debugRulings: function(image, render, clean, show_intersections) {
        image = $(image);
        var imagePos = image.offset();
        var newCanvas =  $('',{'class':'debug-canvas'})
            .attr('width', image.width())
            .attr('height', image.height())
            .css('top', imagePos.top + 'px')
            .css('left', imagePos.left + 'px');
        $('body').append(newCanvas);

        var pdf_rotation = parseInt($(image).data('rotation'));
        var original_pdf_width = parseInt($(image).data('original-width'));
        var original_pdf_height = parseInt($(image).data('original-height'));
        var thumb_width = $(image).width();

        var scale = thumb_width / (Math.abs(pdf_rotation) == 90 ? original_pdf_height : original_pdf_width);

        var lq = $.extend(this.lastQuery,
                          {
                              pdf_page_width: original_pdf_width,
                              render_page: render === true,
                              clean_rulings: clean === true,
                              show_intersections: show_intersections === true
                          });

        $.get('/debug/' + PDF_ID + '/rulings',
              lq,
              _.bind(function(data) {
                  $.each(data.rulings, _.bind(function(i, ruling) {
                      $("canvas").drawLine({
                          strokeStyle: this.colors[i % this.colors.length],
                          strokeWidth: 1,
                          x1: ruling[0] * scale, y1: ruling[1] * scale,
                          x2: ruling[2] * scale, y2: ruling[3] * scale
                      });
                  }, this));

                  $.each(data.intersections, _.bind(function(i, intersection) {
                      $("canvas").drawEllipse({
                          fillStyle: this.colors[i % this.colors.length],
                          width: 5, height: 5,
                          x: intersection[0] * scale,
                          y: intersection[1] * scale
                      });
                  }, this));
              }, this));
    },

    _debugRectangularShapes: function(image, url) {
      image = $(image);
      var imagePos = image.offset();
      var newCanvas =  $('',{'class':'debug-canvas'})
          .attr('width', image.width())
          .attr('height', image.height())
          .css('top', imagePos.top + 'px')
          .css('left', imagePos.left + 'px');
      $('body').append(newCanvas);

      var thumb_width = $(image).width();
      var thumb_height = $(image).height();
      var original_pdf_width = parseInt($(image).data('original-width'));
      var original_pdf_height = parseInt($(image).data('original-height'));
      var pdf_rotation = parseInt($(image).data('rotation'));

      var scale = thumb_width / (Math.abs(pdf_rotation) == 90 ? original_pdf_height : original_pdf_width);

      $.get(url,
            this.lastQuery,
            _.bind(function(data) {
                $.each(data, _.bind(function(i, row) {
                    $("canvas").drawRect({
                        strokeStyle: this.colors[i % this.colors.length],
                        strokeWidth: 1,
                        x: row.left * scale, y: row.top * scale,
                        width: row.width * scale,
                        height: row.height * scale,
                        fromCenter: false
                    });
                }, this));
            }, this));

    },

    debugCharacters: function(image) {
      return this._debugRectangularShapes(image, '/debug/' + PDF_ID + '/characters');
    },

    debugClippingPaths: function(image) {
      return this._debugRectangularShapes(image, '/debug/' + PDF_ID + '/clipping_paths');
    },

    debugColumns: function(image) {
      image = $(image);
      var imagePos = image.offset();
      var newCanvas =  $('',{'class':'debug-canvas'})
          .attr('width', image.width())
          .attr('height', image.height())
          .css('top', imagePos.top + 'px')
          .css('left', imagePos.left + 'px');
      $('body').append(newCanvas);

      var thumb_width = $(image).width();
      var thumb_height = $(image).height();
      var original_pdf_width = parseInt($(image).data('original-width'));
      var original_pdf_height = parseInt($(image).data('original-height'));
      var pdf_rotation = parseInt($(image).data('rotation'));

      var scale = thumb_width / (Math.abs(pdf_rotation) == 90 ? original_pdf_height : original_pdf_width);

      var list_of_coords = JSON.parse(this.lastQuery.coords);

      Tabula.pdf_view.query.doQuery({
        success: _.bind(function(data) {
                   var colors = this.colors;
                   $.each(data[0].vertical_separators, function(i, vert) {
                     newCanvas.drawLine({
                       strokeStyle: colors[i % colors.length],
                       strokeWidth: 1,
                       x1: vert * scale, y1: list_of_coords[0].y1 * scale,
                       x2: vert * scale, y2: list_of_coords[0].y2 * scale
                     });
                   });
                 }, this)});

    },

    debugCoordsToTabula: function() {
        var coords = eval(this.lastQuery.coords)[0];
        return [coords.y1, coords.x1, coords.y2, coords.x2].join(',');
    },

    debugTextChunks: function(image) {
      return this._debugRectangularShapes(image, '/debug/' + PDF_ID + '/text_chunks');
    },
})

================================================
FILE: webapp/static/js/library.js
================================================
Tabula = window.Tabula || {};
var base_uri = $('base').attr("href");

Tabula.FileUpload = Backbone.Model.extend({
  // isOneOfMultiple:
  // uploadTime
  // uploadOrder
  initialize: function(){
    this.set({
      message: 'waiting to be processed...',
      pct_complete: 0,
      warnings: []
    });
  },

  checkStatus: function() {
    if(typeof this.get('file_id') == 'undefined' && typeof !this.get('upload_id') == 'undefined'){
      this.pct_complete = 1;
      this.message = "waiting to be processed..."
    }else{
      $.ajax({
          dataType: 'json',
          url: (base_uri || '/') + 'queue/'+this.get('upload_id')+'/json?file_id=' + this.get('file_id'),
          success: _.bind(function(data, status, xhr) {
            if( (data.message.length && data.message != "complete") || data.pct_complete == 100 ){
              this.set('message',  data.message);
            } else if(data.pct_complete > 1) {
              this.set('message', 'processing');
            }

            this.set('pct_complete', data.pct_complete);
            this.set('warnings', data.warnings);

            if (data.status == "error" && data.error_type == "unknown") {
                // window.location.reload(true);
            } else if (data.status == "error" && data.error_type == "no-text") {
                console.log('no text');
                window.clearTimeout(this.timer);

                // resets upload/input form
                $('form#upload').find('button').removeAttr('disabled');
                $('form#upload')[0].reset();

                //TODO: something prettier.
                alert("Sorry, your PDF file is image-based; it does not have any embedded text. It might have been scanned from paper... Tabula isn't able to extract any data from image-based PDFs. Click the Help button for more information.");
            } else if(data.pct_complete < 100) {
                this.timer = setTimeout(_.bind(this.checkStatus, this), 1000);
            } else {
              this.collection.remove(this);
              Tabula.library.files_collection.fetch();
            }
          }, this),
          error: function(xhr, status, err) {
              console.log('err', err); //TODO:
          }
      });
    }
  },

});

// does flash work?
// clear the input

Tabula.FileUploadsCollection = Backbone.Collection.extend({
  model: Tabula.FileUpload,
  comparator: function(i){ return -i.get('uploadTime') - i.get('uploadOrder')},
})

Tabula.UploadedFile = Backbone.Model.extend({
  size: null,
  page_count: null,
  initialize: function(){
    this.set('size', this.get('size') || null);
    this.set('page_count', this.get('page_count') || null)
  }
});

Tabula.UploadedFilesCollection = Backbone.Collection.extend({
    model: Tabula.UploadedFile,
    url: function(){ return 'documents'+ '?' + Number(new Date()).toString() },
    comparator: function(i){ return -i.get('time')},
    parse: function(pdfs){
      _(pdfs).each(function(i){
        if(!i.original_filename){
          i.original_filename = i.file;
        }
      });
      // if it's still being processed, don't enter it into the library.
      pdfs = _(pdfs).reject(_.bind(function(uploaded_file){
        var in_progress = Tabula.library && Tabula.library.uploads_collection.findWhere({file_id: uploaded_file.id});
        return in_progress
      }, this));
      return pdfs;
    }
});


Tabula.UploadedFileView = Backbone.View.extend({
  tagName: 'tr',
  className: 'uploaded-file',
  events: {
    'click .delete-pdf': 'deletePDF'
  },
  template: _.template( $('#uploaded-file-template').html().replace(/nestedscript/g, 'script')),
  initialize: function(){
    _.bindAll(this, 'render', 'deletePDF');
  },
  render: function(){
    this.$el.append(this.template(this.model.attributes));
    this.$el.addClass('file-id-' + this.model.get('id')); // more efficient lookups than data-attr
    this.$el.data('id', this.model.get('id')); //more cleanly accesse than a class
    return this;
  },
  deletePDF: function(e) {
    var btn = $(e.currentTarget);
    var tr = btn.parents('tr');

    if (!confirm('Delete file "'+btn.data('filename')+'"?')) return;
    var pdf_id = btn.data('pdfid');

    $.post((base_uri || '/') + 'pdf/' + pdf_id,
          { _method: 'delete' },
          function() {
            tr.fadeOut(200, function() { $(this).remove(); });
          });
    },
})

Tabula.ProgressBars = Backbone.View.extend({
  template: _.template( $('#progress-bars-template').html().replace(/nestedscript/g, 'script')),
  initialize: function(stuff){
    _.extend(this, stuff); //  in-place.
    this.listenTo(this.uploads_collection, 'remove', this.render);
  },
  render: function(){
    if(this.uploads_collection.size() > 0){
      this.in_progress = false;
      if(!$.trim(this.$el.html())) this.$el.html(this.template({}))
    }else if(!this.in_progress){
      //TODO: this belongs in Library, technically, but we don't go around rerendering that, so here it is for now.
      $('form#upload').find('button').removeAttr('disabled');
      $('form#upload')[0].reset();
    }
    return this;
  }
});

Tabula.Library = Backbone.View.extend({
    events: {
        "submit form#upload": 'uploadPDF',
    },
    template: _.template( $('#uploader-template').html().replace(/nestedscript/g, 'script')),
    initialize: function(){
      _.bindAll(this, 'uploadPDF', 'render', 'renderFileLibrary');
      this.files_collection = new Tabula.UploadedFilesCollection([]);
      this.files_collection.fetch({silent: true, complete: _.bind(function(){ this.render(); }, this) });
      
      this.listenTo(this.files_collection, 'add', this.renderFileLibrary);
      this.uploads_collection = new Tabula.FileUploadsCollection([]);

      this.listenTo(Tabula.notification, 'change', this.renderNotification);
      this.listenTo(Tabula.new_version, 'change', this.renderVersion);
    },
    renderNotification: function(){
      if(_.isEmpty(Tabula.notification.attributes)) return;
      $('#notification-alert').html(_.template($('#notification-template').html().replace(/nestedscript/g, 'script'))({
        notification: Tabula.notification.attributes,
        api_version: Tabula.api_version
      })).show();
    },
    renderVersion: function(){
      if(_.isEmpty(Tabula.new_version.attributes)) return;
      console.log('render new version');
      $('#new-version-alert').html(_.template($('#new-version-template').html().replace(/nestedscript/g, 'script'))({
        new_release: Tabula.new_version.attributes,
        api_version: Tabula.api_version
      })).show();
    },
    uploadPDF: function(e){
      $(e.currentTarget).find('button').attr('disabled', 'disabled');
      this.progress_bars = new Tabula.ProgressBars({el: '#progress-container', uploads_collection: this.uploads_collection });
      this.progress_bars.in_progress = true;
      this.progress_bars.render();

      var files_list = $(e.currentTarget).find('#file')[0].files
      _(files_list).each(_.bind(function(file, index){
        //TODO: the model should get the data, then fire an event that the view listens for, to rerender
        var file_upload = new Tabula.FileUpload({
          collection: this.uploads_collection,
          filename: file.name,
          uploadTime: new Date(),
          uploadOrder: index,
          isOneOfMultiple: files_list.length != 1
        });
        this.uploads_collection.add(file_upload);
        var checker = new Tabula.ProgressBar({model: file_upload });
        this.progress_bars.render().$el.find('#progress-bars-container').append(checker.render().el)
      },this));

      var formdata = new FormData($('form#upload')[0]);
      $.ajax({
          url: $('form#upload').attr('action'),
          type: 'POST',
          success: _.bind(function (res) {
              var statuses = JSON.parse(res);
              _(statuses).each(_.bind(function(status){
                var file_upload = this.uploads_collection.findWhere({filename: status.filename });
                if(!file_upload){
                  console.log("couldn't find upload objcect for " + status.filename );
                  return
                }
                if(status.success){
                  file_upload.set('file_id', status.file_id);
                  file_upload.set('id', status.file_id);
                  file_upload.set('upload_id', status.upload_id);
                  file_upload.set('error', !status.success);
                  file_upload.checkStatus(); //
                }else{
                  console.log('TODO: failure')
                  file_upload.set('file_id', status.file_id);
                  file_upload.set('id', status.file_id);
                  file_upload.set('upload_id', status.upload_id);
                  file_upload.set('error', !status.success);
                }
              }, this))
          }, this),
          error: _.bind(function(a,b,c){
            $(e.currentTarget).find('button').removeAttr('disabled');
            this.uploads_collection.each(function(file_upload){
              file_upload.message = "Sorry, your file upload could not be processed. ("+a.statusText+")";
              file_upload.pct_complete = 100;
              file_upload.error = true;
            })
          },this),
          data: formdata,

          cache: false,
          contentType: false,
          processData: false
      });
      e.preventDefault();
      return false; // don't actually submit the form
    },

    renderFileLibrary: function(added_model){
      if(this.files_collection.length > 0){
        $('#library-container').show();
        ($('#uploaded-files-container').is(':empty') ? this.files_collection.reverse() : this.files_collection).
        each(_.bind(function(uploaded_file){
          if(this.$el.find('.file-id-' + uploaded_file.get('id') ).length){
            return;
          }
          var file_element = new Tabula.UploadedFileView({model: uploaded_file}).render().$el;
          if(added_model && added_model.get('id') == uploaded_file.get('id')){
            file_element.addClass('flash');
          }
          $('#uploaded-files-container').prepend(file_element);
        }, this));

        //remove anything that was deleted
        this.$el.find('.uploaded-file').each(_.bind(function(i, el){
          if(typeof this.files_collection.findWhere({id: $(el).data('id')}) === "undefined"){
            $(el).remove();
          }
        }, this));

        $("#fileTable").tablesorter( {
          headers: { 3: { sorter: "usLongDate" },  4: { sorter: false}, 5: {sorter: false} },
          sortList: [[3,1]]  // initial sort
          } );
      }else{
        $('#library-container').hide();
        $('#library-container').
          after(_.template( $('#help-template').html().replace(/nestedscript/g, 'script') )({})).
          after('

First time using Tabula? Welcome!

'); $('.jumbotron.help').css('padding-top', '10px'); } }, render: function(){ $('#tabula-app').html( this.template({ TABULA_VERSION: Tabula.version, pct_complete: 0, importing: false }) ); this.renderFileLibrary(); this.renderNotification(); this.renderVersion(); return this; } }); Tabula.ProgressBar = Backbone.View.extend({ file_id: null, upload_id: null, pct_complete: 0, message: null, tagName: 'div', template: _.template( $('#file-upload-template').html().replace(/nestedscript/g, 'script')), initialize: function(){ _.bindAll(this, 'render'); this.listenTo(this.model, 'change:pct_complete', this.render); }, render: function(){ if(this.model.get('pct_complete') <= 0){ this.$el.find('h4').text("Upload Progress"); }else if(this.model.get('pct_complete') >= 100 && !this.model.get('error')){ this.$el.find('h4').text("Upload Finished."); this.$el.find('#message').text(''); if (!!this.spinobj) { this.spinobj.stop() }; if(this.model.get('isOneOfMultiple')){ this.remove(); }else{ window.location = (base_uri || '/') + 'pdf/' + this.model.get('file_id'); }; }else if(this.model.get('pct_complete') >= 100 && this.model.get('error')){ this.$el.find('h4').text("Upload Failed."); }else{ this.$el.find('h4').text("Importing…"); var spinpots = { lines: 11, length: 5, width: 2, radius: 4, hwaccel: true, top: '0', left: 0 }; this.spinobj = new Spinner(spinpots).spin(this.$el.find('#spinner')[0]); } this.$el.html(this.template(this.model.attributes)); return this; } }); ================================================ FILE: webapp/static/js/pdf_view.js ================================================ Tabula = Tabula || {}; var clip = null; var base_uri = $('base').attr("href"); PDF_ID = window.location.pathname.replace(base_uri, '').split('/')[1]; Tabula.LazyLoad = 10; // max number of pages around the cursor to show (2x Tabula.LazyLoad pages are shown) Tabula.HideOnLazyLoad = false; // ideally, set to true, but this requires differently positioned selections, see https://github.com/tabulapdf/tabula/issues/245#issuecomment-75182061 ZeroClipboard.config( { swfPath: (base_uri || '/') + "swf/ZeroClipboard.swf" } ); Tabula.entityMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }; Tabula.escapeHtml = function(string) { return String(string).replace(/[&<>"'`=\/]/g, function (s) { return Tabula.entityMap[s]; }); } Tabula.Page = Backbone.Model.extend({ // number: null, //set on initialize // width: null, //set on initialize // height: null, //set on initialize // rotation: null, //set on initialize initialize: function(){ this.set('number_zero_indexed', this.get('number') - 1); }, imageUrl: function(){ var resolution = Math.max(Tabula.pdf_view.pdf_document.get('thumbnail_sizes')) || 800; this.set('image_url', (base_uri || '/') + 'pdfs/' + PDF_ID + '/document_'+resolution+'_' + this.get('number') + '.png'); return this.get('image_url'); } }); Tabula.Pages = Backbone.Collection.extend({ model: Tabula.Page, url: null, //set on initialize comparator: 'number', initialize: function(){ this.url = (base_uri || '/') + 'pdfs/' + PDF_ID + '/pages.json?_=' + Math.round(+new Date()).toString(); } }); Tabula.Document = Backbone.Model.extend({ page_collection: null, //set on initialize selections: null, //set on initialize pdf_id: PDF_ID, //set on initialize url: null, //set on initialize initialize: function(options){ this.page_collection = new Tabula.Pages([], {pdf_document: this}); this.selections = new Tabula.Selections([], {pdf_document: this}); this.autodetected_selections = new Tabula.AutodetectedSelections([], {pdf_document: this}); this.url = (base_uri || '/') + 'pdf/' + this.pdf_id + '/metadata.json'; this.set('original_filename', ''); this.set('new_filename', false); }, }); Tabula.Selection = Backbone.Model.extend({ pdf_id: PDF_ID, initialize: function(){ _.bindAll(this, 'repeatLassos', 'toCoords'); }, updateCoords: function(){ var page = Tabula.pdf_view.pdf_document.page_collection.findWhere({number: this.get('page_number')}); var imageWidth = this.get('imageWidth'); var original_pdf_width = page.get('width'); var original_pdf_height = page.get('height'); // var pdf_rotation = page.get('rotation'); var scale = original_pdf_width / imageWidth; var rp = this.attributes.getDims().relativePos; this.set({ x1: rp.left * scale, x2: (rp.left + rp.width) * scale, y1: rp.top * scale, y2: (rp.top + rp.height) * scale, width: rp.width * scale, // not used by Tabula right now, but used in the UI elsewhere height: rp.height * scale, // not used by Tabula right now, but used in the UI elsewhere }); }, toCoords: function(){ if (this.attributes.getDims){ this.updateCoords(); } var selection_coords = { page: this.get('page_number'), extraction_method: this.get('extractionMethod') || 'guess', selection_id: this.id, x1: this.get('x1'), x2: this.get('x2'), y1: this.get('y1'), y2: this.get('y2'), width: this.get('width'), height: this.get('height') }; return selection_coords; }, repeatLassos: function() { Tabula.pdf_view.pdf_document.page_collection.each(_.bind(function(page){ if(this.get('page_number') < page.get('number')){ // for each page after this one, new_selection = this.clone(); // and create a new Selection. new_selection.set('page_number', page.get('number')); this.collection.add(Tabula.pdf_view.renderSelection(new_selection.toCoords())); /* which causes thumbnails to be created, Download All button to know about these selections. */ } }, this)); }, repeatLassoOnce: function() { var current_page_number = this.get('page_number'); var next_page = Tabula.pdf_view.pdf_document.page_collection.at(Tabula.pdf_view.pdf_document.page_collection.indexOf(Tabula.pdf_view.pdf_document.page_collection.findWhere({number: current_page_number}))+1); new_selection = this.clone(); // and create a new Selection. new_selection.set('page_number', next_page.get('number')); this.collection.add(Tabula.pdf_view.renderSelection(new_selection.toCoords())); }, }); // Not currently used at all. Tabula.Options = Backbone.Model.extend({ initialize: function(){ _.bindAll(this, 'write'); // this.set('multiselect_mode', localStorage.getItem("tabula-multiselect-mode") !== "false"); }, write: function(){ // localStorage.setItem("tabula-multiselect-mode", this.get('multiselect_mode')); } }); /* What the hell are you doing here, Jeremy? The canonical store of selections now needs to be in Backbone, not in imgareaselect. The UI can listen to the Selections; imgAreaselect creates adds to the collection, causing the thumbnail to be drawn. Clearing or repeating is much easier, because we don't have to mess around with the UI. Querying all is likewise easy. We could also store extraction option info on the selections, if we want. On imgareaselect's _onSelectEnd, add the selection to Selections On Selections's remove (or change), find the right imgAreaSelect */ Tabula.Selections = Backbone.Collection.extend({ // model: Tabula.Selection, comparator: 'page_number', updateOrCreateByVendorSelectorId: function(vendorSelection, pageNumber, imageWidth){ var selection = this.get(vendorSelection.id); if (selection) { // if it already exists selection.set(_.omit(vendorSelection, 'id')); } else { new_selection_args = _.extend({'page_number': pageNumber, 'imageWidth': imageWidth, 'extraction_method': Tabula.pdf_view.options.extraction_method, 'hidden': false, 'pdf_document': this.pdf_document}, vendorSelection); selection = new Tabula.Selection(new_selection_args); this.add(selection); } return selection; }, createHiddenSelection: function(sel){ new_selection_args = _.extend({'page_number': sel.page, 'extraction_method': 'spreadsheet', 'id': Math.random().toString(), 'hidden': true, 'pdf_document': this.pdf_document}, sel); selection = new Tabula.Selection(new_selection_args); this.add(selection); return selection; } }); Tabula.AutodetectedSelections = Tabula.Selections.extend({ url: null, //set on init initialize: function(){ this.url = (base_uri || '/') + 'pdfs/' + PDF_ID + '/tables.json?_=' + Math.round(+new Date()).toString(); _.bindAll(this, 'updateOrCreateByVendorSelectorId'); }, parse: function(response){ // a JSON list of pages, which are each just a list of coords var tables = []; var selections = _(response).map(_.bind(function(page_tables, listIndex){ var pageIndex = listIndex + 1; return _(page_tables).map(_.bind(function(tableCoords){ if(tableCoords[2] * tableCoords[3] < 400){ //exclude tiny autodetected selections return null; } return { x1: tableCoords[0], y1: tableCoords[1], x2: tableCoords[0] + tableCoords[2], y2: tableCoords[1] + tableCoords[3], width: tableCoords[2], height: tableCoords[3], page: pageIndex, extraction_method: 'spreadsheet', selection_id: null }; }, this)); }, this)); return _.select(_.flatten(selections), function(i){ return i; }); } }); Tabula.Query = Backbone.Model.extend({ //has selections, data //pertains to DataView // on modal exit, destroy this.pdf_view.query // on selection end or download all button, create this.pdf_view.query // in the modal, modify and requery. initialize: function(){ // should be inited with list_of_coords _.bindAll(this, 'doQuery', 'setExtractionMethod', 'convertTo', 'convertToCSV', 'convertToTabulaExtractorScript', 'convertToBoundingBoxJSON'); }, convertTo: function(format){ if(!this.get('data')){ throw Error("You need to query for data before converting it locally."); }else{ switch(format.toLowerCase()){ // case "XML": // return this.convertToXML(); // break; case "bbox": return this.convertToBoundingBoxJSON(); case "tsv": return this.convertToCSV("\t"); case "csv": return this.convertToCSV(); case "\uD83D\uDCA9SV": return this.convertToCSV("\uD83D\uDCA9SV"); case "script": return this.convertToTabulaExtractorScript(); default: throw Error("Unknown format: " + format); } } }, convertToCSV: function(delimiter_maybe_undef){ var delimiter = typeof delimiter_maybe_undef == "undefined" ? ',' : delimiter_maybe_undef var csv = _(this.get('data')).chain().pluck('data').map(function(table){ return _(table).chain().map(function(row){ return _.map(row, function(cell){ var text = cell.text; text = text.replace("\"", "\\\""); //escape quotes text = text.indexOf(delimiter) > -1 ? "\"" + text + "\"" : text; //enquote cells containing the delimiter. return text; }).join(delimiter); }).value(); }).flatten(true).value().join("\n"); return csv; }, convertToBoundingBoxJSON: function(){ return JSON.stringify(this.get('list_of_coords'), null, 4); }, convertToTabulaExtractorScript: function(){ return _(this.get('list_of_coords')).map(function(c){ var extraction_method_switch = ""; if(c.extraction_method == "original"){ var extraction_method_switch = "--no-spreadsheet"; }else if(c.extraction_method == "spreadsheet"){ var extraction_method_switch = "--spreadsheet"; } return "tabula "+extraction_method_switch+" -a "+roundTo(c.y1, 3)+","+roundTo(c.x1, 3)+","+roundTo(c.y2, 3)+","+roundTo(c.x2, 3)+" -p "+c.page+" \"$1\""; }).join("\n"); }, doQuery: function(options) { this.query_data = { 'coords': JSON.stringify(this.get('list_of_coords')), 'new_filename': null, }; // print selection coordinates to the console // way easier FOR NOW than downloading the script/JSON console.log(_.map(this.get('list_of_coords'), function(l){ return [l.y1, l.x1, l.y2, l.x2].join(', '); }).join("\n") ); // shallow copy the selections collection // so if hte user somehow changes the selections between starting the query and it finishing, // there isn't an error var stashed_selections = new Tabula.Selections(Tabula.pdf_view.pdf_document.selections.models.slice()); this.trigger("tabula:query-start"); window.tabula_router.navigate('pdf/' + PDF_ID + '/extract'); // TODO: this should probably go in a view!! -JBM $.ajax({ type: 'POST', url: (base_uri || '/') + 'pdf/' + PDF_ID + '/data', data: this.query_data, success: _.bind(function(resp) { this.set('data', resp); // this only needs to happen on the first select, when we don't know what the extraction method is yet // (because it's set by the heuristic on the server-side). // TODO: only execute it when one of the list_of_coords has guess or undefined as its extraction_method _(resp).each(_.bind(function(resp_item, i){ var coord_set = this.get('list_of_coords')[resp_item['spec_index']]; // _(_.zip(this.get('list_of_coords'), resp)).each(function(stuff, i){ // var coord_set = stuff[0]; // var resp_item = stuff[1]; // if(!coord_set) return; // DIRTY HACK, see https://github.com/tabulapdf/tabula/issues/497 // // if one set of coords returns 2+ tables, // // then this zip won't work. if (stashed_selections.get(coord_set.selection_id)){ stashed_selections.get(coord_set.selection_id). set('extraction_method', resp_item["extraction_method"]); } coord_set["extraction_method"] = resp_item["extraction_method"]; },this)); this.trigger("tabula:query-success"); if (options !== undefined && _.isFunction(options.success)){ Tabula.pdf_view.options.success(resp); } }, this), error: _.bind(function(xhr, status, error) { console.log("error!", xhr, status); var error_text = xhr.responseText; window.raw_xhr_responseText = xhr.responseText; // for consoles, etc. if(error_text.indexOf("DOCTYPE") != -1){ // we're in Jar/Jetty/whatever land, not rackup land var error_html = $('
').html( error_text ); var summary = error_html.find('#summary').text().trim(); var meta = error_html.find('#meta').text().trim(); var info = error_html.find('#info').text().trim(); error_text = [summary, meta, info].join("
"); } var debugging_text = "Tabula API version: " + Tabula.api_version + "\nFilename: " + Tabula.pdf_view.pdf_document.get('original_filename') + "\n" + error_text this.set('error_message', debugging_text); this.trigger("tabula:query-error"); if (options !== undefined && _.isFunction(options.error)) options.error(resp); }, this), }); }, setExtractionMethod: function(extractionMethod){ _(this.get('list_of_coords')).each(function(coord_set){ coord_set['extraction_method'] = extractionMethod; }); }, getDataArray: function(){ // this.data is a list of responses (because we sent a list of coordinate sets) // $.each( _.pluck(this.model.get('data'), 'data'), function(i, rows) { // $.each(rows, function(j, row) { // tableHTML += '' + _.pluck(row, 'text').join('') + ''; // }); // }); /* via https://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery * if a PDF contains the string "