From 699f7b52787ed7ad961b6c8e4ae30e47050f3774 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 12 Mar 2015 17:23:55 +0100 Subject: [PATCH] More work on custom controls Added a lot of documentation, more stream lining, should now work completely without having to define types but offer the same/more functionality than before. Backwards compatible too. --- docs/_static/theme_overrides.css | 25 +- docs/conf.py | 5 +- docs/configuration/config_yaml.rst | 388 ++++++++++++++++++ docs/configuration/custom_controls.rst | 135 ------ docs/configuration/index.rst | 5 +- docs/configuration/logging_yaml.rst | 100 +++++ docs/configuration/yaml.rst | 151 ++++--- docs/events/index.rst | 13 +- docs/features/custom_controls.rst | 277 +++++++++++++ docs/features/index.rst | 11 + .../configuration-custom_controls-example.png | Bin 22129 -> 0 bytes .../features-custom_controls-confirm.png | Bin 0 -> 10470 bytes .../features-custom_controls-example.png | Bin 0 -> 28305 bytes docs/index.rst | 5 +- docs/sphinxext/codeblockext.py | 258 ++++++++++++ requirements-bbb.txt | 15 - requirements-dev.txt | 12 - requirements.txt | 27 +- setup.py | 89 ++-- src/octoprint/static/css/octoprint.css | 2 +- .../static/js/app/viewmodels/control.js | 53 ++- src/octoprint/static/less/octoprint.less | 6 +- src/octoprint/templates/tabs/control.jinja2 | 12 +- 23 files changed, 1288 insertions(+), 301 deletions(-) create mode 100644 docs/configuration/config_yaml.rst delete mode 100644 docs/configuration/custom_controls.rst create mode 100644 docs/configuration/logging_yaml.rst create mode 100644 docs/features/custom_controls.rst create mode 100644 docs/features/index.rst delete mode 100644 docs/images/configuration-custom_controls-example.png create mode 100644 docs/images/features-custom_controls-confirm.png create mode 100644 docs/images/features-custom_controls-example.png create mode 100644 docs/sphinxext/codeblockext.py delete mode 100644 requirements-bbb.txt delete mode 100644 requirements-dev.txt diff --git a/docs/_static/theme_overrides.css b/docs/_static/theme_overrides.css index f86e823a..476555ba 100644 --- a/docs/_static/theme_overrides.css +++ b/docs/_static/theme_overrides.css @@ -7,4 +7,27 @@ .wy-table-responsive { overflow: visible !important; -} \ No newline at end of file +} + +/* style headlink for code block captions like other headlinks */ +.code-block-caption .headerlink { + display: none; + visibility: hidden; + font-size: 14px; + font-family: inherit; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; +} + +.code-block-caption:hover .headerlink { + display: inline-block; +} + +.code-block-caption .headerlink:after { + visibility: visible; + content: "\f0c1"; + font-family: FontAwesome; + display: inline-block; +} diff --git a/docs/conf.py b/docs/conf.py index 7ff34180..32dd418a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,6 +17,7 @@ import sys, os # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../src/')) +sys.path.append(os.path.abspath('sphinxext')) import octoprint._version from datetime import date @@ -27,11 +28,11 @@ year_current = date.today().year # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.3' +needs_sphinx = '1.3' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.autodoc', 'sphinxcontrib.httpdomain', 'sphinxcontrib.napoleon'] +extensions = ['codeblockext', 'sphinx.ext.todo', 'sphinx.ext.autodoc', 'sphinxcontrib.httpdomain', 'sphinxcontrib.napoleon'] todo_include_todos = True # Add any paths that contain templates here, relative to this directory. diff --git a/docs/configuration/config_yaml.rst b/docs/configuration/config_yaml.rst new file mode 100644 index 00000000..14116796 --- /dev/null +++ b/docs/configuration/config_yaml.rst @@ -0,0 +1,388 @@ +.. _sec-configuration-config_yaml: + +config.yaml +=========== + +If not specified via the command line, the main configuration file ``config.yaml`` for OctoPrint is expected in its +settings folder, which unless defined differently via the command line is located at ``~/.octoprint`` on Linux, at +``%APPDATA%/OctoPrint`` on Windows and at ``~/Library/Application Support/OctoPrint`` on MacOS. If the file is not there, +you can just create it - it will only get created by OctoPrint once you save settings that deviate from the default +settings. + +Note that many of these settings are available from the "Settings" menu in OctoPrint itself. + +Serial +------ + +Use the following settings to configure the serial connection to the printer: + +.. code-block:: yaml + + serial: + # Use the following option to define the default serial port, defaults to unset (= AUTO) + port: /dev/ttyACM0 + + # Use the following option to define the default baudrate, defaults to unset (= AUTO) + baudrate: 115200 + + # Whether to automatically connect to the printer on server startup (if available) + autoconnect: false + + # Whether to log whole communication to serial.log (warning: might decrease performance) + log: false + + # Timeouts used for the serial connection to the printer, you might want to adjust these if you are + # experiencing connection problems + timeout: + + # Timeout for waiting for a response from the currently tested port during autodetect, in seconds. + # Defaults to 0.5 sec + detection: 0.5 + + # Timeout for waiting to establish a connection with the selected port, in seconds. + # Defaults to 2 sec + connection: 2 + + # Timeout during serial communication, in seconds. + # Defaults to 5 sec + communication: 5 + + # Use this to define additional patterns to consider for serial port listing. Must be a valid + # "glob" pattern (see http://docs.python.org/2/library/glob.html). Defaults to not set. + additionalPorts: + - /dev/myPrinterSymlink + +Server +------ + +Use the following settings to configure the server: + +.. code-block:: yaml + + server: + # Use this option to define the host to which to bind the server, defaults to "0.0.0.0" (= all interfaces) + host: 0.0.0.0 + + # Use this option to define the port to which to bind the server, defaults to 5000 + port: 5000 + + # Use this option to define an optional baseUrl (with a leading /, so absolute to your + # server's root) under which to run OctoPrint. This should only be needed if you want to run + # OctoPrint behind a reverse proxy under a different root endpoint than `/` and can't configure + # said reverse proxy to send `X-Script-Name` and `X-Scheme` HTTP headers with + # forwarded requests (see below). Defaults to an empty string and therefore the server root. + baseUrl: /octoprint + + # Use this option to define an optional URL scheme under which to run OctoPrint. + # Should only be needed for use with reverse proxies, see above. + scheme: http + + # will be automatically set to false once the first-run-wizard has been completed + firstRun: true + +.. note:: + + If you want to run OctoPrint behind a reverse proxy such as HAProxy or Nginx and use a different base URL than the + server root ``/`` you have two options to achieve this. One approach is using the configuration settings ``baseUrl`` and + ``scheme`` mentioned above in which OctoPrint will only work under the configured base URL. + + The second and better approach is to make your proxy send a couple of custom headers with each forwarded requests: + + * ``X-Script-Name``: should contain your custom baseUrl (absolute server path), e.g. ``/octoprint`` + * ``X-Scheme``: should contain your custom URL scheme to use (if different from ``http``), e.g. ``https`` + + If you use these headers OctoPrint will work both via the reverse proxy as well as when called directly. Take a look + `into OctoPrint's wiki `_ for a couple + of examples on how to configure this. + +Webcam +------ + +Use the following settings to configure webcam support: + +.. code-block:: yaml + + webcam: + # Use this option to enable display of a webcam stream in the UI, e.g. via MJPG-Streamer. + # Webcam support will be disabled if not set + stream: http://:/?action=stream + + # Use this option to enable timelapse support via snapshot, e.g. via MJPG-Streamer. + # Timelapse support will be disabled if not set + snapshot: http://:/?action=snapshot + + # Path to ffmpeg binary to use for creating timelapse recordings. + # Timelapse support will be disabled if not set + ffmpeg: /path/to/ffmpeg + + # The bitrate to use for rendering the timelapse video. This gets directly passed to ffmpeg. + bitrate: 5000k + + # Whether to include a "created with OctoPrint" watermark in the generated timelapse movies + watermark: true + + # The default timelapse settings. + timelapse: + + # The timelapse type. Can be either "off", "zchange" or "timed". Defaults to "off" + type: timed + + # Additional options depending on the timelapse type. Currently only the "timed" timelapse takes + # the interval which to leave between images as option "interval", given in seconds. This example + # therefore configures a "Timed" timelapse with an interval of 2s. Defaults to empty. + options: + interval: 2 + +Feature +------- + +Use the following settings to enable or disable OctoPrint features: + +.. code-block:: yaml + + feature: + # Whether to enable the gcode viewer in the UI or not + gCodeVisualizer: true + + # Whether to enable the temperature graph in the UI or not + temperatureGraph: true + + # Specifies whether OctoPrint should wait for the start response from the printer before trying to send commands + # during connect. + waitForStartOnConnect: false + + # Specifies whether OctoPrint should send linenumber + checksum with every command. Needed for + # successful communication with Repetier firmware + alwaysSendChecksum: false + + # Whether to ignore the first ok after a resend response. Needed for successful communication with + # Repetier firmware + swallowOkAfterResend: false + + # Specifies whether support for SD printing and file management should be enabled + sdSupport: true + +Folder +------ + +Use the following settings to set custom paths for folders used by OctoPrint: + +.. code-block:: yaml + + folder: + # Absolute path where to store gcode uploads. Defaults to the uploads folder in the OctoPrint settings folder + uploads: /path/to/upload/folder + + # Absolute path where to store finished timelapse recordings. Defaults to the timelapse folder in the OctoPrint + # settings dir + timelapse: /path/to/timelapse/folder + + # Absolute path where to store temporary timelapse files. Defaults to the timelapse/tmp folder in the OctoPrint + # settings dir + timelapse_tmp: /path/to/timelapse/tmp/folder + + # Absolute path where to store log files. Defaults to the logs folder in the OctoPrint settings dir + logs: /path/to/logs/folder + + # Absolute path to the virtual printer's simulated SD card. Only useful for development, just ignore + # it otherwise + virtualSd: /path/to/virtualSd/folder + + # Absolute path to a folder being watched for new files which then get automatically + # added to OctoPrint (and deleted from that folder). Can e.g. be used to define a folder which + # can then be mounted from remote machines and used as local folder for quickly adding downloaded + # and/or sliced objects to print in the future. + watched: /path/to/watched/folder + +Temperature +----------- + +Use the following settings to configure temperature profiles which will be displayed in the temperature tab: + +.. code-block:: yaml + + temperature: + profiles: + - name: ABS + extruder: 210 + bed: 100 + - name: PLA + extruder: 180 + bed: 60 + +Appearance +---------- + +Use the following settings to tweak OctoPrint's appearance a bit to better distinguish multiple instances/printers +appearance: + +.. code-block:: yaml + + appearance: + # Use this to give your printer a name. It will be displayed in the title bar (as " [OctoPrint]") and in the + # navigation bar (as "OctoPrint: ") + name: My Printer Model + + # Use this to color the navigation bar. Supported colors are red, orange, yellow, green, blue, violet and default. + color: blue + +Controls +-------- + +Use the ``controls`` section to add :ref:`custom controls ` to the "Controls" tab within +OctoPrint. + +.. code-block:: yaml + + controls: + - name: Fan + layout: horizontal + children: + - name: Enable Fan + type: parametric_command + command: M106 S%(speed)s + input: + - name: Speed (0-255) + parameter: speed + default: 255 + - name: Disable Fan + type: command + command: M107 + +System +------ + +Use the following settings to add custom system commands to the "System" dropdown within OctoPrint's top bar. + +Commands consist of a name, an action identifier, the commandline to execute and an optional confirmation message to +display before actually executing the command (should be set to False if a confirmation dialog is not desired). + +The following example defines a command for shutting down the system under Linux. It assumes that the user under which +OctoPrint is running is allowed to do this without password entry: + +.. code-block:: yaml + + system: + actions: + - name: Shutdown + action: shutdown + command: sudo shutdown -h now + confirm: You are about to shutdown the system. + +Access Control +-------------- + +Use the following settings to enable access control: + +.. code-block:: yaml + + accessControl: + # whether to enable access control or not. Defaults to true + enabled: true + + # The user manager implementation to use for accessing user information. Currently only a filebased + # user manager is implemented which stores configured accounts in a YAML file (Default: users.yaml + # in the default configuration folder, see below) + userManager: octoprint.users.FilebasedUserManager + + # The YAML user file to use. If left out defaults to users.yaml in the default configuration folder. + userFile: /path/to/users.yaml + + # If set to true, will automatically log on clients originating from any of the networks defined in + # "localNetworks" as the user defined in "autologinAs". Defaults to false. + autologinLocal: true + + # The name of the user to automatically log on clients originating from "localNetworks" as. Must + # be the name of one of your configured users. + autologinAs: someUser + + # A list of networks or IPs for which an automatic logon as the user defined in "autologinAs" will + # take place. If available OctoPrint will evaluate the "X-Forwarded-For" HTTP header for determining + # the client's IP address (see https://code.google.com/p/haproxy-docs/wiki/forwardfor on how to + # configure the sending of this header in HAProxy). Defaults to 127.0.0.0/8 (so basically anything + # originating from localhost). + localNetworks: + - 127.0.0.0/8 + - 192.168.1.0/24 + +Events +------ + +Use the following settings to add shell/gcode commands to be executed on certain :ref:`events `: + +.. code-block:: yaml + + events: + subscriptions: + # example event consumer that prints a message to the system log if the printer is disconnected + - event: Disconnected + command: "logger 'Printer got disconnected'" + type: system + + # example event consumer that queries printer information from the firmware, prints a "Connected" + # message to the LCD and homes the print head upon established printer connection, disabled though + - event: Connected + command: M115,M117 printer connected!,G28 + type: gcode + enabled: False + +Terminal Filters +---------------- + +Use the following settings to define a set of terminal filters to display in the terminal tab for filtering certain +lines from the display terminal log. + +Use `Javascript regular expressions `_: + +.. code-block:: yaml + + # A list of filters to display in the terminal tab. Defaults to the filters shown below + terminalFilters: + - name: Suppress M105 requests/responses + regex: '(Send: M105)|(Recv: ok T:)' + - name: Suppress M27 requests/responses + regex: '(Send: M27)|(Recv: SD printing byte)' + +API +--- + +Settings for the REST API: + +.. code-block:: yaml + + api: + # whether to enable the API + enabled: True + + # current API key needed for accessing the API + apikey: ... + +Development settings +-------------------- + +The following settings are only relevant to you if you want to do OctoPrint development: + +.. code-block:: yaml + + # Settings only relevant for development + devel: + + # Settings for the virtual printer + virtualPrinter: + + # Whether to enable the virtual printer and include it in the list of available serial connections. + # Defaults to false. + enabled: true + + # Whether to send an additional "ok" after a resend request (like Repetier) + okAfterResend: false + + # Whether to force checksums and line number in the communication (like Repetier), if set to true + # printer will only accept commands that come with linenumber and checksum and throw an error for + # lines that don't. Defaults to false + forceChecksum: false + + # Whether to send "ok" responses with the line number that gets acknowledged by the "ok". Defaults + # to false. + okWithLinenumber: false + diff --git a/docs/configuration/custom_controls.rst b/docs/configuration/custom_controls.rst deleted file mode 100644 index 369255cd..00000000 --- a/docs/configuration/custom_controls.rst +++ /dev/null @@ -1,135 +0,0 @@ -.. _sec-configuration-custom_controls: - -Custom Controls -=============== - -OctoPrint allows you to add custom controls to the "Control" tab of its interface. Control types reach from simple -buttons which trigger sending of one or more lines of GCODE to the printer over more complex controls allowing -parameterization of these commands with values entered by the user to full blown GCODE script templates backed by -`Jinja2 `_. - -.. note:: - - At the current time, the configuration of custom controls is only possible through manually editing OctoPrint's - ``config.yaml`` file. - - To make sure that your ``config.yaml`` stays valid when adding custom controls, don't hesitate to take a look at the - :ref:`YAML Primer `. - -.. _sec-configuration-custom_controls-configyaml: - -config.yaml ------------ - -Custom controls are configured within ``config.yaml`` in a ``controls`` section which basically represents a hierarchical -structure of all configured custom controls of various types. - -The following example defines a control for enabling the cooling fan with a variable speed defined by the user -(default 255 and selectable through a slider UI element) and a control for disabling the fan, all within a section named -"Fan", two example controls with multiple commands in a section "Example for multiple commands" and a command with printer -feedback evaluation for the result of the M114 "Get Position" gcode inside a section named "Reporting". - -.. sourcecode:: yaml - - controls: - - name: Fan - type: section - children: - - name: Enable Fan - type: parametric_command - command: M106 S%(speed)s - input: - - name: Speed (0-255) - parameter: speed - default: 255 - slider: - min: 0 - max: 255 - - name: Disable Fan - type: command - command: M107 - - name: Example for multiple commands - type: section - children: - - name: Move X (static) - type: commands - commands: - - G91 - - G1 X10 F3000 - - G90 - - name: Move X (parametric) - type: parametric_commands - commands: - - G91 - - G1 X%(distance)s F%(speed)s - - G90 - input: - - default: 10 - name: Distance - parameter: distance - - default: 3000 - name: Speed - parameter: speed - - name: Reporting - type: section - children: - - command: M114 - name: Get Position - type: feedback_command - regex: "X:([0-9.]+) Y:([0-9.]+) Z:([0-9.]+) E:([0-9.]+)" - template: "Position: X={0}, Y={1}, Z={2}, E={3}" - -Adding this to ``config.yaml``, restarting the OctoPrint server and switching to the "Control" tab within its -interface yields the following visual representation: - -.. _fig-configuration-custom_controls-example: -.. figure:: ../images/configuration-custom_controls-example.png - :align: center - :alt: The rendered output created through the example configuration - -As you can see there are quite a number of different custom controls already in this small example, each with their own -attributes: :ref:`sections `, :ref:`commands `, -:ref:`parametric commands ` and -:ref:`feedback commands `. Two attributes are common for all -of the types: ``name`` and ``type``. - -.. _sec-configuration-custom_controls-types: - -Types ------ - -.. _sec-configuration-custom_controls-types-sections: - -Sections -........ - -.. _sec-configuration-custom_controls-types-rows: - -Rows -.... - -.. _sec-configuration-custom_controls-types-section_rows: - -Section rows -............ - -.. _sec-configuration-custom_controls-types-commands: - -Commands -........ - -.. _sec-configuration-custom_controls-types-parametric_command: - -Parametric commands -................... - -.. _sec-configuration-custom_controls-types-script: - -Scripts -....... - -.. _sec-configuration-custom_controls-types-feedback_command: - -Feedback commands -................. - diff --git a/docs/configuration/index.rst b/docs/configuration/index.rst index 7a078cef..8348d8e1 100644 --- a/docs/configuration/index.rst +++ b/docs/configuration/index.rst @@ -7,5 +7,6 @@ Configuration .. toctree:: :maxdepth: 2 - custom_controls.rst - yaml.rst \ No newline at end of file + yaml.rst + config_yaml.rst + logging_yaml.rst diff --git a/docs/configuration/logging_yaml.rst b/docs/configuration/logging_yaml.rst new file mode 100644 index 00000000..daf8b462 --- /dev/null +++ b/docs/configuration/logging_yaml.rst @@ -0,0 +1,100 @@ +.. _sec-configuration-logging_yaml: + +logging.yaml +============ + +The logging configuration file ``logging.yaml`` for OctoPrint is expected in its settings folder, which unless defined +differently on the command line is located at ``~/.octoprint`` on Linux, at ``%APPDATA%/OctoPrint`` on Windows and at +``~/Library/Application Support/OctoPrint`` on MacOS. + +You can use it to change the log levels of the individual components within OctoPrint, which might be necessary to help +in debugging issues you are experiencing, or to change the configuration of the logging handlers themselves, e.g. in +order to change size after which to rollover the ``serial.log``. + +Changing log levels +------------------- + +If you need to change the default logging level within OctoPrint, create the file with a text editor of your choice +(it's usually not there). The general format is this:: + + logger: + : + level: + +with ```` being the internal OctoPrint component for which to change the loglevel, and ```` being the +new log level to set. An example for increasing the log level of the events and the file management components to +``DEBUG`` (the highest amount of logging) would be this ``logging.yaml``: + +.. code-block:: yaml + + logger: + octoprint.events: + level: DEBUG + octoprint.filemanager: + level: DEBUG + +A list of important components for which an increase in logging might be interesting follows: + + * ``octoprint.events``: the event sub system + * ``octoprint.filemanager``: the file management layer + * ``octoprint.plugin``: the plugin sub system + * ``octoprint.plugins.``: the plugin ````, e.g. ``octoprint.plugins.discovery`` to change the log level of + the `Discovery plugin `_ or ``octoprint.plugins.cura`` + to change the log level of the `Cura plugin `_. + * ``octoprint.slicing``: the slicing sub system + +This list will be expanded when deemed necessary. + +Changing logging handlers +------------------------- + +You can also change the configuration of the logging handlers themselves, e.g. in order to make the ``serial.log`` larger +for debugging long running communications or to change the behaviour of the ``octoprint.log``. + +You can find the default configurations of the ``file`` handler used for the ``octoprint.log``, the ``serialFile`` handler +used for the ``serial.log`` and the ``console`` handler used for the output to stdout in YAML format below: + +.. code-block:: yaml + + handlers: + # stdout + console: + class: logging.StreamHandler + level: DEBUG + formatter: simple + stream: ext://sys.stdout + + # octoprint.log + file: + class: logging.handlers.TimedRotatingFileHandler + level: DEBUG + formatter: simple + when: D + backupCount: 1 + filename: /path/to/octoprints/logs/octoprint.log + + # serial.log + serialFile: + class: logging.handlers.RotatingFileHandler + level: DEBUG + formatter: simple + maxBytes: 2097152 # 2 * 1024 * 1024 = 2 MB in bytes + filename: /path/to/octoprints/logs/serial.log + +You can find more information on the used logging handlers in the +`Python documentation on logging handlers `_. + +Changing logging formatters +--------------------------- + +The logging formatters can be defined via ``logging.yaml`` as well. The ``simple`` formatter as referenced above is +expressed in YAML as follows: + +.. code-block:: yaml + + formatters: + simple: + format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + +The possible keys for the logging format can be found in the +`Python documentation on LogRecord attributes `_. \ No newline at end of file diff --git a/docs/configuration/yaml.rst b/docs/configuration/yaml.rst index 4fc37ef7..3c669656 100644 --- a/docs/configuration/yaml.rst +++ b/docs/configuration/yaml.rst @@ -17,11 +17,11 @@ Basic Rules First of all some basic things to know about working with YAML files: - * Never use tabs outside of quoted strings, especially not for indentation. The tab characters is illegal within + * Never use tabs outside of quoted strings, especially not for indentation. The tab character is illegal within YAML files. * Whitespace and indentation matters and plays an important part in structuring the data, so take special care to stay consistent here. - * YAML's comments start with a `#` and go until the end of the line. + * YAML's comments start with a ``#`` and go until the end of the line. .. _sec-configuration-yaml-types: @@ -29,7 +29,7 @@ Interesting data types ---------------------- You will probably only come across the three most basic types of data within OctoPrint's YAML files: scalars -(such as strings, integers, ...), lists and associated arrays (aka key-value-paris, aka maps, aka dictionaries). +(such as strings, integers, ...), lists and associated arrays (aka key-value-pairs, aka maps, aka dictionaries). .. _sec-configuration-yaml-types-scalar: @@ -53,68 +53,80 @@ Quoted strings can also span across multiple lines, just indent the following li completely empty line in order for force a line break, the data will not be actually wrapped across multiple lines just because you spread its representation across multiple lines. -.. list-table:: +.. _sec-configuration-yaml-types-scalar-int: - - * **Data type** - * **Examples** - - * int - * .. sourcecode:: yaml +int +''' - 23 +.. code-block:: yaml - 42 + 23 - - * float - * .. sourcecode:: yaml + 42 - 23.5 +.. _sec-configuration-yaml-types-scalar-float: - 100.0 +float +''''' - - * boolean - * .. sourcecode:: yaml +.. code-block:: yaml - true + 23.5 - false + 100.0 - Yes +.. _sec-configuration-yaml-types-scalar-boolean: - No +boolean +''''''' - yes +.. code-block:: yaml - no + true - - * string - * .. sourcecode:: yaml + false - a string + Yes - "some quoted string with a : colon and a { bracket and a quote \" and a backslash \\ - phew" + No - 'some single quoted string with a single quote '' and a backslash \ - yay' + yes - "and a multiline string - just because we can we'll make it span - across not two but four YAML lines! + no - Including this paragraph. But in fact it will only be two lines :)" +.. _sec-configuration-yaml-types-scalar-string: - "23" +string +'''''' - "42.3" +.. code-block:: yaml - "Yes" + a string - "No" + "some quoted string with a : colon and a { bracket and a quote \" and a backslash \\ - phew" - "true" + 'some single quoted string with a single quote '' and a backslash \ - yay' - "false" + "and a multiline string - just because we can we'll make it span + across not two but four YAML lines! - yes and no + Including this paragraph. But in fact it will only be two lines :)" - true or false + "23" + + "42.3" + + "Yes" + + "No" + + "true" + + "false" + + yes and no + + true or false .. _sec-configuration-yaml-types-lists: @@ -124,7 +136,7 @@ Lists Lists allow to "collect" a number of similar things into one data structure. They are created by prefixing one or more consecutive lines with a ``-``: -.. sourcecode:: yaml +.. code-block:: yaml - item 1 - 23.42 @@ -151,9 +163,50 @@ being separated through a colon ``:``: Examples -------- -Based on the three types explained above, quite complex data structures are possible: +Based on the three types explained above, quite complex data structures are possible (whitespace made visible to +help track indentation): -.. sourcecode:: yaml +.. code-block-ext:: yaml + :whitespace: + + general: + some_setting: some_value + a_list: + - item 1 + - 23.42 + - 57 + - true + some_flag: true + quoted_string: "This string is quoted because {we have this here} and also > this and : that" + specific: + setting1: value1 + setting2: + subsetting21: value11 + subsetting22: + - subsubsetting221 + - subsubsetting222 + - subsubsetting223 + the_end: yes + +In this example we have a dictionary on the top most "layer" which has three keys, ``general``, ``specific`` and +``the_end``. + +``general`` in turn is a dictionary with the keys ``some_setting`` (a string), ``a_list`` (a list with four items, +a string, a float, an int and a boolean), ``some_flag`` (a boolean) and ``quoted_string`` (a -- you guessed it -- string). + +``specific`` is also a dictionary, with keys ``setting1`` (a string) and ``setting2``, a dictionary with two keys, one +a string and the other again a list. + +Finally, ``the_end`` is just a boolean, since an unquoted ``yes`` evaluates as a boolean value as we saw in the +:ref:`section about boolean scalars above `. + +Don't get confused by the list "dividing" one part of the dictionary under ``general`` from the other -- your mind is +just playing a trick on you due to the list's dashes ``-`` being on the same levels as the dictionary keys. You could +also just add two more spaces to your identation and write that part like this, which makes the structure a bit +clearer (whitespace again made visible to help track indentation): + +.. code-block-ext:: yaml + :whitespace: general: some_setting: some_value @@ -163,13 +216,9 @@ Based on the three types explained above, quite complex data structures are poss - 57 - true some_flag: true - quoted_string: "This string is quoted because {we have this here} and also > this and : that" - specific: - setting1: value1 - setting2: value2 - subsetting21: value11 - subsetting22: - - subsubsetting221 - - subsubsetting222 - - subsubsetting223 - the_end: yes + # ... + +Just make sure you follow a consistent way of indenting your files -- YAML is not as strict as Python when it comes to +differing identation variants within the same file (as long as it's still valid), but consistency will help you as +a lot as a human. Ideally you'll use a text editor which highlights white space characters for you (most editors can +be configured this way), this will help tremendously when editing whitespace sensitive syntax such as YAML. \ No newline at end of file diff --git a/docs/events/index.rst b/docs/events/index.rst index bbc45947..d1973c5e 100644 --- a/docs/events/index.rst +++ b/docs/events/index.rst @@ -6,11 +6,14 @@ Events .. contents:: -With release of OctoPrint 1.1.0, the payload data has been harmonized, it is now a key-value-map for all events. -Additionally, the format of the placeholders in both system command and gcode command triggers has been changed to -accommodate for this new format. Last but not least, the way of specifying event hooks has changed, OctoPrint no longer -separates hooks into two sections (gcodeCommandTrigger and systemCommandTrigger) but instead event hooks are now typed -to indicate what to do with the command contained. + +.. note:: + + With release of OctoPrint 1.1.0, the payload data has been harmonized, it is now a key-value-map for all events. + Additionally, the format of the placeholders in both system command and gcode command triggers has been changed to + accommodate for this new format. Last but not least, the way of specifying event hooks has changed, OctoPrint no longer + separates hooks into two sections (gcodeCommandTrigger and systemCommandTrigger) but instead event hooks are now typed + to indicate what to do with the command contained. .. _sec-events-configuration: diff --git a/docs/features/custom_controls.rst b/docs/features/custom_controls.rst new file mode 100644 index 00000000..31235233 --- /dev/null +++ b/docs/features/custom_controls.rst @@ -0,0 +1,277 @@ +.. _sec-features-custom_controls: + +Custom Controls +=============== + +.. contents:: + +OctoPrint allows you to add custom controls to the "Control" tab of its interface. Control types reach from simple +buttons which trigger sending of one or more lines of GCODE to the printer over more complex controls allowing +parameterization of these commands with values entered by the user to full blown GCODE script templates backed by +`Jinja2 `_. + +Custom controls are configured within :ref:`config.yaml ` in a ``controls`` section which +basically represents a hierarchical structure of all configured custom controls of various types. + +.. note:: + + To make sure that your ``config.yaml`` stays valid when adding custom controls, don't hesitate to take a look at the + :ref:`YAML Primer `. + +The following example defines a control for enabling the cooling fan with a variable speed defined by the user +(default 255 and selectable through a slider UI element) and a control for disabling the fan, all within a section named +"Fan", two example controls with multiple commands in a section "Example for multiple commands", a command with printer +feedback evaluation for the result of the M114 "Get Position" gcode inside a section named "Reporting" and finally +a GCODE script including user input. + +.. code-block-ext:: yaml + + controls: + - name: Fan + layout: horizontal + children: + - name: Enable Fan + command: M106 S%(speed)s + input: + - name: Speed (0-255) + parameter: speed + default: 255 + slider: + min: 0 + max: 255 + - name: Disable Fan + command: M107 + - name: Example for multiple commands + children: + - name: Move X (static) + confirm: You are about to move the X axis right by 10mm with 3000mm/s. + commands: + - G91 + - G1 X10 F3000 + - G90 + - name: Move X (parametric) + commands: + - G91 + - G1 X%(distance)s F%(speed)s + - G90 + input: + - default: 10 + name: Distance + parameter: distance + - default: 3000 + name: Speed + parameter: speed + - name: Reporting + children: + - name: Get Position + command: M114 + regex: "X:([0-9.]+) Y:([0-9.]+) Z:([0-9.]+) E:([0-9.]+)" + template: "Position: X={0}, Y={1}, Z={2}, E={3}" + - name: Fun stuff + children: + - name: Dance + script: custom/dance.gco + input: + - name: Go arounds + parameter: repetitions + slider: + max: 10 + min: 1 + step: 1 + +Adding this to ``config.yaml``, restarting the OctoPrint server and switching to the "Control" tab within its +interface yields the following visual representation: + +.. _fig-configuration-custom_controls-example: +.. figure:: ../images/features-custom_controls-example.png + :align: center + :alt: The rendered output created through the example configuration + +As you can see you have two basic types of control definitions here: controls that actually do something (providing a +button that sends one or more commands to the printer when clicked, displaying output received from the printer) and +controls that just serve as *container* for other controls, the latter being identified by having a ``children`` +attribute wrapping more controls. + +.. _sec-features-custom_controls-types: + +Types +----- + +Let's take a closer look at the possible attributes that are available for both basic types. + +.. _sec-features-custom_controls-types-containers: + +Containers +.......... + +.. list-table:: + :widths: 25 75 + + * - **Attribute** + - **Description** + * - ``children`` + - A list of children controls or containers contained within this container + * - ``name`` + - (Optional) A name to display above the container, basically a section header + * - ``layout`` + - (Optional) The layout to use for laying out the contained children, either from top to bottom (``vertical``) or + from left to right (``horizontal``). Defaults to a ``vertical`` layout. + +.. _sec-features-custom_controls-types-controls: + +Controls +........ + +.. list-table:: + :widths: 25 75 + + * - **Attribute** + - **Description** + * - ``name`` + - The name of the control, will be displayed either on the button if it's a control sending a command or as a label + for controls which only display output. + * - ``command`` + - (Optional) A single GCODE command to send to the printer. Will be rendered as a button which sends the command to + the printer upon click. The button text will be the value of the ``name`` attribute. Mutually exclusive with + ``commands`` and ``script``. The rendered button be disabled if the printer is currently offline or printing or + alternatively if the requirements defined via the ``enabled`` attribute are not met. + * - ``commands`` + - (Optional) A list of GCODE commands to send to the printer. Will be rendered as a button which sends the commands + to the printer upon click. The button text will be the value of the ``name`` attribute. Mutually exclusive with + ``command`` and ``script``. The rendered button will be disabled if the printer is currently offline or printing + or alternatively if the requirements defined via the ``enabled`` attribute are not met. + * - ``script`` + - (Optional) The name of a full blown :ref:`GCODE script ` to send to the printer. + Will be rendered as a button which sends the script to the printer upon click. The button text will be the value + of the ``name`` attribute. Mutually exclusive with ``command`` and ``commands``. The rendered button will be + disabled if the printer is currently offline or printing or alternatively if the requirements defined via the + ``enabled`` attribute are not met. + + Values of input parameters will be available in the template context under the ``parameter`` variable (e.g. + an input parameter ``speed`` will be available in the script template as ``parameter.speed``). On top of that all + other variables defined in the :ref:`GCODE template context ` will be available. + + :ref:`See below for an example `. + * - ``javascript`` + - (Optional) A JavaScript snippet to be executed when the button rendered for ``command`` or ``commands`` is + clicked. This allows to override the direct sending of the command or commands to the printer with more + sophisticated behaviour. The JavaScript snippet is ``eval``'d and processed in a context where the control + it is part of is provided as local variable ``data`` and the ``ControlViewModel`` is available as ``self``. + * - ``enabled`` + - (Optional) A JavaScript snippet returning either ``true`` or ``false`` determining whether the control + should be enabled or not. This allow to override the default logic for this (disabled if printer is offline + or currently printing). The JavaScript snippet is ``eval``'d and processed in a context where the control + it is part of is provided as local variable ``data`` and the ``ControlViewModel`` is available as ``self``. + * - ``input`` + - (Optional) A list of definitions of input parameters for a ``command`` or ``commands``, to be rendered as + additional input fields. ``command``/``commands`` may contain placeholders to be replaced by the values obtained + from the user for the defined input fields: + + .. code-block-ext:: yaml + + name: Enable Fan + command: M106 S%(speed)s + input: + - name: Speed (0-255) + parameter: speed + default: 255 + slider: + min: 0 + max: 255 + + In OctoPrint's default UI input fields are always rendered left to right (inline). + * - ``input.name`` + - Name to display for the input field. + * - ``input.parameter`` + - Internal parameter name for the input field, used as a placeholder in ``command``/``commands``. + * - ``input.default`` + - Default value for the input field. + * - ``input.slider`` + - (Optional) If this attribute is included, instead of an input field a slider control will + be rendered. If you don't want to define any of ``min``, ``max`` or ``step``, write ``slider: {}`` to render + a slider based on default values. + * - ``input.slider.min`` + - (Optional) Minimum value of the slider, defaults to 0. + * - ``input.slider.max`` + - (Optional) Maximum value of the slider, defaults to 255. + * - ``input.slider.step`` + - (Optional) Step size per slider "tick", defaults to 1. + * - ``regex`` + - (Optional) A `regular expression `_ to + match against lines received from the printer to retrieve information from it (e.g. specific output). Together + with ``template`` this allows rendition of received data from the printer within the UI. + * - ``template`` + - (Optional) A template to use for rendering the match of ``regex``. May contain placeholders in + `Python Format String Syntax `_ for either named + groups within the regex (e.g. ``Temperature: {temperature}`` for a regex ``T:\s*(?P\d+(\.\d*)``) + or positional groups within the regex (e.g. ``Position: X={0}, Y={1}, Z={2}, E={3}`` for a regex + ``X:([0-9.]+) Y:([0-9.]+) Z:([0-9.]+) E:([0-9.]+)``). + * - ``confirm`` + - (Optional) A text to display to the user to confirm his button press. Can be used with sensitive custom controls + like changing EEPROM values in order to prevent accidental clicks. The text will be displayed in a confirmation + dialog like the following: + + .. _fig-configuration-custom_controls-confirm: + .. figure:: ../images/features-custom_controls-confirm.png + :align: center + :alt: An example confirmation dialog + +.. _sec-features-custom_controls-examples: + +Examples +-------- + +.. _sec-features-custom_controls-examples-gcode_script: + +Parameterized GCODE Script +.......................... + +.. code-block-ext:: yaml + :caption: Control definition in ~/.octoprint/config.yaml + :name: code-features-custom_controls-example-gcode_script-config_yaml + + name: Dance + script: custom/dance.gco + input: + - default: 5 + name: Go arounds + parameter: repetitions + slider: + max: 10 + min: 1 + step: 1 + +.. code-block-ext:: jinja + :caption: ~/.octoprint/scripts/gcode/custom/dance.gco + :name: code-features-custom_controls-example-gcode_script-dance_gco + + {% set center_x = printer_profile.volume.width / 2 %} + {% set center_y = printer_profile.volume.depth / 2 %} + {% set speed_x = printer_profile.axes.x.speed %} + {% set speed_y = printer_profile.axes.y.speed %} + {% set speed_z = printer_profile.axes.z.speed %} + M117 run {{ script.name }} + G4 P500 + G1 Z10 + G1 X{{ center_x }} Y{{ center_y }} F{{ speed_x }} + M117 let's dance! + G91 + G1 X-1 Y-1 F{{ speed_x }} + {% for n in range(parameters.repetitions) %} + M117 and {{ n + 1 }} + {% if n % 2 == 0 %} + G1 Z1 F{{ speed_z }} + G1 Z-2 F{{ speed_z }} + G1 Z1 F{{ speed_z }} + {% endif %} + G1 X2 F{{ speed_x }} + G1 Y2 F{{ speed_y }} + G1 X-2 F{{ speed_x }} + G1 Y-2 F{{ speed_y }} + {% endfor %} + G90 + G1 X{{ center_x }} Y{{ center_y }} F{{ speed_x }} + G28 X0 Y0 + +Note the usage of the ``parameters.repetitions`` template variable in the GCODE script template, which will contain +the value selected by the user for the "Go arounds" slider. \ No newline at end of file diff --git a/docs/features/index.rst b/docs/features/index.rst new file mode 100644 index 00000000..83088990 --- /dev/null +++ b/docs/features/index.rst @@ -0,0 +1,11 @@ +.. _section-features: + +******** +Features +******** + +.. toctree:: + :maxdepth: 2 + + custom_controls.rst + gcode_scripts.rst diff --git a/docs/images/configuration-custom_controls-example.png b/docs/images/configuration-custom_controls-example.png deleted file mode 100644 index eab2a58b2792bb1f99299578d7bb98d7675d36e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22129 zcmd43cU+U(w)cx=St%-t(se1lNs$N$C@8%t(o1LoLzNB*5ETSP1*Ao~NQp}Cod~Fu z&_fR-QUXLus0omE!&+zW^X~WVd(XY^dp`Gb|KP(X&%-nG%rVEDWBk5zOkSH9X|tW- zIm5!j!ltWp{}BtzQ4kBuk&;sIPP}O@E!|GMf_Q+ z;~&h=r=RLr`LnRFcO3p4>Gb*R!n}AP;DKd;sgG+wu%jP{McWSq^7en?6JT$4ius7y zvhMwRk3;O&W{9SI7TLs5#(BWH`Xl4a3f@IseGaY}HqGf)>(G-`vTK8i$1D8KUH2NC z2_F4b_=kKwR8w9ySaQHlK{irBUc9JGPgOA}{#}z-c|>y5%XfAjr$k!Bu2? zLYQjBeBOlX@5aWsdrn04GEGn(@%L9vESRLefBpSgz&bef1oSm}QVgnm(j`QBX?)Y= z0zVc%;9~yhwLN%-5VFggUf_QdoO+!3aGv1tB>$C~kKw1|%vg-n|fI;8rPIyibll9G7p3HM+Ty z64&jlVP(g?dAIR5l*->6j#O=p;TaHVk!m-5>y8(8-&tNvmv4H0_v7CW)q>$N{(0Ez zveO%8rN^^XwGIal(=Ci$_F2?p*K_la6l~|4Y(SVo=JVuKRVD2X{$N3r-#HxI2_xp< zF$Ziy=fB4l{`MXdQ&D{c`r?_F8o4H-$!0y)L#F?Y?)Janp{GFKxN4i5B~49D{Wj+w z=n5w#8;Uo!1U9XZPCj!#-}6jL?^s)bKHMcJ$Xq}@LQV{aRw4$+SxipnvQE6HhHDYM4(Jr(%qJqZH{ImT`pIw(mXveM7wC#U!pkZ; zP&Pqh`NxIl#8yh&R_57U*1I*QKzHv;NlJF@u8iZ0%3A%1`oo{f0yB-6z6&~#y4$lY z#T>xVKa-D~4_FzK0z}z01sSg6kU8pYD<1ra_{KqH{Des%Al)?E=UVcS&tu9OR$7Ug zcEgS6_m+~v716E)zALGZ$8xBA%z1cWMdw3m$)A90$Dk*L@W_;%S39-q7q!(Rt4yt% zqHi?(KKj<+(Fql5=#D>!@SAZZez>Z#lqGZSzyA3ZjS#}hUhU3g1ZC}M;3U5ux?hO=lAM)9lB~Y%<uH@_=L?5F#GXrLvy8Ma1&XF_}MGKdafic;JfJ@sQWEz zu+rS|VW$73(D6g37;YAo26%GTzOiz2JuhB4kQ{O z@G#rV_l$|)hxW@#GBP{D_?N)6_M3?vvzrp$SJB}JRcDCY_;`V)irtF)FX>CHAPzw_ z+m4OGX0-j*NzIQtLPd7{?j7612$V8#WoIShPj zf&)aTude-h7S+Y7ukCp^k#1w*ZW6Ti8dc2*dilCzZdIH;yI~0XY1iF>-&QEiJbnG; z54}L~reI=r<{fn@8L9>6PkNCOfuUY_^X+OmElZc22vW@G1C|y)u3lftfk|@++}R*E zc1Fvsd7+=0tZmG8@cIo$rPI&GZ?_Gw*MtOq1=>$+4CUqTWaLcJT}lfHMQj!xNRn+R z^A1*v^)!g(tC_PXO6Svc;l7jea_@=a68JyrEUQkddIKJ7X+bl75O_AB1;eh~Y!6x< zukVC$JS-smP&IELLPCMKViqBWhO%uT@YtMY#6dUAfgQ#Y9nRQ?>T;06_NKBizcYew56OC@b%x{Y+Bg zXN*=jaN@$`&=K%0i6D>1>E48;VD^l$5hLP5$n5TR;fEwOp(zkfsbS{_+>g9&N50>h z`f1z1$cRhz7B*Ur?SzLI3N=1slJ{KHvoRHq_xFC{Hx-Y%oR)bfBCM}>UT6NjzJ1mt zdEv5A(oQ^R8Y`xvI+mKiEk6@oYH5mmo3`)YP#s3qO1ga#3!nTJP{w9)13PwgtrMB> z)+%+3pCB6u)pF_gG4{oX*C8KK#3Nd7acOWrb1#|Kg5~TBrSTYcnfSzvZ=>&A<@9bm zbrxVxObcRZAj1eUiW38^-F%TO7A-_aA#oGQ?s>GOVO2z{_TkSNNSGTj6QsOd%Lo}zP|9&_HuI@;wQ$W5WRcBtwxjW z7M|Fxe8bI9bxn78a9DlOj(x=8gW9CGhT$~Zt;XVEtXMFFqOu;~6Vcgn2fT8p5o&E8 zUxWI>t)eO%(=UY@-m@95r+mm42yJn-W(-B1C%ooQAiK5<0PQH41z=g|?pF`s{=nth z8FStXJuHtsXt~8*)vPr?srpfPjkIwaGeRLXy-=h>BXyuf(u$|2$F6m!-2{A7vNiof z5+Ni;;lpkU5`_DDai_Tq_Ey zw-!Y!dx+`l%X=Fq+0(0V0@V+W#YVI8TJLCug_q&AnxzEY1C-vpsgesNC9}5d7X}b9 zQig1cZl7r`S9hxQsnG!B*f>_Kr2)t0^xP!K4!**mUV_iaDG*8|EPHBjwKHQy)2*ZG zIO{WqQONx)h{rYa2q&+3`juDR(q#5PnP->&Nc)9Hy*^U)7P}Q6@%eW6JGe{-q^I)w z@THX$DqJ>2t@M+^=ae2p{pPBB=^SyztS;-dVhyXG?+rwx>Y+>C{T9Q}L_%j_01=wH z{7c7xn6k{20h#b?RaI5%Rb4wjY3?xx&6P4ps+>YH_=%0am2IXkG+iNKxd6bc=lOB- z_p+*m{gYv`vYMc^LCectw=LHsY|N;X_Pn63T%c)T97XlvdSw7TNJ+LT8CZ5AS8baz zXIRzyYpVsHogAQhcjS{-k4Ok*(4MQuO*7F3Lr{5>-JSkHEWPF=5|Lh9+<;w+T zQ(P>Ysci8mq-PIfrD^RNo7ZKvAi*UOku7RV#go+@SGnt9(mKdz<@zU@eE?UK(u@MS zu++<};)Y~`Dk!Dh@efEI0~WH&vDFS!laQfKWbTO#Nx2HX%cM<(uYVwgl@u)BfmFdP zMbU$WZ6Bu`6`_W6Ucw2PyGKneTO6JYk$J4A1*ABwOVh^v1%vcgMSS;3xtHJWYyp4o zty2Sh=vtv3VPeSXA8DM!>-LEwSIsQxTMe3v@gD#SNlG#fgvQmI#o?pX$VO5MBMhHv zYvN%vv1m+t<>cFainxOKvO2G zl#GEx#8zQ%4N+&+^}5b7P&o@Pf68yQGu)4UgUP*gtd3?7GOKAwPB}HTby6x}-r%d4 zwZ+mWZ?Rz9RJJS*ZwqHUW7NgD2oOsOr;yzHz&yvs+IN zBUIbC(T%KkI0|Pv7tYGh^b@Pubhj3dnTiM@NB})&Txf%vhVj$=H*b>siiLy?X9Rod z)(?m}zat~JwoovkykPU%l5~;PCb>l3!c#KbXi^!PqZp%x zC?2J0bU>D0e+v&;U9P6aFsQA~8^er*%k-t&La}(5vSSaj3;E8V>oPEGHX=_hsrxaX zyInY6^!iG!d`5HK@K?+Gb&j2cvAjMN>V8y$FnR&ncVsL$Mu3_?i}tv=CgX3TBY zO`p`?dA+^8U86-7ASWjcHTs@2nU>cVnyi6VcB64}!2<-Lay6hStVvBOD6}mQ zUW>DzVx@#B7uSa4)qoB7)W6r*jF)nGJ20SDfAx2AYS=ytCOY~__(3!2Sqp2XlbCVMvdH#|lsLZ6KB)|PF5P)x4)Adk$Af<{Z_sAz% z9y6D^+N&)@1HsvkjL)_?dobETAQ|TJND;A28bhVJ^=JB$JKTXxeah6Lp7%&YJUpj< z{`@)J3C>gtPp{N{P*>+2JVS336c3j@#&VIVb3S?AJgfF7vNH6C+64UWiI3KYuYkVm zAXtpJivwnHltE*wlG9Q0{j!_5Q(QQ&DtwnyvKGiK9K+GL13;Im;eQGLqwd z1_V(@lW{O2*IJ3=URVr-+m!sel_`*S!85sUFT8UipJrkCY@`;BC)-sW0_ zxTR;y=oBJn+oaeqPB`vhO&*Pj>sgARw2w7S{cSm>Wx?kx^(*daK?`F$JqFMpPU|$` zC&s6?{h6;Qm+QG-lsCMv({+-Y=t|lla=b!^d}s5~uOfEKWC{}mQT1p6^;XwZpLRnV z4cFcP3@4YzZ@6qQ{a?~$)qkHZyZL5xsOvxcGN?vT$|B8gy#(iEVM7)k?QMzwbD(SM z>qRF$Yk%jS;BG+}beI!%3JSOZ3w+9m787Oyx1R8whXUF$nw87q@)2M&f0-@DUuayb zUrfvI{XoF_@zuHY_fwYF!J(>S(g@ep03TKTc^}>R_4%!uFL{A8ANL&YL!3@7v`iLM zuGxjETV-V4M2$g4Yh+wCY@~6m8N}tC;AukJu9-Y@En_jkxwC_Kj*mT3=z1cG{#D~Q zbt!b|me17iuoa*<Ozt$w1cPi ztZi%L_UGZFYc(~~(gbXQxBfXVn2@CSi==eFPIF(>$1446Xf;{K?z4B_ym8xZ(~XQh zk#*8SWMOAhfQT)M&Ospy`ohu%7W#x`iuvEcZgh_rrYQ@of`{?dsMl%j2MVWl)1HwF zn^xN)%{K!c4L^SddQ*FC!d&XW%Cjto^kUM)>~Y;!Qs~O~0Z;K(uB1!WVf1HCesh0O z=*F+-yeGc$yH<_IYFIrzn2wp5Q{Ye01^n7`{85H*d=MEA)!lrk7q=eQ-D)cDN5sLz zDssN#Z8)a_(#Lf9aZ(kvAy;=4dTi$HzYXn5_GKn0G7?>$szTC6d?5?y(6YBn)N&I1>;&^B=BF{*B9k+xaH8+Rm+;xAZQFJwrHy(jQa>mJ!bEWgYkJ{NP3$A~%Uqbw zC_iz5ZWXIvvsQ%~RF)TMHc|8{giDt_Vv?x8U5F{!ysvx?+WXaJ2I#totJ+Oepyk`l z<=}##h0XRk16z(l87(67niQJ0(}!m@d4_RekeQMqv^2k05*mgQ5a4U^^<9R6bW&sMVTx-`h;EX9iN6trfxML7Z_fYPyy$6KbcsE@8hkqQ> z8Qv4jETr7=*lT|G&x03=-6Er+d+Q?j~eX$#YZJYLeRRaz)GK?^Sk`uSemO$tTmpfO)u-PtG(2i=7ug1iZg( z`f^wMvs98#UHUt66q*Fhw*R4vK>JZhUV6u4*U!#~{Pl+xhPj@8evhPqt*a+qOio%w z4}{*nbql|qBx0Ps2R+4XIU`*oO|5Zu?#CNu{w+OT#_V04_rq+>A+IvH)Ig@v{CW~I zavuEiZ%JKGPF>;UO=8AT3!@x0!%+4IbuH`1W-d1xN9@g>gmEx~Cd8B(G?S3g&pP7; z^`+r?cRD{&p50|eJQ_1Hi?JPnG#DIvj&(4aq<+HKlaD+M@=37Rt^vESHztWX7H{?z@4J$2ib-Jq#jJY94fAua|x5vS)N}(Pz_&zJr zCP<>^S;Wt{D5bA2_!#+vy{Z0WYvs~ z`=UkKOdr7fao9|#D28kHxk>aWbF0Dgat8BN<)&vpgz^!tNGk~~Cd!qgBnM=Vh=im_ z%U^r_+-MR#{fqu+Y;JY>de*THxvcG#`WI{6-2tC0tb-vdQ5P5+BWpUIIOID3`fHL_5~sPe0&IR{@o~;PD+_XN=pxLif6HCm;M!=PhdvvuehfY6fLw(6Cby zo3DpYBy)h$77_v`Y5X1ui~UEqjY>)~DxYvWc3Rk*Kk7I(oTgriDj{<7jkiHB@md!E zWW7?0E9K4uI?Ws?Lb0$e+eyMh?%z`q(A7;hJL%erKg5t5eEfdq(m8-7;8btQl#TF_v-;y9AJZ$Ge!JOx+ODS*e4$ zgvpLl@`Z|w-31FIKTgBn;wYqou8e`ZswDGa%HKmRi(d;wq`LuJmt|7b3*x``l=0WEnjd#|LiBEp5k7; zQP*96u$^|J*6=Lm8zJ%i-JqT{yaIgebh6!poKf6ZQ+k2Y&Qh*fEM4tpC#k14&1q_I zl+ePy9!%tDPHglRQ{y`FG5gLoFKq_df6OnhWxe|c;YyJ4+cZa_i!%=DmlzOfU9}Te zcnrDhpQ!tTmSnQ=UEqnaCgS@VaCQnaPwrQWyIvBLw2v))3yy)l@MXXJ0(AAEp&h5*;yK+Esi8`8S+-v-S12o)%G*Z01v((!?(d1ciF7TuDBSQLI{h zeUA~fwxf5=e;;+TAoQx3+3x;?iL0Kbo9&s5A@$7+ujSh%ez(D7-Ji$Zi7xAW(%-iO zU&>ib-1f3>Fe&_jS+q~`ms1TJ#39=pD*PIF6oS%xA5bu={TKX9G&P14r8=k;zJoJr zC33fC%Oo>)G^0-oKDYB$*DP+Zh(>sIR2H_-H!UB-^5Q+TNvszkVO6^7E`$g#HOu9e zp28dJG1(erwG2Gx_DQolDVtaiuM^xMEA_d%7~$j&Sqz&VF) zO1QE#G{9E-&Y-jRlmK_=Ut)O26 z${xpMbXnSe&KEPxBSR?A(|0QCM@#Hmt#+d_U+G_V9?l?5naTr;M=jiulcNcmT`ta`d*DkCKpbq`cSBs4(E*Pwyf z*dglcgV3nTu>@2lI)XSE>y-#BB@O?kN~o7f+*;0FIJ+H#R#ym6EuhTA$%Od_SD;L?&pbc-l=O=6}0&9-T%%sle48F*{0sHf; zN5*Vj%To<9yrOPP2z`gQN3T6$OU>hH21R3Wl4`=mx_rb@gz*Vq=rX82TW0>E<(XsQ zJaif&QEMp1TZ~%cY?5lyq6#42sg)Le_DIRnhTW)2G!hb0N>9k`Xc=zk#J;&)3G7hw zAS_iAQG6JQc-1Q03%D}x;XXqGE8<1VZx$0+wy~)EBTc%hq{=b4)r*}AeQm0A8Op|^ zJt11Lv3>S%`NIP>7}$OE!tl>a8XCGUYcCmj20=o~t;}@3Res{{>G4FzV!p$GUy?D4 zt(BO<5pm48=~Sy*xNVv5KBR+=^&@wHzf=Rm3owp9BE)O`ki1h|6nwOUFRAO>a_p_6 zckM#day^x$OV(vfI%x${Vf8z%%f)X4LdjVQ)j{3gX0PeKO-J^M6bdDcQozl?Z!dwv z0|yHQ)rR)r7S7#~Lq@i^@DjCD5ip6BN61jp6=aU2wdekJ~Ta z+-q=yBOlrC#F)6k8UQFq&dO$dau~`GS?~pE+hJr++T?zK%m?f(Tnb7oUCfq)mgz5* z!yc8Gb)7C5gZ8u=#o|4mh+<5sYsxA7sYWF>n+yC{5>pNcXI*of?I9;mer)lu!%bAd zODv}KpQ!t&xr{=LCr|K?kB-#nEmd>|Sw0>1dG@Of8uJ5Il=J)2Ams3!_vnFK(u+ z^a!>19E0M#CBuqt!gY1$J_-~abiGP>UZyiqC*zNnTkQw(U0HK`^#^k8$yC!poeW^P zzO=B^OgVn-ix>Yz%K5$+h0fiNtGhX!7NN)kjd*T`O|uYgWQX*;E(~*#@<;3hOg>6{ZKsX zfuNaxRL9*bLwpGn#a!p-f0-1V`?$(bVKusMB_+Clc0>Q2P>(9Y6JJF*Y=q!H%8Yl+ z4%Iki6D~3013{-raivnpp(qZe+CD*#V<%h2UoK`eLQ#we%TSf$EF&>}XF>Zuw&|ST zVyiNhPE!W#&YUQ5p%bu$^~S5~DSOM+1{}c+BH!A#Un$ZT3I-N`d+i!!AB-G4ccicu zzZf(rq%!U&_%t!r%2SMIWZY`*nr+?Ku0+{;af3V`i^}_} z12FQMJM{>WJ-cJ-^yQo?RYWG|Ps6ws@kgp7CU zjPnM_nO3|o+siidTagTW8{;jsiCy1G1M1P@V6&`ikKdDkX8sYs_B(qS319%v@2LL~ z&}}m0&vxWvD>I+1{ah&`b0009dz9swvZm|L;mom_P)DLdo5_C3IQFKG{W1_sjMt%0n_@-GW)jw0{Wy z=34&)Ffx^ph;fcuieSXvb4PxTK=t4Bk;6(87KiQ8i#>^@OQ*0 zt!SR9bQZrbDW#8|H2hGD)r?5BJ5U7B~x&j);>AZP|TNP2SGIJv%hhB zxBMkA`te|AEr@OS65()M#^H`XbB-(KrdR4nuhfhi#w*QGj5XSWF(^iTqH&8y+DHzXoN z)2Oa9pBPpE!T-+K{r)wL;h}`ZisX?cMkUk_VN?13*rlGGZsI7rpsJo8^7N&$)`N6j z$yfv~m4jVD&pGe3mIyj`TOE~~x+;h}CqnwlXRNx_iGyz=!50v;eB0fQo}T?Bq5X`R zVfn3ZYzh*H%h6LSfx}V7bQkYY=GU%ld0Ba>@vG^ObWI0d^;&$kINaeLPV~W35M9vu~FxEd#3jnk%=L}ZxlZ4J24rgik!GS zJ#5}5?OgD}_NU!2|KbOk>&7!TD-{4@o7vx*4{HWi{WPQF1ymEx(hM(nKy1_i#H9iL zMB$}pVF}$0_k=uKV{igVsj2hcPqu#!pcY_DhC}=bANl48m>p79AT z_$cQ%b5&=TqPNLb`1C zf?uM|2f6JuvQKuBk~}WYCFk}#?P-<*l$AYQE3W4Iw0%)QfrRjgf(~W#v=7$SS__hH z;6UkOi*#H=-`!fi_vj$QNqAvLw+VfN*8K+{;pOP~?2A#fJ|RS z0D5tE!oPXV*QXVF4GxUMW-BaUB-QVKs_IrY&=jh^{D#Ni^J<5J!ZNznsd)OHu?-8S;*gyyt6V)8){au z@33et(N?q9X@ajz;Ti}hA`3R_@`sLRR-D8ZXi7DFnXgm{x{J-Q+tSEJi)yQpH75a` z3!@Xfa(;|l0C9aj@r>AVZvmZKxKKOzJ8KlSlxA` zE~Ldp*?WKb+Ur{+)P$W+3rRpKtF#4puzx^3uwGrN^cuN($wQq$KEX9!hcVWi+*;Dk zuh{fT+kpGXfVrk>Z^R2@6){AB-&k|)e9>X~*I%i#p9FjG2 zOGEC4I)VGvk>zM!jh#nXCn7N&6vMlr+NBxgj_}!Ct{T*9ZkdrA6h88W!m)9Ect!U4 zI+0aKvlNU_R?j4`-36b5{y;Hz7p+{AEXJdXj2C;x?b0cOQO!ZGfgH8OL(U7)9eU62 zH6s_`Zd=+b1=%&+8xfFdp*~rWk?!wVm^78!SI_nr97ghEdC#lqIlnK$j$AI$_S8NBK`Tt z8zYWd3CqR)-{CH6ep^!@CAzyo<~oNE=Obg(aPMir&J&x}+jg}iTh)5yYlwKV4u)OZ ziA^02(_c|oJFk$#CQkPQbzAwhA2uE7mC3N~VrfwkgxCj>$BJx_t(0E3UgTf+7c(8+c= z;TS3kZhyr$GRD6Bt)ToobU_p8rZ00{*%e!!EuAGZA#KA|NPjTJr_J6B8*jQ1vda&C zqqKFIh&@w+TqY&gqzzVCD%g+b<_t82r6uMGORlTja{dWK#YmO}|C2CRNkf(71HOdZ8e;g%O7K)hI`xb*Oe!{-^`_LxycZeo#$4cBwf#e zsKTsaiz8~p^ZYH&uG6af)F&CMgI7s&@%bP|!i`RBYN2I3_1gUI;vXv~>vAsdVUxVc z@2|-8#MRzw2$9L~iAnWf9GLnV{2FZxvaR{2hcZ!jgUE(^jD6SUx=$ss2B3#qSz(sc ze)Mb&d|3%4ua|&7i-b#&TKFy2Ti9`xSg_n48&?@HCI?^uPy7+u9wcR(~8H??gW04T)VvIprW^O67B{(iNNfyza=%o zy?6awpN7?F9un}3vPF|Zk&QKb1y&F->phUM4@>fo_#BD_d3)Q^HwR#1j0l+wj;9{~ zxxOZKcQJu_9c_?g4(2euwVShRf^mcneElM*_;;3am_8jvg#0*>{yBNKHs&9Tz)XXG zOyvV+F)uU!vM?2GdOG_e9}R8@rznEnT$(9sg#Fd`(sYfUFJ zR%B*&thZjutvwjxBu`9yXr`<;`5o+l^|CI{#5bx3B7f6qvoV6y7G{~dqNZW4f$;=n zE`qvOvEZlF!zI?Jewul(;f^4)g#r=pmhS~3zAa*zk8lsjdF#eUnWh`i?ql|ag@yO9 zhyQJ73I0nVP$_;VbnE^wq1v`FKsT}b240ElaQ8kS$5W`m)~M9B;ZJ7X%}Se2?vrTb z2mmgtiMfS_S``)+P5_hHWFQ8Fih|B7wSpQ}e?YbvTPPX)&v(3X>gqCQ&z?FrZzZvXrwwtA&%zS=G6U+;>oMp>2pV9pr)FdROm8>(up8?vncf~Jt77D{GoB=@89m_FMT}lU{A3;rxvy>DRN>(3;^qNo z6_StOzjf`H>(sX>Ms4w1)(pH^Y2E%_?u6}OAQB9Av_nSNdE;8wkP@d<9JyR>D2)h} zsPGdfJfEcYKX=qs?HtU}4bUmR?r2?mq0>^~CBJh}W`ulPr5VbwAr#hEx%noN~8t{3iE@B_* zVmfZZ-@k4%_f2Qk)W=VGGQV3Ny+!vSH*^k4lu#Dxh{mWy^=>o56&vD?m-wNXchdYI z!^IIH_E>L--ND=v-nDCof{W|g%nnjYsDJ26ce~w8Y2|zBG)(UwO(a+dVHb5!n~(Rx zl$&Ap2lh}K>68rnU}h+|7h{%KTWJo$uQFKSuygR-fTP2gJZ5~ zc4!XIlA=El_%##HxVG(-ry<)6JQBvR=fxnsPrR)!w3G~gLJKO634sl%{r4%WiL!V7O?TDy=) z=3)s%aR#;TB(G%Mn&;PMZS%1mz`q8(eVm@n+%Ag=rYcsm>rgka zJerf?`y+hvW&GUa7ZWsJrL8H6ElgGX%$Jn-id`dI>tBv&oPO|Z(me+9ClS!u&OBPN zn7#4l-%HAyoxh9x?l3o)VZeSyp>8HA$#0b7w8T;le8DG3f1v9a;BIlIJxp^=NCm86 z1(UO=&E{%pegZ5r_qjGHW2k!F50(NcVk=T+IOtDqn7A6rE=JX9&!G>LpT5WxNOVP5 zXi@cb(q^T7w`NORLMP8FeOC3>g|>)!6=o#4buy9TcIpbV@Kpa1cE>KVR`7;UWM30? zKhWC1dY+X0g~*$KJ^O+Wft!2HiwhAv^8IIuIL$;dTuBtR*(0%anOUv~FUVb`Q?{xE z8SmaweC$jkho|T&{^Iw=*0?DYBm)YF;#UiskUBV69?FY&_oAG$uu~;9o#Q9yPn?-~ zk4l77-?2GTkx(+zoy!)`cgH8-+7Y&= z3{&C`P5txG)J)~ttqL|*8Og3hDsn^1}Yl2^_>53%kdBP`Hen4w`8yII6`3 zqW5Mbed2#l#~drecb&xOKp`;&L|$xnxZ z#;`x<%M`oc55Ui^06WTu_fOgk$e#kWfuEZw%3iIoBi*ocufd1L$}sj&Y}8iC^lTp1 zow1ZbFm!ItRZ9XO-cnH-=D_-ON3&uFkC2PdhDx<2UuTXp>iU-6%148JAG=`lY?nF} z8ZZ)qvlLEx@6)<3j8kz%jRRp)^78WQ3Y4-G=1LXHJfvU&(@h7Kvh`KgdEA}LLq|M& z1fkv@_Mr3hquBKkswc$xucs6m^RZLgX4B$`Un&sA6V5Fo69?%^{nYGAz0L^;!pGUM z^8-IZ#4vmg#;myqO_`3tW>cHd*y}mzADs|5MG-219%2=-6eGu9SFLdUwW4|5SRU4l=nuD)?jwTj_zj_uQ9R+i!X5fS+hg9OQR-`du3mb@I147nfq>Lnqbi>p>Ep88WeT?~DLm zgXBiR1DOzpJ4zae2^fzWIO)n?n-$YfSQ3C=H+&aC+1dWE7QD(U-&$_x(~6ch!tGaL zd~0T{BLEH_At!PrrCu}nTkl)J^&NWRJZUZsKqHag1M$rgZLVHw;98~yGJ<3&}%4rYG9_U^)=nzkBZlVj&t{{ zcQGM+(zyM8MKcL=z5#s9w7}W31zlHB?%W%P=3KOn&7PhyaiyQDhaLnH=ufcxWwR34 zvFm~|`7@l%qZNP|&aJ~k6w5mcMD5|k3}xvi=fhevA(;iGcitRto2Wi<-9;4um-~@# z`YAS^U51@q-Bo0U7((mNR@W3X!sHNcq9Z{++R z$TJu%C@MgGnda2EUamOlJ7ro+-9HcZ46_mL-I@mNqoh0$LZJ$qwUcn<`>MqnexTPE zIyJJyXa(kzjkoEP}OJRA}{U{&CpUr6YFUb$VocA1!Hz(5ZyT!Px3 z@5xU4%e)M;##AS$#dJmo@rDbN>JVO&dlIPmZX?G(@_Jtx)OUr*wW>Db*e;CsoyJOQ zcH9LP+ZpwSI0{WJ)x&SrwAwcYKqGtiRyJ!B)UQ;_WhQ zX`BK$ZxmWT5iSD^5`=AzS^&FcVEd@BQ|NJvQrq{;V~FGn2>aiU9YqY_>rl6EeAgrl zS-(>$>@6(j0k$V(fac0t;zqC_xQv~CPEXm8b$=f(Z#v6o3#0vfUE71>Ah;5tpOB{u-9F^31DdE74{00dl= zs?_G#2TIrRGH;_{;p2(`L6VHur6PLFpEr^lLWaL|-)X$x)FaLSFK&8|_^91^h?jlT z7l7D!z(TeJboxl;8u&EA@UN5_kG=pfER=tasf6>MRr$GEf09F>_{)Ov!lFx=2xF2= zLea_nJtq2fnCqa9XKb9LEqu;8=q&03-b{>zx^v4MzE&@{S0{ci{`;v=Tdg3CIXn71YxPW4 z>Gxz$k9kZlY46^rz_$4strGw!e3O<8A#8?!6i>R#7e>eaRH40Zf?2ol-hn`*g&jgA5V@w;tQ3a5QC1E8^r)BTw_6>l{n(_y3C@(&KR9 zwyjUq{jaS~>`E>!ZN7Non0*KoU7t3&hf8^jZr9~WGtbP*d^hazg<)(1G2z;U^bP$g zFS_2(b@$KmFq1Ue#x}+Al!T7 z8U3fqhHwJA`dUyV<2jjl@g1-=+$fqv+5TytSQzfpEfQgDSZ=qyU5Bp%A|)#dHT{B0 z%RRj!X(yK7sM9R=r#qkpS6q5d!kF&L=l;7g- zSpLGq{D}I+41FSR6J+-*qn`rMKR|tX%yfH5AXm?ZZPXz_z|Mc}1l4HDEQF9RPLij1 zK~R4tC=EM2>QlELU>{zBUiI6pA-NL*_^0**8l%rb8wMhHZ(cd$sVY_LW`MwKDvyAc zL!=zH3Gj>7Jh;T|eG(*Bl0lV*wKQh_+FD&Y&E?gURk~KOGPJ2IU4JLs3toiY4d19D zPzx{*JHg>ur9^#~AR{k3X`aGMvq>v6k1C?qwQe3rA;`zfU08j}wlVmPYF zeN(2D?S20No=*EWU1k%Wgt{$^!|1q$%+u!;lW7O?GS8y=sIcIbb+ zz_0BA_23-R+b2WepP0CjxUp%-o zUBG`r?G)(JGDj4tYnkITtl|!=kwf9zvf89Lve>U76LY;omW!>C!yDU7Sm!)!Cr2&N z$7LKmKR@sN6iq9H)yulnpVy>Cn#$PxhRF^&8^$XgfyGg-jqc;(vb|4&ge zbI0_5|DWIdkHGpFkEWH@1^)k|l`{=XGV8;*)r>Wz+0<2*rsG=REw+Isf~2--l8fXtKT>MHX9sU-KO^n*v(VRvjHKH3S4fK=?LmBh)q@%1tbf z4uS7WU+^u~1&eq{i|@{y8OxW@2YL>b>Sjsj{I*pKqN+SAPV1}GxTHC0k!P49O0)||eOz+!U#&vtW z_CE%IHHwI~I>dy?>qi-zxpC^wVI{{N7_Yx5}T^|Vc-4xauuXZip3#$+?o&C|Dt&7PX z|LAU}U1@zJjb4jWD>YMU&bUXKp<{~^bR7EHhhYb>irMaF(WtvUiJTUAcw*OSnwMx! z%*x!vIjaWv4XC?WcwuFUD)sNWSh|l1bi0xR%mZ|{z+6iH~ zepf>DP-jw!TkIBJ3uj(xV)qsrpR3w*ccGdd45L=>%}@#2`~ol5iO3ayU||&t@>uEe za6fZvIPM7R=W&LF0|6)`s-56?OfBO?cDY*lfg~o zJyR~5u;0NvNnKr5G6bnCSNmr+QLU!cfSB$YCApZjeOfl)@GI{VB8LxW2d}6MRsg>J zqjJ$$V?@oAr{}?P9sBLA9+$WTjmLKjxr>7wGmn%%dx5)xT;?14C`PE0zwITKhTY}f z;ad6ZyoIyl$?DoILt!O<_BoJK2pamTHMBqV$DnURM;#`#G~Gi+-cP&`0?QHQ+_^xM za>}FyK5^zMmY@cq>sur(p^-_fY1hc|FYprSjB0H=6-UufxQ2RXjF!BtH*@;dYlAI$ zP9Vp~nsQBD682-SQsLld+hM$o<2V~zoLqkIlP|IamX*D{P&ja3w%v>t52p2(jl%yIQFATIK}7HY4%q6TDZ` zYV}x@MedntBcEk4e^3)iCbZ-%pd02{-VOKv)zozS;qcQHbj{@_^RtVw_L+H1;s_e# zR2lnt8lE4mCuNH?J=?F?&BNs57&;90LFt<-l6}Okt4CEGPT0*aDk?MbPBm{>git2U zKX=j&pP|@SsQCE2bg*FEN-&WCNmqex3FW6bizFk3t#&>evHqdEtQw5#+$mS6xu9l{ zrOa7H^yar-yqLHo3`4XEe4^wZ%~_!z2j|E{7S%&@e_NXg!$|w$(&7C;{d0V{2Pzcg zHIUNzzhk`qR>>ZiJHrc#>{Z1fP9N zLgd`X-_HhnE=?u5fX*q#@c)ia4k@cw+k4{7lST(Pf(@Vo5+&{PQYXyVz zy&0s=%mLDul~%|yFY&|!n2B#h)h5O2OY`!yJBOQ!sjIeSKHNI{#bG{gFs!6C!uHFrsC`9V=E-uGv_x~oTPJsAM!Lob)lcp7m(I&JpqLpzc179iy=_qnwhjW5PK`Mbt-VlcltdL(;v`^X3gH3@93{UE|WBrKJRjM%-3M9$DWLVYBu z7ei^~t1{W{)wT<{62pmyVLAC($hMjT8W(D3bcP0;!p5e~cEC5%1#ua5#Fiaw`NB1g zl0~~Jju_*U_Q~f2vK22Dq;SSVT5i#junQ--tpzAgk}8t(`ju zB{xWPJqM1<`1LYZ(m{wumCzJ<_Rt7nJrCS8WqxNAU;i~?2>CN;x&TwnL zG~ah!Oq$K$z$~#py{pHJ)*f#BiL^VDes#-(EN{(2{!lNa5@l+r3i5WGbfPS=`dmo@ zKE{xfl%74wFWLjId3ou9rd(fN-i*wRUkqAS)`uS$PN)~Pf{>Kn;KiYM{wI1JfA%zN zUc=2uIS6rE%B|y8c%zKF96$Bzw7shC-Cqzhn(&iPP)P3KNsXY;!tXOT%Hi}Yy}%II z7L|H?@lq(dNWixd*15y1I_(zd9d^_ZsBv_Ix<1@F zIqmyi8`X5Db0naD@+Yb$RoK$9=&bZ&+=p!i$f;?LpWi_j%V48kEd^f-*7-SjNxwMz z157li&lCzpU%JxIe)e_l;?DJT?`)Eza^ELyasDBVi^kmc)S7 z4@(RJqKeKG^h6@7H=|gu1e0ht@{SwNgSxuOxcVwCGo(77(N1{I_1&OlIT+Bf9LL>2 zu3~(zRe(HdmtI#XrGM0~6W!J3&igaHb`rjp?ehSNRXX~Ykva8g72D}iGD!$N8Kd~H~SSe6Uq9kCL zcAfMTJBP7i=P=l^bY()$;qw1-4m*Ivl5fsotk^mHpKBKy{UrY897dd|qE4^x-&5@& zb`HZJ=kQqv0Q6ENzdMIH4_9I#=P;D%p(ZU6_0;ywt$~Y(NK^59A%F?W%>d-mt-BVG pf%u<>o&I%~^w%8>&NyAPr$L5vF@qpLf<1|Z)d|G$GIP(ke*+Y6p-cb( diff --git a/docs/images/features-custom_controls-confirm.png b/docs/images/features-custom_controls-confirm.png new file mode 100644 index 0000000000000000000000000000000000000000..9bae6fa55e13da615a813d6f2d643eea322096c0 GIT binary patch literal 10470 zcmb_?XH=6-w{{c+k*1>3L8M6&g@i~~qVys~KoF1;NTfum(#3+0(mM&g_aeOpvCu+^ zR0)Kj^b&dtC7i(XtaaY^th3g8zO}v|$=tK=seAV9eO+_U$49zqj2AdA0000+4fO{G z0Ki!wL_obCf*Y3-u>%007gs zli!(kM7|wGc-j4-skbz-f{) zcSKlDRdfh?vabGqQi$2>a=$|HIThwRIO%1!WcW4RzTZD@Pky}5XJ>a^hvvNX{KecU zf#Fy8yD!T!%Ly&q4TrYJv#13KRHSrBlCDFc%1XRz^*9f*6y5J?}$mE z@6vFIx$7~yVb>V`^G68l%-8qy8#`kNj5(rNaIP;c!KeAwTyIKDr9)q4;^Oy@EE!{x zYVG0N^mv}fADFnK!2~};-4wYY!^OuX#*S#FS+B9cn!|DNyVh&}n8&Er$Ks)^%dZ_$WZRK6j=2D=ACYPKP%*@Zb^G=r^x6XbNC)ix z(NvZ9rhVs(>&DtQW(*4C_=sV9j6jxgKbV;hqUAYH8FmYKyKJVFmNztR7LruW*h1<- zER&frf#4kH{+b`_IGUWfH7tbreSqiGb?1Y)7u?w8PX`WLt~sd>nm_tn*%n=V^3*oV z(mo1}4O`roamESgDQ?Gd$+~{`yhmAMz~;Gap+)_{qI?Ja)l44M=I$H*FZZ|LqjfK{ zmVbTzHhN+m&&Zjn51T`L*tVrYwtjFTn)vh-*54UYpT5ePc&HfagM9dbnYRW!Z^KU! zzOG9j(BqVGDreP^>~Fln<2`+8xSJxsSN!O-k5EOGEU~;Z6v?09(?%`*w;$K|kWBtte*d(igB@Z_+VSCBuRW#g>%H`oL1((wcgM0& z^4~9?s<(Lu=g7uE$^Rv|Xg!E|2BSP)uK_ZKP0VanrX6*UGEf8;c?ZAcC$wTIkN2FA zZV*FEgyxN?H8DjAg$TA=AD`>HBK6sInSjcA!;|Hqxs_5DrLylS+Q_)m9-J#$AN3mf z86@g$!@TvtqH9#29d;n@4eeZeb$<_b1|Y65JB&4Qle*0D>ax_QtRSBJS+(yMNL=ql zWc6Kl&H`SOzI1noHXZGZ^)_DHw~eM4uh)bHkK1#Y=%|qxmH{ddvqPO4m28ya3g9ka z6>zRrk~e<-^g`TlHniCway@ov-$~FQy5uer09Y$sA88>!X5y9;Ft2rqYxdpU*A64A z)VL6;9ZjqP*nF87bskm}7+>U&BA}MuSIwDw=A|3PYFCc`H7)uW*_&;LWqM8(&DGOU zHNrTg89m~0^{wusN*d^|*v_k2=DGdfBi$6TjE1X}7zS?XJ!9mA7G86UX6N?AJqJd{ z&e%>xOTLd#f9%FzGPPJwlf=a~({&|yG z*!9pOvDc*0#JI&OJA=1jOV0bxfYL;8dGpiCKd+YDY(rn(S$4C+VDin|U;?~HI4Z!G z@$@W7-<{Z}i%Q5<@ZLY$#Xb;G{Ec7pQ+nYco{8iMYyFwpNArDk^>y}DS>If%*>NmGn1)OIwmfmG z5BpA6c;^5$)Z@@u%l0b~xs{`Bat83_X@>o57RoBR@# z8{|!zNg$s4LUB`$E@E+-o7=bY&hy_!pQ|G;B+-z+a5Q|8zWd{+4)RT zR!i@{jaq?qBc&adiO=14RtX41T8oz~sax|wn9eyDzEmp66eBui4NqQD`1#9MxAlGZ zWr}3`8$vcU&M}QK5!RN$X;u@yJxIbRp8u;m;l^A9j;*Bf$@nTsO8u+OG`d zwwaB63w^!IF0R_#zS3ZXIoBB$(dpW^$_tuF+SrUJt>)z5Caq8JK8NkU>S=2GWL|X! zklq(8bn&8ZWMB}C8ZzJ);ELz4TSv!> zNu)#+L)aaO96w_zTM>=-cvjxqyd@tNX;yx1ldKLhX^alciE+y2wNAppu3Y#q%-r(SX z4EYu5`E=EYiHPO-SQTILGqpUBO9SW!>_2O|h!ai;$bI(A{izhjd^IZ!o9KAym6BFs z@$dB=!o$KOH1na;eZ%4MPzU3h39C;TcebWb))bfWMeCR$j1D%D&gJa?;0rZ~6{89U z$_!;rHz~WrfRSABKecsz_WZj5xr`H0F*j*?(v@{(m1>?wuiziTIJxz}$_41LWG ztyiASSN>A(r!AC+nN1{noM=(ULR8m0^Z0JgTczretvp|*;q*Mo=C+y3jA1=cOKAp1 zig_>~CQPY>EvyiC_IgrrXl?G%`cBuVE&s-;^;FrU55GqRgnf5;?d2pEL%D9L! zc|GDER1$RQ6i_JsjVt~~;v76nft%;~-d$Are3}0Qd|&jv{l6usVEeHeXV+c4mweJG z0)h-+mvPlvEA?|c4$_o*_xxZSC`t_P+S{wEWTyzOE0qVI;CLJ6|G!Bt|Koz;OL z^K+oz`)2`9MY?SvhH>NSDypuJ=Z@rc9&gOM-35Q8!VP_2|EV+O_iprSWec;nh-=C=q{_upMQiGL_x{9I>r`$drp)S& zqHa5j?f3E(H|zQj$mS{LqCY3c76~G`*sow>Id6}^x|}DS<_5kKf@eVsFD#bchcY~| zl^R-Zs<1Pp(}30nkIZDf3=k6*f&v$+2)o|WTU$uiQtNhq0ASMKBQoPokhOrApuCik zHd+u;T69xSvtQ~=Kb_^!VWKI7rN3jSf=Vh{LbfekbYLOdbOCPrHdYl6LB2_`+NE9} zMQ0=k1%KbLAI`NCkMnpFqw8QA?Y>y~HWAG$xgS1yu~!*Gvp5ec2Fqj4h+RHM4!=ij*7p5vF>K&0%S1kGiJu#e0-enR*1#Dk@5 z+BdG}(6MuPQXwJ!X8m-#W4^w43#!y%ID=8^#|PB~pX0sHPmjh{N^vQq=B?a@Od<5B zx9W6QSg$`%vR|@-fGHBhfefDDaF%`rXlQhHBzwsNl>f6zTtiP=T{J4%sqzI7BJCLH zuIQd&U-zPa)z&|MrR`Vj;FfvKToO1~6;6;54i@@KzAE8>>ql7{?mvUc@ih7ddVafw zSX?73e{5i+P>Pr5!m!jLnCTZPs+&S1)VgAK@qhR!?SX*?7!1rt+qJ%m!MDXmEoEYT z(4v>gw^y)O@e=lZb%OlNU`F6vQU+zJPdYgC z!#Q5V7B`IZjl|y>E@usH)L{+RCsO4jWAzCV{lTB^+*u)Z`^c|Vf$Kih3SVyZX%4Ee zO={RK6In0iL`6FG|8Bq;>gZ5q)zv!7)8tKU6DN2RHjs-=%oJM@-Ta09PR$YR#HYhyHO^x~UIhQzf1L1b zmH%t#_&-FK|4?N0@~LaiaL3RB0I)j_!MT>|A#v*JqUJAa0Ch%!%F&V9KfT9PYY)ZJ zp1VA_%r85@!Zh?oJ5&hzcExmm!7LaX)m`;2f|z(z!iQX|&qis7)%CU0*cWZu~kmTd9f2L*Mx%w*ge)5!_ z1GHO-eDB!<$R_{OgvmRi-fq2Ay8eb_$6+GM6EkutF-kR%DO)O<+iIdgm*TK0q;iLN zo*PQp_kJ!pprE#!0g#v{Gfrp)O%{kv4t?7Nprx?tCOI8OhA~4g?9?=H+ldPO#aIsedY>1Xh!|GgsBRw z>C3iJO8EA%N*gQ+0GO`rG4v>U9mQ0Vr1Dt>h}@5{KT+=-9<(x6^xTAF5$WHah{z+H z7YCwsLqTEhm=8FM!U3R(VG4q86^wK+>_sV)T`Zc6fCV@AP@n&9t)DT^qlElpF~>5nUdu`O)~C*L|8YYxp@<|=F0^@^RzhzME?j6^&tixo)I327FxdzN#YL@xIDvHCQG{b<&zTJ8MuHc(D8qkVWV zp zKI1mi3)P%p+TmG-=f4ZZu@hUr^Dv%g+V%Q|ROy)Mms)0eauc7+q!Lbe`Kl$XLYrx+ z9=1Ty$LdpJRFJ!I1wSU|PL}l|TZj5^Vqx3OC_{Vi-d`iv@Vy7F3_81;44LhwU9IF8p;NAdsUU`4Ezd(!6xij+PW$VCN;*VAli*Am~ z+MycQsFZBd?C74MMZzaKROfWv6$kpW{dJ)63WJ~mluL*_=lu+%RZ6tG0c%w-t@nYq zT+fdj8s83r18q5Yuv>C9;(D)#8q?fgmOGp&WJ$M>))&)N*JS-HqZX0Lj*6=+ zg)z=r;W8(OGpE~bj2n~6m-;c8lMS&#hJSAPtp@01P5ZiFYLsnrmE|pjDd%E8l_9o) zR6DoGjL#&QhCx);t>6C+J0+mgup{D5a&(EfLd|L}$`LwlZbus}h4VZppoFyDsi-1$^IUfnea^75+BJKLA%SVFL>(kPwVx1 zj(NtkRa?KK0i>rWg=3rOuSiF4DQC}gLHSaapwc1MX8^Co;@LP+s4G$;NGHyUy30@0 z=Wxs??1Db*6$k3MrRwE)hQ5a2KNoEHQXC0iCM$3&52V8LV!Xr1Q zX^iV0FWPC>yp~K9IMr&Jy}kYNrH?+%F0^j$KUe69EX1U8CAS=sq@XgNn#mzTc7tR- zGw)m*t*X(o^{|o9u#FG~G4^OlHVYJ)lrc$AmJ0Se-?(UWNo^wFz}Z|*^E1{k#iw8C zCz@_a+62|&ztBE2NeD1z;^gKaGr-?%O**Gl9+a3Lds3)5Wj*|SHhaMS!8D+3|4e_D zVTV%S@ejR;8?+ykC1{l$9&pGG1uPA>q`b?ZSkH8fBh20CZ1t5PtP|;b&qkX=%tl*@ zYIc+%5qvV840I<5=;OumT%<5#RKdNni9DL)Iw`HC;j3OvxP8*wzR(DEUd43Kzz*U@ zIhI}>NQ*sE&HnkX^(o)1Dyd}Q{9(^wGWezkUB{a&2D$-FdF}_7wT8vfX2X8jaixu9 zGjIEO+o+v1)`j-6IFOdhC(DVL=PlMSiV1A%SVG)(mPaQBvL2GAEUaR3PFcE*1nEt2 zmrFvH{%+cUd*wJ3=RPuf^0a!wEBKol2Eq@?-zx;yGwd87VFSRZsNKMt7{ zu&>bq36v#O{mUF28K)I<%Is%69Si)t@JzCv|y?+2&0K4RS<9hY$@!k>=Cj|nr`<|UyVVnpLIyvLMX3=%zbyyO2#MOSw+N# zjXV`ISE?}`wseatwy5|n;+5sZ%@tYAOODjOg;w1FPt2DE!agea9}R7+^48cLO{OLfaIP3>VEp+gmdHtcRu>ZTQTqukMW@2>@O=SbEz?-e3_ z?-`4K<{*jjL^=yAw2y7lRvy3Z@ ztT*ThuS^R+gf6{&<$F9;(X-`jdn~x|$DebiIL3b+>sH}5nr?WU?nG|mkX;$`dh2xD z&-ioGM0tYaiCl}7?n=>U@a$hHtI82B1v{LcScLybpr|tzSSUQIW zyxJW6mEZcgme)s{+-WAN>{I$YDP?nRx3gg^?B$cFm?N`@JHY31#bYBKOojKL19hAkj(tx zSxK;;ktT18h9(5O6G=9haAycZ9JH4v_)8XKc#k*raYAhGDhS3&PTZnJ*M6NQh&`U- zyM-oKaUFJrRd_95lC@o|FJHam{c!i#%5f%k^yn~H9=b|6`r6yL*VO`A)H~{)*!?QD zr0qX@WU>;4v$nNlA`9A(&19_?(U1I0cLLYxD*}n0_36YUZ~bs!pO{bK(XcW^nmm9# z@zB@8pF*-CGDax&q0`s22GI~$iSB7@dN)%f^1={wS9I3{iYG?b`KK&{p%#$MtU0p* z6~y6(*<&^Sz_GIFc=MHnOxwt(S=sHfM}PcXF(r=ES1TiYmF9GHIz?@(c;vI&>|!i- znXO>4%#L$TC)@A${+Us4%;l_Bp8mA4;Mu`Iq3NKa2}Je+p=)rp=CAOG!L&U!!(3}v zuVQm?HK74-kKvQumeBK$K#Q}^BqldudIiXIt@(poZL~AY*p4_d zv2Q*ztdTQOhsPBKudk2bLozu~%7I%PA`|W@%XJI;JpI1T5H}zHJlBX$xUFz+F~XUE z;Eb2pD6AciJ{Haehi1IotnCW0QVgrIRgC+ z3+bQc*k6{;<#w!?$|YqbcZlyz!Sub<;&YLdik3IV*U> zrB2n8m=9(MGe^_HTRfHsx;F19bBok-SyS@fu+yt}`*WhWxIDhAmUr|<84uh^+04hx zShCV?Qr=rOf7ZtEo4bN1tWAcVHtje^yz+8%-8SE-^_Fu6E4#;`!;siEmV=99L8sPyX98kcJigtpe-+Teb=*Er zLJ(i6%P=&XxGEEFAdov0=fz)jl=9yp1_Tt=O)jVMmMjPlPL^FO*7oy9j=y+pd(`z9 zJTByASKFB}5OyiSjF{*Y`0Ty7K8xEBW5x1PjKQmwfF~$ZK|LdnY^ZJ0!WsvM{5-J- z!@c7?Cg%a-ljK3fR&O%3TxUj3Ny>N#Tn>RQn5@P)?0~ytI8eND9%{0@2#z7_wDJbu zsLwZ>QJX7@+_i`?rG!k*%W8@OG9M2B6t4R$_&Bq#}$0TENc%Z-KVnc-~ za#TXCWe9hi!+U6{%j>lZQia*4aUFL$_;!uR=Q;JR#ta;UC80(|%j8Ke^*0N4{sqnf z^Xr0V_tvKrb40y9sV(&{2~dx_037+ib;b9Kv53xc?6vKPe~c zN_|?6z}%#kN||5igx&E4XUR3d@14Jl_fa&T~OqrXFGs>=p}KqVmGj8}lLp z*P1;~x9L~x^>-IHG}3-&2KiBLPi_1Ok?abhqMe>>eM@iPvm!UNb-39#=Kn{DU@rqF zw>qRn(GoVTW}7z(r_n*t3tf)Q5w65 z(lhAG{O4xWKFdO*Co#I(aRjFv7hZ5eNwI$MK3BKJ7cEY1AU!cEFtS^nXs)nrXY$_r z{bA;(8gE>dS_DqM{1MwpXPfs+h5!Bf7`Kw&FP=h?IL!(QtM=Ys$UC_r7CTgAf?*C= zqau-aTM&*zg^zEl?oaHZSsRXAxA3b0V0T|5{L6Okjg(bCHRIB!>?mGV_`$Zqmfst1 z`rllaROVA+mmq^N`Tz5-+8YiJ86W1|-V}M_*(5L`K8zFGRoSN`)~B!;dN?B)__^Bp z8_g9K#r5x}7w(ou%9trP*BXvv^pxO%7r$*x-EeM6RWl8&o12fPpKZVI(&!+s_U@uj y-t<26_Kii2!K8dO{j$IBm?he_hj$*+@+=oCwVmmcpd11KG#=_cC{=m(=Dz@XXC^NI literal 0 HcmV?d00001 diff --git a/docs/images/features-custom_controls-example.png b/docs/images/features-custom_controls-example.png new file mode 100644 index 0000000000000000000000000000000000000000..ad2b3ea0ed60a4ec162f0d6d381cef7349c3b6c4 GIT binary patch literal 28305 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 literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst index 2803415b..06895909 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,16 +6,13 @@ Welcome to OctoPrint's documentation! :alt: The OctoPrint Logo :align: right -This is a work in progress. The goal is to document OctoPrint's REST API, event system, configuration etc in a way that -allows different documentation per development branch in Git, which so far did not scale well with the Github-Wiki-based -approach. - Contents ======== .. toctree:: :maxdepth: 2 + features/index.rst configuration/index.rst api/index.rst events/index.rst diff --git a/docs/sphinxext/codeblockext.py b/docs/sphinxext/codeblockext.py new file mode 100644 index 00000000..d70d883c --- /dev/null +++ b/docs/sphinxext/codeblockext.py @@ -0,0 +1,258 @@ +# coding=utf-8 +from __future__ import absolute_import + +__author__ = "Gina Häußge " +__license__ = 'The MIT License ' +__copyright__ = "Copyright (C) 2015 Gina Häußge - Released under terms of the MIT License" + +from sphinx.directives.code import CodeBlock + +import sphinx.highlighting +from sphinx.highlighting import PygmentsBridge +from sphinx.ext import doctest +from sphinx.util.texescape import tex_hl_escape_map_new + +from docutils.nodes import General, FixedTextElement, literal_block, container +from docutils.parsers.rst import directives + +from six import text_type + +from pygments import highlight +from pygments.filters import VisibleWhitespaceFilter, ErrorToken +from pygments.lexers.python import PythonConsoleLexer +from pygments.util import ClassNotFound + +def _merge_dict(a, b): + """ + Little helper to merge two dicts a and b on the fly. + """ + result = dict(a) + result.update(b) + return result + +class literal_block_ext(General, FixedTextElement): + """ + Custom node which is basically the same as a :class:`literal_block`, just with whitespace support and introduced + in order to be able to have a custom visitor. + """ + + @classmethod + def from_literal_block(cls, block): + """ + Factory method constructing an instance exactly copying all attributes over from ``block`` and settings a + custom ``tagname``. + """ + new = literal_block_ext() + for a in ("attributes", "basic_attributes", "child_text_separator", "children", "document", "known_attributes", + "line", "list_attributes", "local_attributes", "parent", "rawsource", "source"): + setattr(new, a, getattr(block, a)) + new.tagname = "literal_block_ext" + return new + +class CodeBlockExt(CodeBlock): + """ + This is basically an extension of a regular :class:`CodeBlock` directive which just supports an additional option + ``whitespace`` which if present will enable (together with everything else in here) to render whitespace in + code blocks. + """ + + option_spec = _merge_dict(CodeBlock.option_spec, dict(whitespace=directives.flag)) + + def run(self): + # get result from parent implementation + code_block = CodeBlock.run(self) + + def find_and_wrap_literal_block(node): + """ + Recursive method to turn all literal blocks located within a node into :class:`literal_block_ext`. + """ + + if isinstance(node, container): + # container node => handle all children + children = [] + for child in node.children: + children.append(find_and_wrap_literal_block(child)) + node.children = children + return node + + elif isinstance(node, literal_block): + # literal block => replace it + return self._wrap_literal_block(node) + + else: + # no idea what that is => leave it alone + return node + + # replace all created literal_blocks with literal_block_ext instances + return map(find_and_wrap_literal_block, code_block) + + def _wrap_literal_block(self, node): + literal = literal_block_ext.from_literal_block(node) + literal["whitespace"] = "whitespace" in self.options + return literal + +class PygmentsBridgeExt(object): + """ + Wrapper for :class:`PygmentsBridge`, delegates everything to the wrapped ``bridge`` but :method:`highlight_block`, + which calls the parent implementation for lexer selection, then + """ + + def __init__(self, bridge, whitespace): + self._bridge = bridge + self._whitespace = whitespace + + def __getattr__(self, item): + return getattr(self._bridge, item) + + def highlight_block(self, source, lang, opts=None, warn=None, force=False, **kwargs): + if not self._whitespace: + return self._bridge.highlight_block(source, lang, opts=opts, warn=warn, force=force, **kwargs) + + # We are still here => we need to basically do everything the parent implementation does (and does so in a very + # unextensible way...), but inject the whitespace filter into the used lexer just before the highlighting run + # and remove it afterwards so the lexer can be safely reused. + # + # For this we define a context manager that will allow us to wrap a lexer and modify its filters on the fly to + # include the whitespace filter. + + class whitespace(object): + def __init__(self, lexer): + self._lexer = lexer + self._orig_filters = lexer.filters + self._orig_tabsize = lexer.tabsize + + def __enter__(self): + new_filters = list(self._orig_filters) + new_filters.append(VisibleWhitespaceFilter(spaces=True, tabs=True, tabsize=self._lexer.tabsize)) + self._lexer.filters = new_filters + self._lexer.tabsize = 0 + return self._lexer + + def __exit__(self, type, value, traceback): + self._lexer.filters = self._orig_filters + self._lexer.tabsize = self._orig_tabsize + + # Then a ton of copy-pasted code follows. Sadly, we need to do this since we have no way to inject ourselves + # into the highlighting call otherwise - lexer selection and actual call are tightly coupled in the original + # "highlight_block" method, with no means for external code to inject different functionality. + # + # Unless otherwise marked ("MODIFIED"), any code in this method after this line is copied verbatim from the + # implementation of sphinx.highlighting.PygmentsBridge, released under the Simplified BSD License, the copyright + # lies with the respective authors. + + if not isinstance(source, text_type): + source = source.decode() + + # find out which lexer to use + if lang in ('py', 'python'): + if source.startswith('>>>'): + # interactive session + lexer = sphinx.highlighting.lexers['pycon'] + elif not force: + # maybe Python -- try parsing it + if self.try_parse(source): + lexer = sphinx.highlighting.lexers['python'] + else: + lexer = sphinx.highlighting.lexers['none'] + else: + lexer = sphinx.highlighting.lexers['python'] + elif lang in ('python3', 'py3') and source.startswith('>>>'): + # for py3, recognize interactive sessions, but do not try parsing... + lexer = sphinx.highlighting.lexers['pycon3'] + elif lang == 'guess': + try: + lexer = sphinx.highlighting.guess_lexer(source) + except Exception: + lexer = sphinx.highlighting.lexers['none'] + else: + if lang in sphinx.highlighting.lexers: + lexer = sphinx.highlighting.lexers[lang] + else: + try: + lexer = sphinx.highlighting.lexers[lang] = sphinx.highlighting.get_lexer_by_name(lang, **opts or {}) + except ClassNotFound: + if warn: + warn('Pygments lexer name %r is not known' % lang) + lexer = sphinx.highlighting.lexers['none'] + else: + raise + else: + lexer.add_filter('raiseonerror') + + if not isinstance(source, text_type): + source = source.decode() + + # trim doctest options if wanted + if isinstance(lexer, PythonConsoleLexer) and self._bridge.trim_doctest_flags: + source = doctest.blankline_re.sub('', source) + source = doctest.doctestopt_re.sub('', source) + + # highlight via Pygments + formatter = self._bridge.get_formatter(**kwargs) + try: + # MODIFIED: replaced by whitespace wrapped call + with whitespace(lexer) as l: + hlsource = highlight(source, l, formatter) + # /MODIFIED + except ErrorToken: + # this is most probably not the selected language, + # so let it pass unhighlighted + + # MODIFIED: replaced by whitespace wrapped call + with whitespace(sphinx.highlighting.lexers["none"]) as l: + hlsource = highlight(source, l, formatter) + # /MODIFIED + if self._bridge.dest == 'html': + return hlsource + else: + if not isinstance(hlsource, text_type): # Py2 / Pygments < 1.6 + hlsource = hlsource.decode() + return hlsource.translate(tex_hl_escape_map_new) + + +class whitespace_highlighter(object): + """ + Context manager for adapting the used highlighter on a translator for a given node's whitespace properties. + """ + def __init__(self, translator, node): + self.translator = translator + self.node = node + + self._orig_highlighter = self.translator.highlighter + + def __enter__(self): + whitespace = self.node["whitespace"] if "whitespace" in self.node else False + if whitespace: + self.translator.highlighter = PygmentsBridgeExt(self._orig_highlighter, whitespace) + return self.translator + + def __exit__(self, exc_type, exc_val, exc_tb): + self.translator.highlighter = self._orig_highlighter + + +def visit_literal_block_ext(translator, node): + """ + When our custom code block is visited, we temporarily exchange the highlighter used in the translator, call the + visitor for regular literal blocks, then switch back again. + """ + with whitespace_highlighter(translator, node): + translator.visit_literal_block(node) + + +def depart_literal_block_ext(translator, node): + """ + Just call the depart function for regular literal blocks. + """ + with whitespace_highlighter(translator, node): + translator.depart_literal_block(node) + + +def setup(app): + # custom directive + app.add_directive("code-block-ext", CodeBlockExt) + + # custom node type + handler = (visit_literal_block_ext, depart_literal_block_ext) + app.add_node(literal_block_ext, html=handler, latex=handler, text=handler) + + return dict(version="0.1") \ No newline at end of file diff --git a/requirements-bbb.txt b/requirements-bbb.txt deleted file mode 100644 index 127383ed..00000000 --- a/requirements-bbb.txt +++ /dev/null @@ -1,15 +0,0 @@ -flask==0.9 -werkzeug==0.8.3 -tornado==3.0.2 -sockjs-tornado>=1.0.0 -PyYAML==3.10 -Flask-Login==0.2.2 -Flask-Principal==0.3.5 -netaddr>=0.7.10 -mock>=1.0.1 -nose>=1.3.0 -watchdog -sarge - -sphinxcontrib-httpdomain -sphinx_rtd_theme diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index cac003f2..00000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Testing dependencies -mock>=1.0.1 -nose>=1.3.0 -ddt - -# Documentation dependencies -sphinxcontrib-httpdomain -sphinxcontrib-napoleon -sphinx_rtd_theme - -# Translation dependencies -po2json diff --git a/requirements.txt b/requirements.txt index 5dbe7218..9347fd9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,11 @@ -flask==0.9 -werkzeug==0.8.3 -tornado==4.0.1 -sockjs-tornado>=1.0.0 -PyYAML==3.10 -Flask-Login==0.2.2 -Flask-Principal==0.3.5 -Flask-Babel==0.9 -pyserial -netaddr -watchdog -sarge>=0.1.4 -netifaces -pylru -rsa -pkginfo +### +# This file is only here to make sure that something like +# +# pip install -e .[develop] +# +# works as expected. Requirements can be found in setup.py in the +# variables INSTALL_REQUIRES and EXTRA_REQUIRES. +### + +--process-dependency-links +. diff --git a/setup.py b/setup.py index 3d2b59a3..aa40fa9e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,64 @@ -# coding=utf-8 #!/usr/bin/env python +# coding=utf-8 +from setuptools import setup, find_packages, Command +import os +import shutil +import glob import versioneer + +#----------------------------------------------------------------------------------------------------------------------- + +# Requirements for out application +INSTALL_REQUIRES = [ + "flask==0.9", + "werkzeug==0.8.3", + "tornado==4.0.1", + "sockjs-tornado>=1.0.0", + "PyYAML==3.10", + "Flask-Login==0.2.2", + "Flask-Principal==0.3.5", + "Flask-Babel==0.9", + "pyserial", + "netaddr", + "watchdog", + "sarge>=0.1.4", + "netifaces", + "pylru", + "rsa", + "pkginfo" +] + +# Requirements for developing etc +EXTRA_REQUIRES = dict( + develop=[ + # Testing dependencies + "mock>=1.0.1", + "nose>=1.3.0", + "ddt", + + # Documentation dependencies + "sphinx>=1.3", + "sphinxcontrib-httpdomain", + "sphinx_rtd_theme", + + # Translation dependencies + "po2json" + ] +) + +# Dependency links for any of the aforementioned dependencies +DEPENDENCY_LINKS = [] + +# I18N setup +I18N_MAPPING_FILE = "babel.cfg" +I18N_DOMAIN = "messages" +I18N_INPUT_DIRS = "." +I18N_OUTPUT_DIR_PY = os.path.join("src", "octoprint", "translations") +I18N_OUTPUT_DIR_JS = os.path.join("src", "octoprint", "static", "js", "i18n") +I18N_POT_FILE = os.path.join(I18N_OUTPUT_DIR_PY, "messages.pot") + +# Versioneer configuration versioneer.VCS = 'git' versioneer.versionfile_source = 'src/octoprint/_version.py' versioneer.versionfile_build = 'octoprint/_version.py' @@ -9,17 +66,8 @@ versioneer.tag_prefix = '' versioneer.parentdir_prefix = '' versioneer.lookupfile = '.versioneer-lookup' -from setuptools import setup, find_packages, Command -import os -import shutil -import glob - -I18N_MAPPING_FILE = "babel.cfg" -I18N_DOMAIN = "messages" -I18N_INPUT_DIRS = "." -I18N_OUTPUT_DIR_PY = os.path.join("src", "octoprint", "translations") -I18N_OUTPUT_DIR_JS = os.path.join("src", "octoprint", "static", "js", "i18n") -I18N_POT_FILE = os.path.join(I18N_OUTPUT_DIR_PY, "messages.pot") +#----------------------------------------------------------------------------------------------------------------------- +# Anything below here is just command setup and general setup configuration def package_data_dirs(source, sub_folders): dirs = [] @@ -250,10 +298,6 @@ def get_cmdclass(): return cmdclass -def requirements(filename): - return filter(lambda line: line and not line.startswith("#"), map(lambda line: line.strip(), open(filename).read().split("\n"))) - - def params(): name = "OctoPrint" version = versioneer.get_version() @@ -291,14 +335,13 @@ def params(): include_package_data = True zip_safe = False - install_requires = requirements("requirements.txt") - extras_require = dict( - develop=requirements("requirements-dev.txt") - ) + install_requires = INSTALL_REQUIRES + extras_require = EXTRA_REQUIRES + dependency_links = DEPENDENCY_LINKS if os.environ.get('READTHEDOCS', None) == 'True': # we can't tell read the docs to please perform a pip install -e .[develop], so we help - # it a bit here by explicitely adding the development dependencies, which include our + # it a bit here by explicitly adding the development dependencies, which include our # documentation dependencies install_requires = install_requires + extras_require['develop'] @@ -308,10 +351,6 @@ def params(): ] } - #scripts = { - # "scripts/octoprint.init": "/etc/init.d/octoprint" - #} - return locals() setup(**params()) diff --git a/src/octoprint/static/css/octoprint.css b/src/octoprint/static/css/octoprint.css index 73043d1a..19f0af91 100644 --- a/src/octoprint/static/css/octoprint.css +++ b/src/octoprint/static/css/octoprint.css @@ -1 +1 @@ -.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{border-color:transparent;cursor:pointer;color:#08c;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.nowrap{white-space:nowrap}.actioncol{text-align:center;white-space:nowrap}.actioncol a{text-decoration:none;color:#000}.actioncol a.disabled{color:#ccc;cursor:default}#navbar .navbar-inner{background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#navbar .navbar-inner .brand,#navbar .navbar-inner .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner .brand .caret,#navbar .navbar-inner .nav>li>a .caret{border-bottom-color:#939393;border-top-color:#939393}#navbar .navbar-inner .brand:hover .caret,#navbar .navbar-inner .nav>li>a:hover .caret,#navbar .navbar-inner .brand:focus .caret,#navbar .navbar-inner .nav>li>a:focus .caret{border-bottom-color:#636363;border-top-color:#636363}#navbar .navbar-inner .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e0e0e0;background-image:-moz-linear-gradient(top,#ccc,#fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(top,#ccc,#fff);background-image:-o-linear-gradient(top,#ccc,#fff);background-image:linear-gradient(to bottom,#ccc,#fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffcccccc',endColorstr='#ffffffff',GradientType=0)}#navbar .navbar-inner.transparent{background-color:rgba(235,235,235,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,0.6)),to(rgba(204,204,204,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99ffffff',endColorstr='#99cccccc',GradientType=0)}#navbar .navbar-inner.transparent .brand,#navbar .navbar-inner.transparent .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.transparent .brand .caret,#navbar .navbar-inner.transparent .nav>li>a .caret{border-bottom-color:#939393;border-top-color:#939393}#navbar .navbar-inner.transparent .brand:hover .caret,#navbar .navbar-inner.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.transparent .brand:focus .caret,#navbar .navbar-inner.transparent .nav>li>a:focus .caret{border-bottom-color:#636363;border-top-color:#636363}#navbar .navbar-inner.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(224,224,224,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(204,204,204,0.6)),to(rgba(255,255,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99cccccc',endColorstr='#99ffffff',GradientType=0)}#navbar .navbar-inner.red{background-color:#bb645f;background-image:-moz-linear-gradient(top,#e28e8a,#802420);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e28e8a),to(#802420));background-image:-webkit-linear-gradient(top,#e28e8a,#802420);background-image:-o-linear-gradient(top,#e28e8a,#802420);background-image:linear-gradient(to bottom,#e28e8a,#802420);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe28e8a',endColorstr='#ff802420',GradientType=0)}#navbar .navbar-inner.red .brand,#navbar .navbar-inner.red .nav>li>a{text-shadow:0 1px 0 #802420;color:#f2f2f2}#navbar .navbar-inner.red .brand .caret,#navbar .navbar-inner.red .nav>li>a .caret{border-bottom-color:#d89491;border-top-color:#d89491}#navbar .navbar-inner.red .brand:hover .caret,#navbar .navbar-inner.red .nav>li>a:hover .caret,#navbar .navbar-inner.red .brand:focus .caret,#navbar .navbar-inner.red .nav>li>a:focus .caret{border-bottom-color:#e5c3c1;border-top-color:#e5c3c1}#navbar .navbar-inner.red .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.red .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.red .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open.active>.dropdown-toggle{background-color:#a74f4a;background-image:-moz-linear-gradient(top,#802420,#e28e8a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#802420),to(#e28e8a));background-image:-webkit-linear-gradient(top,#802420,#e28e8a);background-image:-o-linear-gradient(top,#802420,#e28e8a);background-image:linear-gradient(to bottom,#802420,#e28e8a);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff802420',endColorstr='#ffe28e8a',GradientType=0)}#navbar .navbar-inner.red.transparent{background-color:rgba(187,100,95,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(226,142,138,0.6)),to(rgba(128,36,32,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99e28e8a',endColorstr='#99802420',GradientType=0)}#navbar .navbar-inner.red.transparent .brand,#navbar .navbar-inner.red.transparent .nav>li>a{text-shadow:0 1px 0 #802420;color:#f2f2f2}#navbar .navbar-inner.red.transparent .brand .caret,#navbar .navbar-inner.red.transparent .nav>li>a .caret{border-bottom-color:#d89491;border-top-color:#d89491}#navbar .navbar-inner.red.transparent .brand:hover .caret,#navbar .navbar-inner.red.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.red.transparent .brand:focus .caret,#navbar .navbar-inner.red.transparent .nav>li>a:focus .caret{border-bottom-color:#e5c3c1;border-top-color:#e5c3c1}#navbar .navbar-inner.red.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.red.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.red.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(167,79,74,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(128,36,32,0.6)),to(rgba(226,142,138,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99802420',endColorstr='#99e28e8a',GradientType=0)}#navbar .navbar-inner.orange{background-color:#e39665;background-image:-moz-linear-gradient(top,#f9c3a0,#c2530c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f9c3a0),to(#c2530c));background-image:-webkit-linear-gradient(top,#f9c3a0,#c2530c);background-image:-o-linear-gradient(top,#f9c3a0,#c2530c);background-image:linear-gradient(to bottom,#f9c3a0,#c2530c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9c3a0',endColorstr='#ffc2530c',GradientType=0)}#navbar .navbar-inner.orange .brand,#navbar .navbar-inner.orange .nav>li>a{text-shadow:0 1px 0 #f6a570;color:#f2f2f2}#navbar .navbar-inner.orange .brand .caret,#navbar .navbar-inner.orange .nav>li>a .caret{border-bottom-color:#f2b58d;border-top-color:#f2b58d}#navbar .navbar-inner.orange .brand:hover .caret,#navbar .navbar-inner.orange .nav>li>a:hover .caret,#navbar .navbar-inner.orange .brand:focus .caret,#navbar .navbar-inner.orange .nav>li>a:focus .caret{border-bottom-color:#f2d3c0;border-top-color:#f2d3c0}#navbar .navbar-inner.orange .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.orange .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.orange .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open.active>.dropdown-toggle{background-color:#d88047;background-image:-moz-linear-gradient(top,#c2530c,#f9c3a0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c2530c),to(#f9c3a0));background-image:-webkit-linear-gradient(top,#c2530c,#f9c3a0);background-image:-o-linear-gradient(top,#c2530c,#f9c3a0);background-image:linear-gradient(to bottom,#c2530c,#f9c3a0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc2530c',endColorstr='#fff9c3a0',GradientType=0)}#navbar .navbar-inner.orange.transparent{background-color:rgba(227,150,101,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,195,160,0.6)),to(rgba(194,83,12,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99f9c3a0',endColorstr='#99c2530c',GradientType=0)}#navbar .navbar-inner.orange.transparent .brand,#navbar .navbar-inner.orange.transparent .nav>li>a{text-shadow:0 1px 0 #f6a570;color:#f2f2f2}#navbar .navbar-inner.orange.transparent .brand .caret,#navbar .navbar-inner.orange.transparent .nav>li>a .caret{border-bottom-color:#f2b58d;border-top-color:#f2b58d}#navbar .navbar-inner.orange.transparent .brand:hover .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.orange.transparent .brand:focus .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:focus .caret{border-bottom-color:#f2d3c0;border-top-color:#f2d3c0}#navbar .navbar-inner.orange.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.orange.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.orange.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(216,128,71,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,83,12,0.6)),to(rgba(249,195,160,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c2530c',endColorstr='#99f9c3a0',GradientType=0)}#navbar .navbar-inner.yellow{background-color:#e3d765;background-image:-moz-linear-gradient(top,#f9f0a0,#c2b00c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f9f0a0),to(#c2b00c));background-image:-webkit-linear-gradient(top,#f9f0a0,#c2b00c);background-image:-o-linear-gradient(top,#f9f0a0,#c2b00c);background-image:linear-gradient(to bottom,#f9f0a0,#c2b00c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f0a0',endColorstr='#ffc2b00c',GradientType=0)}#navbar .navbar-inner.yellow .brand,#navbar .navbar-inner.yellow .nav>li>a{text-shadow:0 1px 0 #f6e970;color:#333}#navbar .navbar-inner.yellow .brand .caret,#navbar .navbar-inner.yellow .nav>li>a .caret{border-bottom-color:#93892e;border-top-color:#93892e}#navbar .navbar-inner.yellow .brand:hover .caret,#navbar .navbar-inner.yellow .nav>li>a:hover .caret,#navbar .navbar-inner.yellow .brand:focus .caret,#navbar .navbar-inner.yellow .nav>li>a:focus .caret{border-bottom-color:#635e30;border-top-color:#635e30}#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.yellow .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open.active>.dropdown-toggle{background-color:#d8ca47;background-image:-moz-linear-gradient(top,#c2b00c,#f9f0a0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c2b00c),to(#f9f0a0));background-image:-webkit-linear-gradient(top,#c2b00c,#f9f0a0);background-image:-o-linear-gradient(top,#c2b00c,#f9f0a0);background-image:linear-gradient(to bottom,#c2b00c,#f9f0a0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc2b00c',endColorstr='#fff9f0a0',GradientType=0)}#navbar .navbar-inner.yellow.transparent{background-color:rgba(227,215,101,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,240,160,0.6)),to(rgba(194,176,12,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99f9f0a0',endColorstr='#99c2b00c',GradientType=0)}#navbar .navbar-inner.yellow.transparent .brand,#navbar .navbar-inner.yellow.transparent .nav>li>a{text-shadow:0 1px 0 #f6e970;color:#333}#navbar .navbar-inner.yellow.transparent .brand .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a .caret{border-bottom-color:#93892e;border-top-color:#93892e}#navbar .navbar-inner.yellow.transparent .brand:hover .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.yellow.transparent .brand:focus .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:focus .caret{border-bottom-color:#635e30;border-top-color:#635e30}#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(216,202,71,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,176,12,0.6)),to(rgba(249,240,160,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c2b00c',endColorstr='#99f9f0a0',GradientType=0)}#navbar .navbar-inner.green{background-color:#98f064;background-image:-moz-linear-gradient(top,#c8ffa7,#50da00);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8ffa7),to(#50da00));background-image:-webkit-linear-gradient(top,#c8ffa7,#50da00);background-image:-o-linear-gradient(top,#c8ffa7,#50da00);background-image:linear-gradient(to bottom,#c8ffa7,#50da00);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8ffa7',endColorstr='#ff50da00',GradientType=0)}#navbar .navbar-inner.green .brand,#navbar .navbar-inner.green .nav>li>a{text-shadow:0 1px 0 #a7ff74;color:#333}#navbar .navbar-inner.green .brand .caret,#navbar .navbar-inner.green .nav>li>a .caret{border-bottom-color:#55992e;border-top-color:#55992e}#navbar .navbar-inner.green .brand:hover .caret,#navbar .navbar-inner.green .nav>li>a:hover .caret,#navbar .navbar-inner.green .brand:focus .caret,#navbar .navbar-inner.green .nav>li>a:focus .caret{border-bottom-color:#446630;border-top-color:#446630}#navbar .navbar-inner.green .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.green .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.green .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open.active>.dropdown-toggle{background-color:#80e943;background-image:-moz-linear-gradient(top,#50da00,#c8ffa7);background-image:-webkit-gradient(linear,0 0,0 100%,from(#50da00),to(#c8ffa7));background-image:-webkit-linear-gradient(top,#50da00,#c8ffa7);background-image:-o-linear-gradient(top,#50da00,#c8ffa7);background-image:linear-gradient(to bottom,#50da00,#c8ffa7);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff50da00',endColorstr='#ffc8ffa7',GradientType=0)}#navbar .navbar-inner.green.transparent{background-color:rgba(152,240,100,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,255,167,0.6)),to(rgba(80,218,0,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8ffa7',endColorstr='#9950da00',GradientType=0)}#navbar .navbar-inner.green.transparent .brand,#navbar .navbar-inner.green.transparent .nav>li>a{text-shadow:0 1px 0 #a7ff74;color:#333}#navbar .navbar-inner.green.transparent .brand .caret,#navbar .navbar-inner.green.transparent .nav>li>a .caret{border-bottom-color:#55992e;border-top-color:#55992e}#navbar .navbar-inner.green.transparent .brand:hover .caret,#navbar .navbar-inner.green.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.green.transparent .brand:focus .caret,#navbar .navbar-inner.green.transparent .nav>li>a:focus .caret{border-bottom-color:#446630;border-top-color:#446630}#navbar .navbar-inner.green.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.green.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.green.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(128,233,67,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,218,0,0.6)),to(rgba(200,255,167,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9950da00',endColorstr='#99c8ffa7',GradientType=0)}#navbar .navbar-inner.blue{background-color:#2e63cc;background-image:-moz-linear-gradient(top,#4d88ff,#002b80);background-image:-webkit-gradient(linear,0 0,0 100%,from(#4d88ff),to(#002b80));background-image:-webkit-linear-gradient(top,#4d88ff,#002b80);background-image:-o-linear-gradient(top,#4d88ff,#002b80);background-image:linear-gradient(to bottom,#4d88ff,#002b80);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d88ff',endColorstr='#ff002b80',GradientType=0)}#navbar .navbar-inner.blue .brand,#navbar .navbar-inner.blue .nav>li>a{text-shadow:0 1px 0 #002b80;color:#f2f2f2}#navbar .navbar-inner.blue .brand .caret,#navbar .navbar-inner.blue .nav>li>a .caret{border-bottom-color:#799bdf;border-top-color:#799bdf}#navbar .navbar-inner.blue .brand:hover .caret,#navbar .navbar-inner.blue .nav>li>a:hover .caret,#navbar .navbar-inner.blue .brand:focus .caret,#navbar .navbar-inner.blue .nav>li>a:focus .caret{border-bottom-color:#b6c7e9;border-top-color:#b6c7e9}#navbar .navbar-inner.blue .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.blue .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.blue .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open.active>.dropdown-toggle{background-color:#1f50b3;background-image:-moz-linear-gradient(top,#002b80,#4d88ff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#002b80),to(#4d88ff));background-image:-webkit-linear-gradient(top,#002b80,#4d88ff);background-image:-o-linear-gradient(top,#002b80,#4d88ff);background-image:linear-gradient(to bottom,#002b80,#4d88ff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff002b80',endColorstr='#ff4d88ff',GradientType=0)}#navbar .navbar-inner.blue.transparent{background-color:rgba(46,99,204,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(77,136,255,0.6)),to(rgba(0,43,128,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#994d88ff',endColorstr='#99002b80',GradientType=0)}#navbar .navbar-inner.blue.transparent .brand,#navbar .navbar-inner.blue.transparent .nav>li>a{text-shadow:0 1px 0 #002b80;color:#f2f2f2}#navbar .navbar-inner.blue.transparent .brand .caret,#navbar .navbar-inner.blue.transparent .nav>li>a .caret{border-bottom-color:#799bdf;border-top-color:#799bdf}#navbar .navbar-inner.blue.transparent .brand:hover .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.blue.transparent .brand:focus .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:focus .caret{border-bottom-color:#b6c7e9;border-top-color:#b6c7e9}#navbar .navbar-inner.blue.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.blue.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.blue.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(31,80,179,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(0,43,128,0.6)),to(rgba(77,136,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99002b80',endColorstr='#994d88ff',GradientType=0)}#navbar .navbar-inner.violet{background-color:#9864f0;background-image:-moz-linear-gradient(top,#c8a7ff,#5000da);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8a7ff),to(#5000da));background-image:-webkit-linear-gradient(top,#c8a7ff,#5000da);background-image:-o-linear-gradient(top,#c8a7ff,#5000da);background-image:linear-gradient(to bottom,#c8a7ff,#5000da);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8a7ff',endColorstr='#ff5000da',GradientType=0)}#navbar .navbar-inner.violet .brand,#navbar .navbar-inner.violet .nav>li>a{text-shadow:0 1px 0 #5000da;color:#f2f2f2}#navbar .navbar-inner.violet .brand .caret,#navbar .navbar-inner.violet .nav>li>a .caret{border-bottom-color:#b58df9;border-top-color:#b58df9}#navbar .navbar-inner.violet .brand:hover .caret,#navbar .navbar-inner.violet .nav>li>a:hover .caret,#navbar .navbar-inner.violet .brand:focus .caret,#navbar .navbar-inner.violet .nav>li>a:focus .caret{border-bottom-color:#d3c0f5;border-top-color:#d3c0f5}#navbar .navbar-inner.violet .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.violet .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.violet .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open.active>.dropdown-toggle{background-color:#8043e9;background-image:-moz-linear-gradient(top,#5000da,#c8a7ff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5000da),to(#c8a7ff));background-image:-webkit-linear-gradient(top,#5000da,#c8a7ff);background-image:-o-linear-gradient(top,#5000da,#c8a7ff);background-image:linear-gradient(to bottom,#5000da,#c8a7ff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5000da',endColorstr='#ffc8a7ff',GradientType=0)}#navbar .navbar-inner.violet.transparent{background-color:rgba(152,100,240,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,167,255,0.6)),to(rgba(80,0,218,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8a7ff',endColorstr='#995000da',GradientType=0)}#navbar .navbar-inner.violet.transparent .brand,#navbar .navbar-inner.violet.transparent .nav>li>a{text-shadow:0 1px 0 #5000da;color:#f2f2f2}#navbar .navbar-inner.violet.transparent .brand .caret,#navbar .navbar-inner.violet.transparent .nav>li>a .caret{border-bottom-color:#b58df9;border-top-color:#b58df9}#navbar .navbar-inner.violet.transparent .brand:hover .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.violet.transparent .brand:focus .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:focus .caret{border-bottom-color:#d3c0f5;border-top-color:#d3c0f5}#navbar .navbar-inner.violet.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.violet.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.violet.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(128,67,233,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,0,218,0.6)),to(rgba(200,167,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#995000da',endColorstr='#99c8a7ff',GradientType=0)}#navbar .navbar-inner.black{background-color:#4f4f4f;background-image:-moz-linear-gradient(top,#787878,#121212);background-image:-webkit-gradient(linear,0 0,0 100%,from(#787878),to(#121212));background-image:-webkit-linear-gradient(top,#787878,#121212);background-image:-o-linear-gradient(top,#787878,#121212);background-image:linear-gradient(to bottom,#787878,#121212);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff787878',endColorstr='#ff121212',GradientType=0)}#navbar .navbar-inner.black .brand,#navbar .navbar-inner.black .nav>li>a{text-shadow:0 1px 0 #121212;color:#f2f2f2}#navbar .navbar-inner.black .brand .caret,#navbar .navbar-inner.black .nav>li>a .caret{border-bottom-color:#959595;border-top-color:#959595}#navbar .navbar-inner.black .brand:hover .caret,#navbar .navbar-inner.black .nav>li>a:hover .caret,#navbar .navbar-inner.black .brand:focus .caret,#navbar .navbar-inner.black .nav>li>a:focus .caret{border-bottom-color:#c4c4c4;border-top-color:#c4c4c4}#navbar .navbar-inner.black .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.black .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.black .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open.active>.dropdown-toggle{background-color:#3b3b3b;background-image:-moz-linear-gradient(top,#121212,#787878);background-image:-webkit-gradient(linear,0 0,0 100%,from(#121212),to(#787878));background-image:-webkit-linear-gradient(top,#121212,#787878);background-image:-o-linear-gradient(top,#121212,#787878);background-image:linear-gradient(to bottom,#121212,#787878);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff121212',endColorstr='#ff787878',GradientType=0)}#navbar .navbar-inner.black.transparent{background-color:rgba(79,79,79,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(120,120,120,0.6)),to(rgba(18,18,18,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99787878',endColorstr='#99121212',GradientType=0)}#navbar .navbar-inner.black.transparent .brand,#navbar .navbar-inner.black.transparent .nav>li>a{text-shadow:0 1px 0 #121212;color:#f2f2f2}#navbar .navbar-inner.black.transparent .brand .caret,#navbar .navbar-inner.black.transparent .nav>li>a .caret{border-bottom-color:#959595;border-top-color:#959595}#navbar .navbar-inner.black.transparent .brand:hover .caret,#navbar .navbar-inner.black.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.black.transparent .brand:focus .caret,#navbar .navbar-inner.black.transparent .nav>li>a:focus .caret{border-bottom-color:#c4c4c4;border-top-color:#c4c4c4}#navbar .navbar-inner.black.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.black.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.black.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(59,59,59,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(18,18,18,0.6)),to(rgba(120,120,120,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99121212',endColorstr='#99787878',GradientType=0)}#navbar .navbar-inner.white{background-color:#e9e9e9;background-image:-moz-linear-gradient(top,#fff,#c8c8c8);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#c8c8c8));background-image:-webkit-linear-gradient(top,#fff,#c8c8c8);background-image:-o-linear-gradient(top,#fff,#c8c8c8);background-image:linear-gradient(to bottom,#fff,#c8c8c8);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffc8c8c8',GradientType=0)}#navbar .navbar-inner.white .brand,#navbar .navbar-inner.white .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.white .brand .caret,#navbar .navbar-inner.white .nav>li>a .caret{border-bottom-color:#919191;border-top-color:#919191}#navbar .navbar-inner.white .brand:hover .caret,#navbar .navbar-inner.white .nav>li>a:hover .caret,#navbar .navbar-inner.white .brand:focus .caret,#navbar .navbar-inner.white .nav>li>a:focus .caret{border-bottom-color:#626262;border-top-color:#626262}#navbar .navbar-inner.white .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.white .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.white .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open.active>.dropdown-toggle{background-color:#dedede;background-image:-moz-linear-gradient(top,#c8c8c8,#fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8c8c8),to(#fff));background-image:-webkit-linear-gradient(top,#c8c8c8,#fff);background-image:-o-linear-gradient(top,#c8c8c8,#fff);background-image:linear-gradient(to bottom,#c8c8c8,#fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8c8c8',endColorstr='#ffffffff',GradientType=0)}#navbar .navbar-inner.white.transparent{background-color:rgba(233,233,233,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,0.6)),to(rgba(200,200,200,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99ffffff',endColorstr='#99c8c8c8',GradientType=0)}#navbar .navbar-inner.white.transparent .brand,#navbar .navbar-inner.white.transparent .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.white.transparent .brand .caret,#navbar .navbar-inner.white.transparent .nav>li>a .caret{border-bottom-color:#919191;border-top-color:#919191}#navbar .navbar-inner.white.transparent .brand:hover .caret,#navbar .navbar-inner.white.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.white.transparent .brand:focus .caret,#navbar .navbar-inner.white.transparent .nav>li>a:focus .caret{border-bottom-color:#626262;border-top-color:#626262}#navbar .navbar-inner.white.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.white.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.white.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(222,222,222,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,200,200,0.6)),to(rgba(255,255,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8c8c8',endColorstr='#99ffffff',GradientType=0)}#navbar .navbar-inner .brand span{background-size:20px 20px;background-position:left center;padding-left:24px;background-repeat:no-repeat}.octoprint-container{margin-top:20px}.octoprint-container .tab-content{padding:9px 15px;border-left:1px solid #DDD;border-right:1px solid #DDD;border-bottom:1px solid #DDD;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.octoprint-container .nav{margin-bottom:0}.octoprint-container .tab-content h1{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5;font-weight:normal}.octoprint-container .accordion-heading .accordion-heading-button{float:right}.octoprint-container .accordion-heading .accordion-heading-button a{display:inline-block;padding:8px 15px;font-size:14px;line-height:20px;color:#000;text-decoration:none;background:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.octoprint-container .accordion-heading a.accordion-toggle{display:inline-block}.octoprint-container .accordion-heading [class^="icon-"],.octoprint-container .accordion-heading [class*=" icon-"]{color:#000}.print-control .btn{padding-left:4px;padding-right:4px}.upload-buttons .btn{margin-right:0}table{table-layout:fixed}table .popover-title{text-overflow:ellipsis;word-break:break-all}table th,table td{overflow:hidden}table th.gcode_files_name,table td.gcode_files_name{text-overflow:ellipsis;text-align:left;white-space:nowrap}table th.gcode_files_action,table td.gcode_files_action{width:90px;text-align:center;white-space:nowrap}table th.gcode_files_action a,table td.gcode_files_action a{text-decoration:none;color:#000}table th.gcode_files_action a.disabled,table td.gcode_files_action a.disabled{color:#ccc;cursor:default}table th.timelapse_files_name,table td.timelapse_files_name{text-overflow:ellipsis;text-align:left}table th.timelapse_files_size,table td.timelapse_files_size{text-align:right;width:55px}table th.timelapse_files_action,table td.timelapse_files_action{width:45px;text-align:center;white-space:nowrap}table th.timelapse_files_action a,table td.timelapse_files_action a{text-decoration:none;color:#000}table th.timelapse_files_action a.disabled,table td.timelapse_files_action a.disabled{color:#ccc;cursor:default}table th.settings_users_name,table td.settings_users_name{text-overflow:ellipsis;text-align:left}table th.settings_users_active,table td.settings_users_active,table th.settings_users_admin,table td.settings_users_admin{text-align:center;width:55px}table th.settings_users_actions,table td.settings_users_actions{width:60px;text-align:center;white-space:nowrap}table th.settings_users_actions a,table td.settings_users_actions a{text-decoration:none;color:#000}table th.settings_users_actions a.disabled,table td.settings_users_actions a.disabled{color:#ccc;cursor:default}table th.settings_logs_name,table td.settings_logs_name{text-overflow:ellipsis;text-align:left}table th.settings_logs_size,table td.settings_logs_size{text-align:right;width:70px}table th.settings_logs_date,table td.settings_logs_date{text-align:left;width:130px}table th.settings_logs_action,table td.settings_logs_action{width:70px;text-align:center;white-space:nowrap}table th.settings_logs_action a,table td.settings_logs_action a{text-decoration:none;color:#000}table th.settings_logs_action a.disabled,table td.settings_logs_action a.disabled{color:#ccc;cursor:default}table th.settings_printerProfiles_profiles_name,table td.settings_printerProfiles_profiles_name{text-overflow:ellipsis;text-align:left}table th.settings_printerProfiles_profiles_model,table td.settings_printerProfiles_profiles_model{text-align:left;width:250px}table th.settings_printerProfiles_profiles_action,table td.settings_printerProfiles_profiles_action{width:80px;text-align:center;white-space:nowrap}table th.settings_printerProfiles_profiles_action a,table td.settings_printerProfiles_profiles_action a{text-decoration:none;color:#000}table th.settings_printerProfiles_profiles_action a.disabled,table td.settings_printerProfiles_profiles_action a.disabled{color:#ccc;cursor:default}#temperature-graph{height:350px;width:100%;background-image:url("../img/graph-background.png");background-position:center;background-repeat:no-repeat}.tab-content,.tab-pane{overflow:visible}.tempInput{width:50px}#temp_newTemp,#temp_newBedTemp,#speed_innerWall,#speed_outerWall,#speed_fill,#speed_support,#webcam_timelapse_interval,#webcam_timelapse_postRoll,#webcam_timelapse_fps{text-align:right}ul.dropdown-menu li a{cursor:pointer}#connection_ports,#connection_baudrates,#connection_printers{width:100%}#offline_overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:10000;display:none}#offline_overlay_background{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#offline_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#offline_overlay_wrapper .container{margin:auto}#webcam_container{width:100%;position:relative;outline:0}#webcam_container .flipH{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1)}#webcam_container .flipV{-webkit-transform:scaleY(-1);-moz-transform:scaleY(-1)}#webcam_container .flipH.flipV{-webkit-transform:scaleX(-1) scaleY(-1);-moz-transform:scaleX(-1) scaleY(-1)}#webcam_container .keycontrol_overlay{position:absolute;left:10px;right:10px;bottom:10px;background:rgba(0,0,0,0.5);font-size:85%;color:white;padding:0}#webcam_container .keycontrol_overlay kbd{border:1px solid #eee;border-radius:3px;margin-left:2px;margin-right:2px;font-size:90%;padding:2px;min-width:1em}#webcam_container .keycontrol_overlay .keycontrol_overlay_heading{position:relative;padding:10px;font-weight:bold}#webcam_container .keycontrol_overlay .keycontrol_overlay_column{position:relative;width:45%;padding:10px;float:left}#files .gcode_files{padding-right:7px}#files .gcode_files .entry{padding:5px;line-height:20px;border-bottom:1px solid #ddd;position:relative}#files .gcode_files .entry:hover{background-color:#f5f5f5}#files .gcode_files .entry .title{text-overflow:ellipsis;word-break:break-all}#files .gcode_files .entry .uploaded,#files .gcode_files .entry .size,#files .gcode_files .entry .additionalInfo{font-size:85%;color:#999}#files .gcode_files .entry .action-buttons{position:absolute;bottom:5px;right:5px}#files .gcode_files .entry .additionalInfo{padding-bottom:22px}#files .upload-buttons{margin-top:10px}#files .form-search{text-align:center;margin-bottom:5px!important}#control{overflow:hidden}#control .jog-panel{float:left;margin-right:19px}#control h1{text-align:left}#control .jog-panel>div{text-align:center}#control .jog-panel>div.distance{text-align:left}#control .jog-panel .slider{margin-bottom:10px}#control .box{width:30px;height:30px;margin-right:10px;margin-bottom:10px;padding-left:8px}#control .control-box{display:block;height:30px;margin-bottom:10px}#control .btn-group{margin-bottom:10px}#control .btn-group.distance>.btn{width:43px;padding:3px 0;height:30px}#control .slider-handle{width:14px;height:14px;margin-left:-7px;margin-top:-3px}#control .custom_parametric_command .slider{margin-left:10px;margin-right:10px;margin-bottom:2px}#gcode .progress{width:582px}#gcode .progress .bar{-webkit-transition:width 0s linear;-moz-transition:width 0s linear;-o-transition:width 0s linear;transition:width 0s linear}#gcode #gcode_layer_slider{height:568px;float:right}#gcode #gcode_layer_slider .slider-handle{width:14px;height:14px;margin-left:-3px;margin-top:-7px}#gcode #gcode_command_slider .slider-handle{width:14px;height:14px;margin-left:-7px;margin-top:-3px}#term .terminal{margin-bottom:30px}#term .terminal #terminal-output{min-height:340px;margin-bottom:5px}#term #terminal-sendpanel{text-align:right}.footer ul{margin:0}.footer ul li{display:inline;margin-left:1em;font-size:85%}.footer ul li:first-child{margin-left:0}.footer ul li a{color:#555}.ui-pnotify .alert a{color:#c09853}.ui-pnotify .alert-error a,.ui-pnotify .alert-danger a{color:#b94a48}.ui-pnotify .alert-success a{color:#468847}.ui-pnotify .alert-info a{color:#3a87ad}.pnotify_additional_info .pnotify_more{font-size:85%}.text-right{text-align:right}.overflow_visible{overflow:visible!important}.border_box{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none}textarea.block{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%}#drop_overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:10000;display:none}#drop_overlay.in{display:block}#drop_overlay #drop_overlay_background{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#drop_overlay #drop_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#drop_overlay #drop_overlay_wrapper #drop,#drop_overlay #drop_overlay_wrapper #drop_background{position:absolute;top:0;left:0;margin-left:0;width:100%}#drop_overlay #drop_overlay_wrapper #drop_locally,#drop_overlay #drop_overlay_wrapper #drop_locally_background{position:absolute;top:0;left:50%;margin-left:-50%;width:50%;border-right:2px dashed #ccc}#drop_overlay #drop_overlay_wrapper #drop_sd,#drop_overlay #drop_overlay_wrapper #drop_sd_background{position:absolute;top:0;left:50%;margin-left:0;width:50%;border-left:2px dashed #ccc}#drop_overlay #drop_overlay_wrapper .dropzone{height:100%;z-index:10001;color:#fff;font-size:30px}#drop_overlay #drop_overlay_wrapper .dropzone i{font-size:50px}#drop_overlay #drop_overlay_wrapper .dropzone .text{display:block;text-align:center;line-height:40px;position:absolute;width:100%;bottom:5%;filter:alpha(opacity=100);-moz-opacity:1.0;-khtml-opacity:1.0;opacity:1.0}#drop_overlay #drop_overlay_wrapper .dropzone_background{width:50%;height:100%;background-color:#000;filter:alpha(opacity=25);-moz-opacity:.25;-khtml-opacity:.25;opacity:.25}#drop_overlay #drop_overlay_wrapper .dropzone_background.hover{background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#drop_overlay #drop_overlay_wrapper .dropzone_background.fade{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-ms-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;opacity:1}.icon-sd-black-14{background:url("../img/icon-sd-black-14.png") 0 3px no-repeat;width:11px;height:17px;display:inline-block!important}.center{float:none;margin-left:auto;margin-right:auto}.slider .slider-selection{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.slider .slider-selection:hover,.slider .slider-selection:focus,.slider .slider-selection:active,.slider .slider-selection.active,.slider .slider-selection.disabled,.slider .slider-selection[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.slider .slider-selection:active,.slider .slider-selection.active{background-color:#039 \9}.slider.slider-disabled .slider-selection{background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-track{background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.slider.slider-disabled .slider-track{background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-handle{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;font-size:14px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);padding:0;margin-bottom:0;opacity:1;filter:alpha(opacity=100)}.slider .slider-handle:hover,.slider .slider-handle:focus,.slider .slider-handle:active,.slider .slider-handle.active,.slider .slider-handle.disabled,.slider .slider-handle[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.slider .slider-handle:active,.slider .slider-handle.active{background-color:#ccc \9}.slider .slider-handle:first-child{*margin-left:0}.slider .slider-handle:hover,.slider .slider-handle:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.slider .slider-handle:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.slider .slider-handle.active,.slider .slider-handle:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.slider .slider-handle.disabled,.slider .slider-handle[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-handle.hide{display:none}.slider .slider-handle.round{-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%} \ No newline at end of file +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{border-color:transparent;cursor:pointer;color:#08c;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.nowrap{white-space:nowrap}.actioncol{text-align:center;white-space:nowrap}.actioncol a{text-decoration:none;color:#000}.actioncol a.disabled{color:#ccc;cursor:default}#navbar .navbar-inner{background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#navbar .navbar-inner .brand,#navbar .navbar-inner .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner .brand .caret,#navbar .navbar-inner .nav>li>a .caret{border-bottom-color:#939393;border-top-color:#939393}#navbar .navbar-inner .brand:hover .caret,#navbar .navbar-inner .nav>li>a:hover .caret,#navbar .navbar-inner .brand:focus .caret,#navbar .navbar-inner .nav>li>a:focus .caret{border-bottom-color:#636363;border-top-color:#636363}#navbar .navbar-inner .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e0e0e0;background-image:-moz-linear-gradient(top,#ccc,#fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ccc),to(#fff));background-image:-webkit-linear-gradient(top,#ccc,#fff);background-image:-o-linear-gradient(top,#ccc,#fff);background-image:linear-gradient(to bottom,#ccc,#fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffcccccc',endColorstr='#ffffffff',GradientType=0)}#navbar .navbar-inner.transparent{background-color:rgba(235,235,235,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,0.6)),to(rgba(204,204,204,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(255,255,255,0.6),rgba(204,204,204,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99ffffff',endColorstr='#99cccccc',GradientType=0)}#navbar .navbar-inner.transparent .brand,#navbar .navbar-inner.transparent .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.transparent .brand .caret,#navbar .navbar-inner.transparent .nav>li>a .caret{border-bottom-color:#939393;border-top-color:#939393}#navbar .navbar-inner.transparent .brand:hover .caret,#navbar .navbar-inner.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.transparent .brand:focus .caret,#navbar .navbar-inner.transparent .nav>li>a:focus .caret{border-bottom-color:#636363;border-top-color:#636363}#navbar .navbar-inner.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(224,224,224,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(204,204,204,0.6)),to(rgba(255,255,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(204,204,204,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99cccccc',endColorstr='#99ffffff',GradientType=0)}#navbar .navbar-inner.red{background-color:#bb645f;background-image:-moz-linear-gradient(top,#e28e8a,#802420);background-image:-webkit-gradient(linear,0 0,0 100%,from(#e28e8a),to(#802420));background-image:-webkit-linear-gradient(top,#e28e8a,#802420);background-image:-o-linear-gradient(top,#e28e8a,#802420);background-image:linear-gradient(to bottom,#e28e8a,#802420);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe28e8a',endColorstr='#ff802420',GradientType=0)}#navbar .navbar-inner.red .brand,#navbar .navbar-inner.red .nav>li>a{text-shadow:0 1px 0 #802420;color:#f2f2f2}#navbar .navbar-inner.red .brand .caret,#navbar .navbar-inner.red .nav>li>a .caret{border-bottom-color:#d89491;border-top-color:#d89491}#navbar .navbar-inner.red .brand:hover .caret,#navbar .navbar-inner.red .nav>li>a:hover .caret,#navbar .navbar-inner.red .brand:focus .caret,#navbar .navbar-inner.red .nav>li>a:focus .caret{border-bottom-color:#e5c3c1;border-top-color:#e5c3c1}#navbar .navbar-inner.red .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.red .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.red .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open.active>.dropdown-toggle{background-color:#a74f4a;background-image:-moz-linear-gradient(top,#802420,#e28e8a);background-image:-webkit-gradient(linear,0 0,0 100%,from(#802420),to(#e28e8a));background-image:-webkit-linear-gradient(top,#802420,#e28e8a);background-image:-o-linear-gradient(top,#802420,#e28e8a);background-image:linear-gradient(to bottom,#802420,#e28e8a);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff802420',endColorstr='#ffe28e8a',GradientType=0)}#navbar .navbar-inner.red.transparent{background-color:rgba(187,100,95,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(226,142,138,0.6)),to(rgba(128,36,32,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(226,142,138,0.6),rgba(128,36,32,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99e28e8a',endColorstr='#99802420',GradientType=0)}#navbar .navbar-inner.red.transparent .brand,#navbar .navbar-inner.red.transparent .nav>li>a{text-shadow:0 1px 0 #802420;color:#f2f2f2}#navbar .navbar-inner.red.transparent .brand .caret,#navbar .navbar-inner.red.transparent .nav>li>a .caret{border-bottom-color:#d89491;border-top-color:#d89491}#navbar .navbar-inner.red.transparent .brand:hover .caret,#navbar .navbar-inner.red.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.red.transparent .brand:focus .caret,#navbar .navbar-inner.red.transparent .nav>li>a:focus .caret{border-bottom-color:#e5c3c1;border-top-color:#e5c3c1}#navbar .navbar-inner.red.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.red.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.red.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(167,79,74,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(128,36,32,0.6)),to(rgba(226,142,138,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(128,36,32,0.6),rgba(226,142,138,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99802420',endColorstr='#99e28e8a',GradientType=0)}#navbar .navbar-inner.orange{background-color:#e39665;background-image:-moz-linear-gradient(top,#f9c3a0,#c2530c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f9c3a0),to(#c2530c));background-image:-webkit-linear-gradient(top,#f9c3a0,#c2530c);background-image:-o-linear-gradient(top,#f9c3a0,#c2530c);background-image:linear-gradient(to bottom,#f9c3a0,#c2530c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9c3a0',endColorstr='#ffc2530c',GradientType=0)}#navbar .navbar-inner.orange .brand,#navbar .navbar-inner.orange .nav>li>a{text-shadow:0 1px 0 #f6a570;color:#f2f2f2}#navbar .navbar-inner.orange .brand .caret,#navbar .navbar-inner.orange .nav>li>a .caret{border-bottom-color:#f2b58d;border-top-color:#f2b58d}#navbar .navbar-inner.orange .brand:hover .caret,#navbar .navbar-inner.orange .nav>li>a:hover .caret,#navbar .navbar-inner.orange .brand:focus .caret,#navbar .navbar-inner.orange .nav>li>a:focus .caret{border-bottom-color:#f2d3c0;border-top-color:#f2d3c0}#navbar .navbar-inner.orange .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.orange .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.orange .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open.active>.dropdown-toggle{background-color:#d88047;background-image:-moz-linear-gradient(top,#c2530c,#f9c3a0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c2530c),to(#f9c3a0));background-image:-webkit-linear-gradient(top,#c2530c,#f9c3a0);background-image:-o-linear-gradient(top,#c2530c,#f9c3a0);background-image:linear-gradient(to bottom,#c2530c,#f9c3a0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc2530c',endColorstr='#fff9c3a0',GradientType=0)}#navbar .navbar-inner.orange.transparent{background-color:rgba(227,150,101,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,195,160,0.6)),to(rgba(194,83,12,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(249,195,160,0.6),rgba(194,83,12,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99f9c3a0',endColorstr='#99c2530c',GradientType=0)}#navbar .navbar-inner.orange.transparent .brand,#navbar .navbar-inner.orange.transparent .nav>li>a{text-shadow:0 1px 0 #f6a570;color:#f2f2f2}#navbar .navbar-inner.orange.transparent .brand .caret,#navbar .navbar-inner.orange.transparent .nav>li>a .caret{border-bottom-color:#f2b58d;border-top-color:#f2b58d}#navbar .navbar-inner.orange.transparent .brand:hover .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.orange.transparent .brand:focus .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:focus .caret{border-bottom-color:#f2d3c0;border-top-color:#f2d3c0}#navbar .navbar-inner.orange.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.orange.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.orange.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(216,128,71,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,83,12,0.6)),to(rgba(249,195,160,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(194,83,12,0.6),rgba(249,195,160,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c2530c',endColorstr='#99f9c3a0',GradientType=0)}#navbar .navbar-inner.yellow{background-color:#e3d765;background-image:-moz-linear-gradient(top,#f9f0a0,#c2b00c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f9f0a0),to(#c2b00c));background-image:-webkit-linear-gradient(top,#f9f0a0,#c2b00c);background-image:-o-linear-gradient(top,#f9f0a0,#c2b00c);background-image:linear-gradient(to bottom,#f9f0a0,#c2b00c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f0a0',endColorstr='#ffc2b00c',GradientType=0)}#navbar .navbar-inner.yellow .brand,#navbar .navbar-inner.yellow .nav>li>a{text-shadow:0 1px 0 #f6e970;color:#333}#navbar .navbar-inner.yellow .brand .caret,#navbar .navbar-inner.yellow .nav>li>a .caret{border-bottom-color:#93892e;border-top-color:#93892e}#navbar .navbar-inner.yellow .brand:hover .caret,#navbar .navbar-inner.yellow .nav>li>a:hover .caret,#navbar .navbar-inner.yellow .brand:focus .caret,#navbar .navbar-inner.yellow .nav>li>a:focus .caret{border-bottom-color:#635e30;border-top-color:#635e30}#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.yellow .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open.active>.dropdown-toggle{background-color:#d8ca47;background-image:-moz-linear-gradient(top,#c2b00c,#f9f0a0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c2b00c),to(#f9f0a0));background-image:-webkit-linear-gradient(top,#c2b00c,#f9f0a0);background-image:-o-linear-gradient(top,#c2b00c,#f9f0a0);background-image:linear-gradient(to bottom,#c2b00c,#f9f0a0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc2b00c',endColorstr='#fff9f0a0',GradientType=0)}#navbar .navbar-inner.yellow.transparent{background-color:rgba(227,215,101,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,240,160,0.6)),to(rgba(194,176,12,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(249,240,160,0.6),rgba(194,176,12,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99f9f0a0',endColorstr='#99c2b00c',GradientType=0)}#navbar .navbar-inner.yellow.transparent .brand,#navbar .navbar-inner.yellow.transparent .nav>li>a{text-shadow:0 1px 0 #f6e970;color:#333}#navbar .navbar-inner.yellow.transparent .brand .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a .caret{border-bottom-color:#93892e;border-top-color:#93892e}#navbar .navbar-inner.yellow.transparent .brand:hover .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.yellow.transparent .brand:focus .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:focus .caret{border-bottom-color:#635e30;border-top-color:#635e30}#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(216,202,71,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,176,12,0.6)),to(rgba(249,240,160,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(194,176,12,0.6),rgba(249,240,160,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c2b00c',endColorstr='#99f9f0a0',GradientType=0)}#navbar .navbar-inner.green{background-color:#98f064;background-image:-moz-linear-gradient(top,#c8ffa7,#50da00);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8ffa7),to(#50da00));background-image:-webkit-linear-gradient(top,#c8ffa7,#50da00);background-image:-o-linear-gradient(top,#c8ffa7,#50da00);background-image:linear-gradient(to bottom,#c8ffa7,#50da00);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8ffa7',endColorstr='#ff50da00',GradientType=0)}#navbar .navbar-inner.green .brand,#navbar .navbar-inner.green .nav>li>a{text-shadow:0 1px 0 #a7ff74;color:#333}#navbar .navbar-inner.green .brand .caret,#navbar .navbar-inner.green .nav>li>a .caret{border-bottom-color:#55992e;border-top-color:#55992e}#navbar .navbar-inner.green .brand:hover .caret,#navbar .navbar-inner.green .nav>li>a:hover .caret,#navbar .navbar-inner.green .brand:focus .caret,#navbar .navbar-inner.green .nav>li>a:focus .caret{border-bottom-color:#446630;border-top-color:#446630}#navbar .navbar-inner.green .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.green .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.green .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open.active>.dropdown-toggle{background-color:#80e943;background-image:-moz-linear-gradient(top,#50da00,#c8ffa7);background-image:-webkit-gradient(linear,0 0,0 100%,from(#50da00),to(#c8ffa7));background-image:-webkit-linear-gradient(top,#50da00,#c8ffa7);background-image:-o-linear-gradient(top,#50da00,#c8ffa7);background-image:linear-gradient(to bottom,#50da00,#c8ffa7);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff50da00',endColorstr='#ffc8ffa7',GradientType=0)}#navbar .navbar-inner.green.transparent{background-color:rgba(152,240,100,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,255,167,0.6)),to(rgba(80,218,0,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,255,167,0.6),rgba(80,218,0,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8ffa7',endColorstr='#9950da00',GradientType=0)}#navbar .navbar-inner.green.transparent .brand,#navbar .navbar-inner.green.transparent .nav>li>a{text-shadow:0 1px 0 #a7ff74;color:#333}#navbar .navbar-inner.green.transparent .brand .caret,#navbar .navbar-inner.green.transparent .nav>li>a .caret{border-bottom-color:#55992e;border-top-color:#55992e}#navbar .navbar-inner.green.transparent .brand:hover .caret,#navbar .navbar-inner.green.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.green.transparent .brand:focus .caret,#navbar .navbar-inner.green.transparent .nav>li>a:focus .caret{border-bottom-color:#446630;border-top-color:#446630}#navbar .navbar-inner.green.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.green.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.green.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(128,233,67,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,218,0,0.6)),to(rgba(200,255,167,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(80,218,0,0.6),rgba(200,255,167,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9950da00',endColorstr='#99c8ffa7',GradientType=0)}#navbar .navbar-inner.blue{background-color:#2e63cc;background-image:-moz-linear-gradient(top,#4d88ff,#002b80);background-image:-webkit-gradient(linear,0 0,0 100%,from(#4d88ff),to(#002b80));background-image:-webkit-linear-gradient(top,#4d88ff,#002b80);background-image:-o-linear-gradient(top,#4d88ff,#002b80);background-image:linear-gradient(to bottom,#4d88ff,#002b80);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4d88ff',endColorstr='#ff002b80',GradientType=0)}#navbar .navbar-inner.blue .brand,#navbar .navbar-inner.blue .nav>li>a{text-shadow:0 1px 0 #002b80;color:#f2f2f2}#navbar .navbar-inner.blue .brand .caret,#navbar .navbar-inner.blue .nav>li>a .caret{border-bottom-color:#799bdf;border-top-color:#799bdf}#navbar .navbar-inner.blue .brand:hover .caret,#navbar .navbar-inner.blue .nav>li>a:hover .caret,#navbar .navbar-inner.blue .brand:focus .caret,#navbar .navbar-inner.blue .nav>li>a:focus .caret{border-bottom-color:#b6c7e9;border-top-color:#b6c7e9}#navbar .navbar-inner.blue .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.blue .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.blue .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open.active>.dropdown-toggle{background-color:#1f50b3;background-image:-moz-linear-gradient(top,#002b80,#4d88ff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#002b80),to(#4d88ff));background-image:-webkit-linear-gradient(top,#002b80,#4d88ff);background-image:-o-linear-gradient(top,#002b80,#4d88ff);background-image:linear-gradient(to bottom,#002b80,#4d88ff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff002b80',endColorstr='#ff4d88ff',GradientType=0)}#navbar .navbar-inner.blue.transparent{background-color:rgba(46,99,204,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(77,136,255,0.6)),to(rgba(0,43,128,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(77,136,255,0.6),rgba(0,43,128,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#994d88ff',endColorstr='#99002b80',GradientType=0)}#navbar .navbar-inner.blue.transparent .brand,#navbar .navbar-inner.blue.transparent .nav>li>a{text-shadow:0 1px 0 #002b80;color:#f2f2f2}#navbar .navbar-inner.blue.transparent .brand .caret,#navbar .navbar-inner.blue.transparent .nav>li>a .caret{border-bottom-color:#799bdf;border-top-color:#799bdf}#navbar .navbar-inner.blue.transparent .brand:hover .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.blue.transparent .brand:focus .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:focus .caret{border-bottom-color:#b6c7e9;border-top-color:#b6c7e9}#navbar .navbar-inner.blue.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.blue.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.blue.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(31,80,179,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(0,43,128,0.6)),to(rgba(77,136,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(0,43,128,0.6),rgba(77,136,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99002b80',endColorstr='#994d88ff',GradientType=0)}#navbar .navbar-inner.violet{background-color:#9864f0;background-image:-moz-linear-gradient(top,#c8a7ff,#5000da);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8a7ff),to(#5000da));background-image:-webkit-linear-gradient(top,#c8a7ff,#5000da);background-image:-o-linear-gradient(top,#c8a7ff,#5000da);background-image:linear-gradient(to bottom,#c8a7ff,#5000da);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8a7ff',endColorstr='#ff5000da',GradientType=0)}#navbar .navbar-inner.violet .brand,#navbar .navbar-inner.violet .nav>li>a{text-shadow:0 1px 0 #5000da;color:#f2f2f2}#navbar .navbar-inner.violet .brand .caret,#navbar .navbar-inner.violet .nav>li>a .caret{border-bottom-color:#b58df9;border-top-color:#b58df9}#navbar .navbar-inner.violet .brand:hover .caret,#navbar .navbar-inner.violet .nav>li>a:hover .caret,#navbar .navbar-inner.violet .brand:focus .caret,#navbar .navbar-inner.violet .nav>li>a:focus .caret{border-bottom-color:#d3c0f5;border-top-color:#d3c0f5}#navbar .navbar-inner.violet .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.violet .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.violet .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open.active>.dropdown-toggle{background-color:#8043e9;background-image:-moz-linear-gradient(top,#5000da,#c8a7ff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5000da),to(#c8a7ff));background-image:-webkit-linear-gradient(top,#5000da,#c8a7ff);background-image:-o-linear-gradient(top,#5000da,#c8a7ff);background-image:linear-gradient(to bottom,#5000da,#c8a7ff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5000da',endColorstr='#ffc8a7ff',GradientType=0)}#navbar .navbar-inner.violet.transparent{background-color:rgba(152,100,240,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,167,255,0.6)),to(rgba(80,0,218,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,167,255,0.6),rgba(80,0,218,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8a7ff',endColorstr='#995000da',GradientType=0)}#navbar .navbar-inner.violet.transparent .brand,#navbar .navbar-inner.violet.transparent .nav>li>a{text-shadow:0 1px 0 #5000da;color:#f2f2f2}#navbar .navbar-inner.violet.transparent .brand .caret,#navbar .navbar-inner.violet.transparent .nav>li>a .caret{border-bottom-color:#b58df9;border-top-color:#b58df9}#navbar .navbar-inner.violet.transparent .brand:hover .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.violet.transparent .brand:focus .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:focus .caret{border-bottom-color:#d3c0f5;border-top-color:#d3c0f5}#navbar .navbar-inner.violet.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.violet.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.violet.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(128,67,233,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,0,218,0.6)),to(rgba(200,167,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(80,0,218,0.6),rgba(200,167,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#995000da',endColorstr='#99c8a7ff',GradientType=0)}#navbar .navbar-inner.black{background-color:#4f4f4f;background-image:-moz-linear-gradient(top,#787878,#121212);background-image:-webkit-gradient(linear,0 0,0 100%,from(#787878),to(#121212));background-image:-webkit-linear-gradient(top,#787878,#121212);background-image:-o-linear-gradient(top,#787878,#121212);background-image:linear-gradient(to bottom,#787878,#121212);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff787878',endColorstr='#ff121212',GradientType=0)}#navbar .navbar-inner.black .brand,#navbar .navbar-inner.black .nav>li>a{text-shadow:0 1px 0 #121212;color:#f2f2f2}#navbar .navbar-inner.black .brand .caret,#navbar .navbar-inner.black .nav>li>a .caret{border-bottom-color:#959595;border-top-color:#959595}#navbar .navbar-inner.black .brand:hover .caret,#navbar .navbar-inner.black .nav>li>a:hover .caret,#navbar .navbar-inner.black .brand:focus .caret,#navbar .navbar-inner.black .nav>li>a:focus .caret{border-bottom-color:#c4c4c4;border-top-color:#c4c4c4}#navbar .navbar-inner.black .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.black .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.black .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open.active>.dropdown-toggle{background-color:#3b3b3b;background-image:-moz-linear-gradient(top,#121212,#787878);background-image:-webkit-gradient(linear,0 0,0 100%,from(#121212),to(#787878));background-image:-webkit-linear-gradient(top,#121212,#787878);background-image:-o-linear-gradient(top,#121212,#787878);background-image:linear-gradient(to bottom,#121212,#787878);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff121212',endColorstr='#ff787878',GradientType=0)}#navbar .navbar-inner.black.transparent{background-color:rgba(79,79,79,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(120,120,120,0.6)),to(rgba(18,18,18,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(120,120,120,0.6),rgba(18,18,18,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99787878',endColorstr='#99121212',GradientType=0)}#navbar .navbar-inner.black.transparent .brand,#navbar .navbar-inner.black.transparent .nav>li>a{text-shadow:0 1px 0 #121212;color:#f2f2f2}#navbar .navbar-inner.black.transparent .brand .caret,#navbar .navbar-inner.black.transparent .nav>li>a .caret{border-bottom-color:#959595;border-top-color:#959595}#navbar .navbar-inner.black.transparent .brand:hover .caret,#navbar .navbar-inner.black.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.black.transparent .brand:focus .caret,#navbar .navbar-inner.black.transparent .nav>li>a:focus .caret{border-bottom-color:#c4c4c4;border-top-color:#c4c4c4}#navbar .navbar-inner.black.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.black.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.black.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(59,59,59,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(18,18,18,0.6)),to(rgba(120,120,120,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(18,18,18,0.6),rgba(120,120,120,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99121212',endColorstr='#99787878',GradientType=0)}#navbar .navbar-inner.white{background-color:#e9e9e9;background-image:-moz-linear-gradient(top,#fff,#c8c8c8);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#c8c8c8));background-image:-webkit-linear-gradient(top,#fff,#c8c8c8);background-image:-o-linear-gradient(top,#fff,#c8c8c8);background-image:linear-gradient(to bottom,#fff,#c8c8c8);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffc8c8c8',GradientType=0)}#navbar .navbar-inner.white .brand,#navbar .navbar-inner.white .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.white .brand .caret,#navbar .navbar-inner.white .nav>li>a .caret{border-bottom-color:#919191;border-top-color:#919191}#navbar .navbar-inner.white .brand:hover .caret,#navbar .navbar-inner.white .nav>li>a:hover .caret,#navbar .navbar-inner.white .brand:focus .caret,#navbar .navbar-inner.white .nav>li>a:focus .caret{border-bottom-color:#626262;border-top-color:#626262}#navbar .navbar-inner.white .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.white .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.white .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open.active>.dropdown-toggle{background-color:#dedede;background-image:-moz-linear-gradient(top,#c8c8c8,#fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#c8c8c8),to(#fff));background-image:-webkit-linear-gradient(top,#c8c8c8,#fff);background-image:-o-linear-gradient(top,#c8c8c8,#fff);background-image:linear-gradient(to bottom,#c8c8c8,#fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffc8c8c8',endColorstr='#ffffffff',GradientType=0)}#navbar .navbar-inner.white.transparent{background-color:rgba(233,233,233,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,0.6)),to(rgba(200,200,200,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(255,255,255,0.6),rgba(200,200,200,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99ffffff',endColorstr='#99c8c8c8',GradientType=0)}#navbar .navbar-inner.white.transparent .brand,#navbar .navbar-inner.white.transparent .nav>li>a{text-shadow:0 1px 0 #fff;color:#333}#navbar .navbar-inner.white.transparent .brand .caret,#navbar .navbar-inner.white.transparent .nav>li>a .caret{border-bottom-color:#919191;border-top-color:#919191}#navbar .navbar-inner.white.transparent .brand:hover .caret,#navbar .navbar-inner.white.transparent .nav>li>a:hover .caret,#navbar .navbar-inner.white.transparent .brand:focus .caret,#navbar .navbar-inner.white.transparent .nav>li>a:focus .caret{border-bottom-color:#626262;border-top-color:#626262}#navbar .navbar-inner.white.transparent .brand span{background-image:url(../img/tentacle-20x20.png)}@media(-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.white.transparent .brand span{background-image:url(../img/tentacle-20x20@2x.png)}}#navbar .navbar-inner.white.transparent .nav li.dropdown.open>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open.active>.dropdown-toggle{background-color:rgba(222,222,222,0.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,200,200,0.6)),to(rgba(255,255,255,0.6))),url("../img/trans-background.png");background-image:-webkit-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:-o-linear-gradient(top,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-image:linear-gradient(to bottom,rgba(200,200,200,0.6),rgba(255,255,255,0.6)),url("../img/trans-background.png");background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#99c8c8c8',endColorstr='#99ffffff',GradientType=0)}#navbar .navbar-inner .brand span{background-size:20px 20px;background-position:left center;padding-left:24px;background-repeat:no-repeat}.octoprint-container{margin-top:20px}.octoprint-container .tab-content{padding:9px 15px;border-left:1px solid #DDD;border-right:1px solid #DDD;border-bottom:1px solid #DDD;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.octoprint-container .nav{margin-bottom:0}.octoprint-container .tab-content h1{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5;font-weight:normal}.octoprint-container .accordion-heading .accordion-heading-button{float:right}.octoprint-container .accordion-heading .accordion-heading-button a{display:inline-block;padding:8px 15px;font-size:14px;line-height:20px;color:#000;text-decoration:none;background:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.octoprint-container .accordion-heading a.accordion-toggle{display:inline-block}.octoprint-container .accordion-heading [class^="icon-"],.octoprint-container .accordion-heading [class*=" icon-"]{color:#000}.print-control .btn{padding-left:4px;padding-right:4px}.upload-buttons .btn{margin-right:0}table{table-layout:fixed}table .popover-title{text-overflow:ellipsis;word-break:break-all}table th,table td{overflow:hidden}table th.gcode_files_name,table td.gcode_files_name{text-overflow:ellipsis;text-align:left;white-space:nowrap}table th.gcode_files_action,table td.gcode_files_action{width:90px;text-align:center;white-space:nowrap}table th.gcode_files_action a,table td.gcode_files_action a{text-decoration:none;color:#000}table th.gcode_files_action a.disabled,table td.gcode_files_action a.disabled{color:#ccc;cursor:default}table th.timelapse_files_name,table td.timelapse_files_name{text-overflow:ellipsis;text-align:left}table th.timelapse_files_size,table td.timelapse_files_size{text-align:right;width:55px}table th.timelapse_files_action,table td.timelapse_files_action{width:45px;text-align:center;white-space:nowrap}table th.timelapse_files_action a,table td.timelapse_files_action a{text-decoration:none;color:#000}table th.timelapse_files_action a.disabled,table td.timelapse_files_action a.disabled{color:#ccc;cursor:default}table th.settings_users_name,table td.settings_users_name{text-overflow:ellipsis;text-align:left}table th.settings_users_active,table td.settings_users_active,table th.settings_users_admin,table td.settings_users_admin{text-align:center;width:55px}table th.settings_users_actions,table td.settings_users_actions{width:60px;text-align:center;white-space:nowrap}table th.settings_users_actions a,table td.settings_users_actions a{text-decoration:none;color:#000}table th.settings_users_actions a.disabled,table td.settings_users_actions a.disabled{color:#ccc;cursor:default}table th.settings_logs_name,table td.settings_logs_name{text-overflow:ellipsis;text-align:left}table th.settings_logs_size,table td.settings_logs_size{text-align:right;width:70px}table th.settings_logs_date,table td.settings_logs_date{text-align:left;width:130px}table th.settings_logs_action,table td.settings_logs_action{width:70px;text-align:center;white-space:nowrap}table th.settings_logs_action a,table td.settings_logs_action a{text-decoration:none;color:#000}table th.settings_logs_action a.disabled,table td.settings_logs_action a.disabled{color:#ccc;cursor:default}table th.settings_printerProfiles_profiles_name,table td.settings_printerProfiles_profiles_name{text-overflow:ellipsis;text-align:left}table th.settings_printerProfiles_profiles_model,table td.settings_printerProfiles_profiles_model{text-align:left;width:250px}table th.settings_printerProfiles_profiles_action,table td.settings_printerProfiles_profiles_action{width:80px;text-align:center;white-space:nowrap}table th.settings_printerProfiles_profiles_action a,table td.settings_printerProfiles_profiles_action a{text-decoration:none;color:#000}table th.settings_printerProfiles_profiles_action a.disabled,table td.settings_printerProfiles_profiles_action a.disabled{color:#ccc;cursor:default}#temperature-graph{height:350px;width:100%;background-image:url("../img/graph-background.png");background-position:center;background-repeat:no-repeat}.tab-content,.tab-pane{overflow:visible}.tempInput{width:50px}#temp_newTemp,#temp_newBedTemp,#speed_innerWall,#speed_outerWall,#speed_fill,#speed_support,#webcam_timelapse_interval,#webcam_timelapse_postRoll,#webcam_timelapse_fps{text-align:right}ul.dropdown-menu li a{cursor:pointer}#connection_ports,#connection_baudrates,#connection_printers{width:100%}#offline_overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:10000;display:none}#offline_overlay_background{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#offline_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#offline_overlay_wrapper .container{margin:auto}#webcam_container{width:100%;position:relative;outline:0}#webcam_container .flipH{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1)}#webcam_container .flipV{-webkit-transform:scaleY(-1);-moz-transform:scaleY(-1)}#webcam_container .flipH.flipV{-webkit-transform:scaleX(-1) scaleY(-1);-moz-transform:scaleX(-1) scaleY(-1)}#webcam_container .keycontrol_overlay{position:absolute;left:10px;right:10px;bottom:10px;background:rgba(0,0,0,0.5);font-size:85%;color:white;padding:0}#webcam_container .keycontrol_overlay kbd{border:1px solid #eee;border-radius:3px;margin-left:2px;margin-right:2px;font-size:90%;padding:2px;min-width:1em}#webcam_container .keycontrol_overlay .keycontrol_overlay_heading{position:relative;padding:10px;font-weight:bold}#webcam_container .keycontrol_overlay .keycontrol_overlay_column{position:relative;width:45%;padding:10px;float:left}#files .gcode_files{padding-right:7px}#files .gcode_files .entry{padding:5px;line-height:20px;border-bottom:1px solid #ddd;position:relative}#files .gcode_files .entry:hover{background-color:#f5f5f5}#files .gcode_files .entry .title{text-overflow:ellipsis;word-break:break-all}#files .gcode_files .entry .uploaded,#files .gcode_files .entry .size,#files .gcode_files .entry .additionalInfo{font-size:85%;color:#999}#files .gcode_files .entry .action-buttons{position:absolute;bottom:5px;right:5px}#files .gcode_files .entry .additionalInfo{padding-bottom:22px}#files .upload-buttons{margin-top:10px}#files .form-search{text-align:center;margin-bottom:5px!important}#control{overflow:hidden}#control .jog-panel{float:left;margin-right:19px}#control h1{text-align:left}#control .jog-panel>div{text-align:center}#control .jog-panel>div.distance{text-align:left}#control .jog-panel .slider{margin-bottom:10px}#control .box{width:30px;height:30px;margin-right:10px;margin-bottom:10px;padding-left:8px}#control .control-box{display:block;height:30px;margin-bottom:10px}#control .btn-group{margin-bottom:10px}#control .btn-group.distance>.btn{width:43px;padding:3px 0;height:30px}#control .slider-handle{width:14px;height:14px;margin-left:-7px;margin-top:-3px}#control .custom_section_horizontal .custom_control{display:inline-block}#control .custom_control .slider{margin-left:10px;margin-right:10px;margin-bottom:2px}#gcode .progress{width:582px}#gcode .progress .bar{-webkit-transition:width 0s linear;-moz-transition:width 0s linear;-o-transition:width 0s linear;transition:width 0s linear}#gcode #gcode_layer_slider{height:568px;float:right}#gcode #gcode_layer_slider .slider-handle{width:14px;height:14px;margin-left:-3px;margin-top:-7px}#gcode #gcode_command_slider .slider-handle{width:14px;height:14px;margin-left:-7px;margin-top:-3px}#term .terminal{margin-bottom:30px}#term .terminal #terminal-output{min-height:340px;margin-bottom:5px}#term #terminal-sendpanel{text-align:right}.footer ul{margin:0}.footer ul li{display:inline;margin-left:1em;font-size:85%}.footer ul li:first-child{margin-left:0}.footer ul li a{color:#555}.ui-pnotify .alert a{color:#c09853}.ui-pnotify .alert-error a,.ui-pnotify .alert-danger a{color:#b94a48}.ui-pnotify .alert-success a{color:#468847}.ui-pnotify .alert-info a{color:#3a87ad}.pnotify_additional_info .pnotify_more{font-size:85%}.text-right{text-align:right}.overflow_visible{overflow:visible!important}.border_box{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none}textarea.block{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%}#drop_overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:10000;display:none}#drop_overlay.in{display:block}#drop_overlay #drop_overlay_background{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#drop_overlay #drop_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#drop_overlay #drop_overlay_wrapper #drop,#drop_overlay #drop_overlay_wrapper #drop_background{position:absolute;top:0;left:0;margin-left:0;width:100%}#drop_overlay #drop_overlay_wrapper #drop_locally,#drop_overlay #drop_overlay_wrapper #drop_locally_background{position:absolute;top:0;left:50%;margin-left:-50%;width:50%;border-right:2px dashed #ccc}#drop_overlay #drop_overlay_wrapper #drop_sd,#drop_overlay #drop_overlay_wrapper #drop_sd_background{position:absolute;top:0;left:50%;margin-left:0;width:50%;border-left:2px dashed #ccc}#drop_overlay #drop_overlay_wrapper .dropzone{height:100%;z-index:10001;color:#fff;font-size:30px}#drop_overlay #drop_overlay_wrapper .dropzone i{font-size:50px}#drop_overlay #drop_overlay_wrapper .dropzone .text{display:block;text-align:center;line-height:40px;position:absolute;width:100%;bottom:5%;filter:alpha(opacity=100);-moz-opacity:1.0;-khtml-opacity:1.0;opacity:1.0}#drop_overlay #drop_overlay_wrapper .dropzone_background{width:50%;height:100%;background-color:#000;filter:alpha(opacity=25);-moz-opacity:.25;-khtml-opacity:.25;opacity:.25}#drop_overlay #drop_overlay_wrapper .dropzone_background.hover{background-color:#000;filter:alpha(opacity=50);-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}#drop_overlay #drop_overlay_wrapper .dropzone_background.fade{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-ms-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;opacity:1}.icon-sd-black-14{background:url("../img/icon-sd-black-14.png") 0 3px no-repeat;width:11px;height:17px;display:inline-block!important}.center{float:none;margin-left:auto;margin-right:auto}.slider .slider-selection{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.slider .slider-selection:hover,.slider .slider-selection:focus,.slider .slider-selection:active,.slider .slider-selection.active,.slider .slider-selection.disabled,.slider .slider-selection[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.slider .slider-selection:active,.slider .slider-selection.active{background-color:#039 \9}.slider.slider-disabled .slider-selection{background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-track{background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.slider.slider-disabled .slider-track{background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-handle{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;font-size:14px;line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #ccc;*border:0;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);padding:0;margin-bottom:0;opacity:1;filter:alpha(opacity=100)}.slider .slider-handle:hover,.slider .slider-handle:focus,.slider .slider-handle:active,.slider .slider-handle.active,.slider .slider-handle.disabled,.slider .slider-handle[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.slider .slider-handle:active,.slider .slider-handle.active{background-color:#ccc \9}.slider .slider-handle:first-child{*margin-left:0}.slider .slider-handle:hover,.slider .slider-handle:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.slider .slider-handle:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.slider .slider-handle.active,.slider .slider-handle:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.slider .slider-handle.disabled,.slider .slider-handle[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.slider .slider-handle.hide{display:none}.slider .slider-handle.round{-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%} \ No newline at end of file diff --git a/src/octoprint/static/js/app/viewmodels/control.js b/src/octoprint/static/js/app/viewmodels/control.js index 911e46d2..9943a0fb 100644 --- a/src/octoprint/static/js/app/viewmodels/control.js +++ b/src/octoprint/static/js/app/viewmodels/control.js @@ -191,10 +191,27 @@ $(function() { }; self.clickCustom = function (data) { + var callback; if (data.hasOwnProperty("javascript")) { - data.javascript(data); + callback = data.javascript; } else { - self.sendCustomCommand(data); + callback = self.sendCustomCommand; + } + + if (data.confirm) { + var confirmationDialog = $("#confirmation_dialog"); + var confirmationDialogAck = $(".confirmation_dialog_acknowledge", confirmationDialog); + + $(".confirmation_dialog_message", confirmationDialog).text(data.confirm); + confirmationDialogAck.unbind("click"); + confirmationDialogAck.bind("click", function (e) { + e.preventDefault(); + $("#confirmation_dialog").modal("hide"); + callback(data); + }); + confirmationDialog.modal("show"); + } else { + callback(data); } }; @@ -285,15 +302,6 @@ $(function() { if (!command) return; - var callback = function () { - $.ajax({ - url: API_BASEURL + "printer/command", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }) - }; var data = undefined; if (command.hasOwnProperty("command")) { // single command @@ -322,22 +330,13 @@ $(function() { }); } - if (command.confirm) { - var confirmationDialog = $("#confirmation_dialog"); - var confirmationDialogAck = $(".confirmation_dialog_acknowledge", confirmationDialog); - - $(".confirmation_dialog_message", confirmationDialog).text(command.confirm); - confirmationDialogAck.unbind("click"); - confirmationDialogAck.bind("click", function (e) { - e.preventDefault(); - $("#confirmation_dialog").modal("hide"); - callback(); - }); - confirmationDialog.modal("show"); - } else { - callback(); - } - + $.ajax({ + url: API_BASEURL + "printer/command", + type: "POST", + dataType: "json", + contentType: "application/json; charset=UTF-8", + data: JSON.stringify(data) + }) }; self.displayMode = function (customControl) { diff --git a/src/octoprint/static/less/octoprint.less b/src/octoprint/static/less/octoprint.less index bc49c1d8..405a69d7 100644 --- a/src/octoprint/static/less/octoprint.less +++ b/src/octoprint/static/less/octoprint.less @@ -595,7 +595,11 @@ ul.dropdown-menu li a { margin-top: -3px; } - .custom_parametric_command { + .custom_section_horizontal .custom_control { + display: inline-block; + } + + .custom_control { .slider { margin-left: 10px; margin-right: 10px; diff --git a/src/octoprint/templates/tabs/control.jinja2 b/src/octoprint/templates/tabs/control.jinja2 index b8cccaca..ec9df95d 100644 --- a/src/octoprint/templates/tabs/control.jinja2 +++ b/src/octoprint/templates/tabs/control.jinja2 @@ -111,11 +111,15 @@ -
+
-
+
+ + + +
@@ -123,9 +127,9 @@