diff --git a/.versioneer-lookup b/.versioneer-lookup index 3d72f7f7..a86a359d 100644 --- a/.versioneer-lookup +++ b/.versioneer-lookup @@ -16,11 +16,11 @@ rc HEAD \(detached.* -# maintenance is currently the branch for preparation of maintenance release 1.2.14 +# maintenance is currently the branch for preparation of maintenance release 1.2.15 # so are any fix/... and improve/... branches -maintenance 1.2.14 cb2e0d449f607bbc89c7ad13c983a0cf11bbfdee pep440-dev -fix/.* 1.2.14 cb2e0d449f607bbc89c7ad13c983a0cf11bbfdee pep440-dev -improve/.* 1.2.14 cb2e0d449f607bbc89c7ad13c983a0cf11bbfdee pep440-dev +maintenance 1.2.15 14969e5508b7b66f38abaf0f96bb7dc5b9ebe929 pep440-dev +fix/.* 1.2.15 14969e5508b7b66f38abaf0f96bb7dc5b9ebe929 pep440-dev +improve/.* 1.2.15 14969e5508b7b66f38abaf0f96bb7dc5b9ebe929 pep440-dev # every other branch is a development branch and thus gets resolved to 1.3.0-dev for now .* 1.3.0 198d3450d94be1a2 pep440-dev diff --git a/CHANGELOG.md b/CHANGELOG.md index b8cd3d2f..b8829f2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,43 @@ * [#1047](https://github.com/foosel/OctoPrint/issues/1047) - Fixed 90 degree webcam rotation for iOS Safari. +## 1.2.14 (2016-07-28) + +### Improvements + + * [#935](https://github.com/foosel/OctoPrint/issues/935) - Support alternative source file types and target extensions in [SlicerPlugins](http://docs.octoprint.org/en/master/plugins/mixins.html#slicerplugin). + * [#1393](https://github.com/foosel/OctoPrint/issues/1393) - Added dedicated sub commands on the job API to pause and resume a print job (instead of only offering a toggle option). + * Better "upload error" message with a list of supported extensions (instead of hardcoded ones) + * Use fuzzy times for print time estimation from GCODE analysis + * Allow M23 "File opened" response with no filename (RepRapPro) + * Allow intermediary startup page to forward query parameters and fragments from initial call to actual web frontend + * More error resilience when rendering templates (e.g. from plugins) + * Make sure that all bytes of a line to send to the printer have actually been sent + * "Tickle" printer when encountering a communication timeout while idle + * Report `CLOSED`/`CLOSED_WITH_ERROR` states as "Offline" in frontend for more consistency with startup `NONE` state which already was reported as "Offline" + * Another attempt at a saner print time estimation: Force linear (way less accurate) estimate if calculation of more accurate version takes too long, sanity check calculated estimate and use linear estimate if it looks wrong, improved threshold values for calculation. Read [the second half of this post on the mailing list](https://groups.google.com/forum/#!msg/octoprint/WWpm1FCUkAs/X3HomTM5DgAJ) on why accurate print time estimation is so difficult to achieve. + * Display print job progress percentage on progress bar. + * Added an indicator for print time left prediction accuracy and explanation of its origin as tooltip. + * Improved visual distinction of "State" sidebar panel info clusters. + +### Bug Fixes + + * [#1385](https://github.com/foosel/OctoPrint/issues/1385) - Send all non-protocol messages from printer to clients. + * [#1388](https://github.com/foosel/OctoPrint/issues/1388) - Track consecutive timeouts even when idle and disconnect from printer when it's not responding any longer. + * [#1391](https://github.com/foosel/OctoPrint/issues/1391) - Only use the first value from the X-Scheme header for the reverse proxy setup. Otherwise there could be problems when multiple reverse proxies were configured chained together, each adding their own header to the mix. + * [#1407](https://github.com/foosel/OctoPrint/issues/1407) - If a file is uploaded with the "print" flag set to true, make sure to clear that flag after the print job has been triggered so that now all following uploaded or selected files will start printing on their own. + * [#1409](https://github.com/foosel/OctoPrint/issues/1409) - Don't report a communication timeout after a heatup triggered by a print from SD. + * Fixed scrolling to freshly uploaded files, also now highlighting the file entry for better visibility. + * Fixed overeager preemptive caching of invalid protocols. + * Fix modal background of update confirmation not vanishing + * Ensure log entries and messages from printer are sent to frontend already converted to utf-8. Otherwise even one line in the log that can't be converted automatically without error can cause updates from the backend to not arrive. + * Report correct printer state including error strings even after disconnecting + * While printing, be sure to read the next line from file and send that if the current line was filtered + * Small fixes in the GCODE analysis + * Small fixes in the documentation + +([Commits](https://github.com/foosel/OctoPrint/compare/1.2.13...1.2.14)) + ## 1.2.13 (2016-06-16) ### Bug Fixes diff --git a/SUPPORTERS.md b/SUPPORTERS.md index a49b3375..659d13df 100644 --- a/SUPPORTERS.md +++ b/SUPPORTERS.md @@ -7,34 +7,37 @@ thanks to everyone who contributed! ## Patreon Patrons * 3D Moniak - * alephobjects + * alephobjects * Andrew Moorby * Arnljot Arntsen * Aurelio Bernal Ramírez * Bart Zudell * Brad Jackson + * Brad Mooneyham * Brent Fiegle * Brian E. Tyler * Charles Mitchell * Christian Petropolis - * COLLE+McVOY - * CreativeTools + * COLLE+McVOY + * CreativeTools * D Brian Kimmel * DeltaMaker 3D Printers * Doug Johnson * E3D BigBox * Erik de Bruijn * Ernesto Martinez - * Exovite + * Exovite * Frank Sander - * georgeroblesjr + * georgeroblesjr * Gregor Luetolf + * J. Eckert * Jason Galarneau * Joe Korzeniewski * Joshua Gregory * Kaile Riser * Kale Stedman - * Kevin Freeheart + * Kazuhiro Ogura + * Korneel Bullens * Kyle Gress * Makespace Madrid * Mark Lane @@ -43,18 +46,20 @@ thanks to everyone who contributed! * Masayoshi Mitsui * Michael McDargh * Miguel Angel Salmeron - * Mikey + * Mikey * Miles Flavel * Mohammed Khorakiwala * Noe Ruiz * Paul Generes + * Peter Grace * Peter Schmehl + * PRINT3Dforum.com * Roger Strolz * Roy Cortes * Samer Najia - * SD3D + * SD3D * Shane Ekerbicer - * Simon + * Simon Hallam * Stefan Krister * stefi davis * Steven Pearson @@ -63,4 +68,4 @@ thanks to everyone who contributed! * Thomas Sanladerer * Trent Shumay -and 734 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file +and 844 more wonderful people pledging on the [Patreon campaign](https://patreon.com/foosel)! \ No newline at end of file diff --git a/docs/api/fileops.rst b/docs/api/fileops.rst index 9320f8b6..e9786c29 100644 --- a/docs/api/fileops.rst +++ b/docs/api/fileops.rst @@ -442,7 +442,7 @@ Issue a file command } - :param location: The target location on which to delete the file, either ``local`` (for OctoPrint's ``uploads`` + :param location: The target location on which to send the command for is located, either ``local`` (for OctoPrint's ``uploads`` folder) or ``sdcard`` for the printer's SD card (if available) :param path: The path of the file for which to issue the command :json string command: The command to issue for the file, currently only ``select`` is supported diff --git a/docs/configuration/config_yaml.rst b/docs/configuration/config_yaml.rst index 64c372a8..41939553 100644 --- a/docs/configuration/config_yaml.rst +++ b/docs/configuration/config_yaml.rst @@ -244,6 +244,9 @@ The following settings are only relevant to you if you want to do OctoPrint deve # be fully rerendered on request to / on the server. enabled: true + # Whether to enable the preemptive cache + preemptive: true + # Settings for stylesheet preference. OctoPrint will prefer to use the stylesheet type # specified here. Usually (on a production install) that will be the compiled css (default). # Developers may specify less here too. @@ -260,6 +263,9 @@ The following settings are only relevant to you if you want to do OctoPrint deve # set to false, no minification will take place either. minify: true + # Whether to delete generated web assets on server startup (forcing a regeneration) + clean_on_startup: true + # Settings for the virtual printer virtualPrinter: @@ -321,6 +327,10 @@ The following settings are only relevant to you if you want to do OctoPrint deve # < ok T0:34.3/220.0 T1:23.5/0.0 B:43.2/0.0 repetierStyleTargetTemperature: false + # If enabled, uses repetier style resends, sending multiple resends for the same line + # to make sure nothing gets lost on the line + repetierStyleResends: false + # If enabled, reports the first extruder in M105 responses as T instead of T0 # # True: > M105 @@ -348,9 +358,54 @@ The following settings are only relevant to you if you want to do OctoPrint deve # side will block rxBuffer: 64 - # Size of + # Size of simulated command buffer commandBuffer: 4 + # Whether to support the M112 command with simulated kill + supportM112: true + + # Whether to send messages received via M117 back as "echo:" lines + echoOnM117: true + + # Whether to simulate broken M29 behaviour (missing ok after response) + brokenM29: true + +.. _sec-configuration-config_yaml-estimation: + +Estimation +---------- + +The following settings provide parameters for estimators within OctoPrint. Currently only +the estimation of the left print time during an active job utilizes this section. + +.. code-block:: yaml + + estimation: + # Parameters for the print time estmation during an ongoing print job + printTime: + # Until which percentage to do a weighted mixture of statistical duration (analysis or + # past prints) with the result from the calculated estimate if that's already available. + # Utilized to compensate for the fact that the earlier in a print job, the least accuracy + # even a stable calculated estimate provides. + statsWeighingUntil: 0.5 + + # Range the assumed percentage (based on current estimated statistical, calculated or mixed + # total vs elapsed print time so far) needs to be around the actual percentage for the + # result to be used + validityRange: 0.15 + + # If no estimate could be calculated until this percentage and no statistical data is available, + # use dumb linear estimate + forceDumbFromPercent: 0.3 + + # If no estimate could be calculated until this many minutes into the print and no statistical + # data is available, use dumb linear estimate + forceDumbAfterMin: 30 + + # Average fluctuation between individual calculated estimates to consider in stable range. Seconds + # of difference. + stableThreshold: 60 + .. _sec-configuration-config_yaml-events: Events @@ -454,6 +509,16 @@ Use the following settings to enable or disable OctoPrint features: # Whether to enable the keyboard control feature in the control tab keyboardControl: true + # Whether to actively poll the watched folder (true) or to rely on the OS's file system + # notifications instead (false) + pollWatched: false + + # Whether to ignore identical resends from the printer (true, repetier) or not (false) + ignoreIdenticalResends: false + + # If ignoredIdenticalResends is true, how many consecutive identical resends to ignore + identicalResendsCount: 7 + .. _sec-configuration-config_yaml-folder: Folder @@ -645,8 +710,24 @@ Use the following settings to configure the serial connection to the printer: # Command to send in order to initiate a handshake with the printer. # Defaults to "M110 N0" which simply resets the line numbers in the firmware and which # should be acknowledged with a simple "ok". - helloCommand: - - M110 N0 + helloCommand: M110 N0 + + # Whether to disconnect on errors or not + disconnectOnErrors: true + + # Whether to completely ignore errors from the firmware or not + ignoreErrorsFromFirmware: false + + # Whether to log resends to octoprint.log or not. Invaluable debug tool without performance + # impact, leave on if possible please + logResends: true + + # Whether to support resends without follow-up ok or not + supportResendsWithoutOk: false + + # Whether to "manually" trigger an ok for M29 (a lot of versions of this command are buggy and + # the responds skips on the ok) + triggerOkForM29: true .. _sec-configuration-config_yaml-server: @@ -741,6 +822,27 @@ Use the following settings to configure the server: # Command to shut down the system OctoPrint is running on, defaults to being unset systemShutdownCommand: sudo shutdown -h now + # Settings of when to display what disk space warning + diskspace: + + # Threshold (bytes) after which to consider disk space becoming sparse, + # defaults to 500MB + warning: 63488000 + + # Threshold (bytes) after which to consider disk space becoming critical, + # defaults to 200MB + critical: 209715200 + + # Configuration of the preemptive cache + preemptiveCache: + + # which server paths to exclude from the preemptive cache + exceptions: + - /some/path + + # How many days to leave unused entries in the preemptive cache config + until: 7 + .. note:: diff --git a/setup.py b/setup.py index 4a0d19e7..c5475d86 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ INSTALL_REQUIRES = [ "Flask-Principal>=0.3.5,<0.4", "Flask-Babel>=0.9,<0.10", "Flask-Assets>=0.10,<0.11", - "Flask-Markdown>=0.3,<0.4", + "markdown>=2.6.4,<2.7", "pyserial>=2.7,<2.8", "netaddr>=0.7.17,<0.8", "watchdog>=0.8.3,<0.9", diff --git a/src/octoprint/plugins/virtual_printer/virtual.py b/src/octoprint/plugins/virtual_printer/virtual.py index 53376c32..74064db2 100644 --- a/src/octoprint/plugins/virtual_printer/virtual.py +++ b/src/octoprint/plugins/virtual_printer/virtual.py @@ -97,6 +97,8 @@ class VirtualPrinter(object): self._incoming_lock = threading.RLock() + self._debug_awol = False + self._debug_sleep = None self._sleepAfterNext = dict() self._sleepAfter = dict() @@ -485,6 +487,8 @@ class VirtualPrinter(object): dont_answer | Will not acknowledge the next command. + go_awol + | Will completely stop replying trigger_resend_lineno | Triggers a resend error with a line number mismatch trigger_resend_checksum @@ -518,7 +522,10 @@ class VirtualPrinter(object): elif data == "drop_connection": self._debug_drop_connection = True elif data == "maxtemp_error": - self.outgoing.put("Error: MAXTEMP triggered!") + self._output("Error: MAXTEMP triggered!") + elif data == "go_awol": + self._output("// Going AWOL") + self._debug_awol = True else: try: sleep_match = VirtualPrinter.sleep_regex.match(data) @@ -529,7 +536,7 @@ class VirtualPrinter(object): if sleep_match is not None: interval = int(sleep_match.group(1)) self._send("// sleeping for {interval} seconds".format(interval=interval)) - time.sleep(interval) + self._debug_sleep = interval elif sleep_after_match is not None: command = sleep_after_match.group(1) interval = int(sleep_after_match.group(2)) @@ -769,7 +776,7 @@ class VirtualPrinter(object): try: handle = open(file, "w") except: - self.outgoing.put("error writing to file") + self._output("error writing to file") if handle is not None: try: handle.close() @@ -789,7 +796,7 @@ class VirtualPrinter(object): self._writingToSdHandle = None self._writingToSd = False self._selectedSdFile = None - self.outgoing.put("Done saving file") + self._output("Done saving file") def _sdPrintingWorker(self): self._selectedSdFilePos = 0 @@ -827,7 +834,7 @@ class VirtualPrinter(object): self._sdPrintingSemaphore.clear() self._selectedSdFilePos = 0 self._sdPrinter = None - self.outgoing.put("Done printing file") + self._output("Done printing file") def _waitForHeatup(self, heater): delta = 1 @@ -838,12 +845,12 @@ class VirtualPrinter(object): toolNum = int(heater[len("tool"):]) while not self._killed and (self.temp[toolNum] < self.targetTemp[toolNum] - delta or self.temp[toolNum] > self.targetTemp[toolNum] + delta): self._simulateTemps(delta=delta) - self.outgoing.put("T:%0.2f" % self.temp[toolNum]) + self._output("T:%0.2f" % self.temp[toolNum]) time.sleep(delay) elif heater == "bed": while not self._killed and (self.bedTemp < self.bedTargetTemp - delta or self.bedTemp > self.bedTargetTemp + delta): self._simulateTemps(delta=delta) - self.outgoing.put("B:%0.2f" % self.bedTemp) + self._output("B:%0.2f" % self.bedTemp) time.sleep(delay) except AttributeError: if self.outgoing is not None: @@ -890,7 +897,17 @@ class VirtualPrinter(object): self._logger.info("Closing down buffer loop") + def _output(self, line): + try: + self.outgoing.put(line) + except: + if self.outgoing is None: + pass + def write(self, data): + if self._debug_awol: + return len(data) + if self._debug_drop_connection: self._logger.info("Debug drop of connection requested, raising SerialTimeoutException") raise SerialTimeoutException() @@ -913,15 +930,40 @@ class VirtualPrinter(object): raise SerialTimeoutException() def readline(self): + if self._debug_awol: + time.sleep(self._read_timeout) + return "" + if self._debug_drop_connection: raise SerialTimeoutException() + if self._debug_sleep > 0: + # if we are supposed to sleep, we sleep not longer than the read timeout + # (and then on the next call sleep again if there's time to sleep left) + sleep_for = min(self._debug_sleep, self._read_timeout) + self._debug_sleep -= sleep_for + time.sleep(sleep_for) + + if self._debug_sleep > 0: + # we slept the full read timeout, return an empty line + return "" + + # otherwise our left over timeout is the read timeout minus what we already + # slept for + timeout = self._read_timeout - sleep_for + + else: + # use the full read timeout as timeout + timeout = self._read_timeout + try: - line = self.outgoing.get(timeout=self._read_timeout) + # fetch a line from the queue, wait no longer than timeout + line = self.outgoing.get(timeout=timeout) self._seriallog.info(">>> {}".format(line.strip())) self.outgoing.task_done() return line except queue.Empty: + # queue empty? return empty line return "" def close(self): @@ -961,7 +1003,8 @@ class CharCountingQueue(queue.Queue): try: if not self._will_it_fit(item) and partial: space_left = self.maxsize - self._qsize() - item = item[:space_left] + if space_left: + item = item[:space_left] if not block: if not self._will_it_fit(item): diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index 5ff7585f..6867aedf 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -72,6 +72,10 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._selectedFile = None self._timeEstimationData = None + self._timeEstimationStatsWeighingUntil = settings().getFloat(["estimation", "printTime", "statsWeighingUntil"]) + self._timeEstimationValidityRange = settings().getFloat(["estimation", "printTime", "validityRange"]) + self._timeEstimationForceDumbFromPercent = settings().getFloat(["estimation", "printTime", "forceDumbFromPercent"]) + self._timeEstimationForceDumbAfterMin = settings().getFloat(["estimation", "printTime", "forceDumbAfterMin"]) # comm self._comm = None @@ -407,20 +411,21 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): if self._selectedFile is None: return + # we are happy if the average of the estimates stays within 60s of the prior one + threshold = settings().getFloat(["estimation", "printTime", "stableThreshold"]) rolling_window = None - threshold = None countdown = None + if self._selectedFile["sd"]: # we are interesting in a rolling window of roughly the last 15s, so the number of entries has to be derived # by that divided by the sd status polling interval rolling_window = 15 / settings().get(["serial", "timeout", "sdStatus"]) - # we are happy if the average of the estimates stays within 60s of the prior one - threshold = 60 - # we are happy when one rolling window has been stable countdown = rolling_window - self._timeEstimationData = TimeEstimationHelper(rolling_window=rolling_window, threshold=threshold, countdown=countdown) + self._timeEstimationData = TimeEstimationHelper(rolling_window=rolling_window, + threshold=threshold, + countdown=countdown) self._fileManager.delete_recovery_data() @@ -614,9 +619,12 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._currentZ = currentZ self._stateMonitor.set_current_z(self._currentZ) - def _setState(self, state): + def _setState(self, state, state_string=None): + if state_string is None: + state_string = self.get_state_string() + self._state = state - self._stateMonitor.set_state({"text": self.get_state_string(), "flags": self._getStateFlags()}) + self._stateMonitor.set_state({"text": state_string, "flags": self._getStateFlags()}) payload = dict( state_id=self.get_state_id(self._state), @@ -664,22 +672,14 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): printTime = self._comm.getPrintTime() cleanedPrintTime = self._comm.getCleanedPrintTime() - estimatedTotalPrintTime = self._estimateTotalPrintTime(progress, cleanedPrintTime) - totalPrintTime = estimatedTotalPrintTime - - if self._selectedFile and "estimatedPrintTime" in self._selectedFile and self._selectedFile["estimatedPrintTime"]: + statisticalTotalPrintTime = None + statisticalTotalPrintTimeType = None + if self._selectedFile and "estimatedPrintTime" in self._selectedFile \ + and self._selectedFile["estimatedPrintTime"]: statisticalTotalPrintTime = self._selectedFile["estimatedPrintTime"] - if progress and cleanedPrintTime: - if estimatedTotalPrintTime is None: - totalPrintTime = statisticalTotalPrintTime - else: - if progress < 0.5: - sub_progress = progress * 2 - else: - sub_progress = 1.0 - totalPrintTime = (1 - sub_progress) * statisticalTotalPrintTime + sub_progress * estimatedTotalPrintTime + statisticalTotalPrintTimeType = self._selectedFile.get("estimatedPrintTimeType", None) - printTimeLeft = totalPrintTime - cleanedPrintTime if (totalPrintTime is not None and cleanedPrintTime is not None) else None + printTimeLeft, printTimeLeftOrigin = self._estimatePrintTimeLeft(progress, printTime, cleanedPrintTime, statisticalTotalPrintTime, statisticalTotalPrintTimeType) if progress is not None: progress_int = int(progress * 100) @@ -690,7 +690,123 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): return dict(completion=progress * 100 if progress is not None else None, filepos=filepos, printTime=int(printTime) if printTime is not None else None, - printTimeLeft=int(printTimeLeft) if printTimeLeft is not None else None) + printTimeLeft=int(printTimeLeft) if printTimeLeft is not None else None, + printTimeLeftOrigin=printTimeLeftOrigin) + + def _estimatePrintTimeLeft(self, progress, printTime, cleanedPrintTime, statisticalTotalPrintTime, statisticalTotalPrintTimeType): + """ + Tries to estimate the print time left for the print job + + This is somewhat horrible since accurate print time estimation is pretty much impossible to + achieve, considering that we basically have only two data points (current progress in file and + time needed for that so far - former prints or a file analysis might not have happened or simply + be completely impossible e.g. if the file is stored on the printer's SD card) and + hence can only do a linear estimation of a completely non-linear process. That's a recipe + for inaccurate predictions right there. Yay. + + Anyhow, here's how this implementation works. This method gets the current progress in the + printed file (percentage based on bytes read vs total bytes), the print time that elapsed, + the same print time with the heat up times subtracted (if possible) and if available also + some statistical total print time (former prints or a result from the GCODE analysis). + + 1. First get an "intelligent" estimate based on the :class:`~octoprint.printer.estimation.TimeEstimationHelper`. + That thing tries to detect if the estimation based on our progress and time needed for that becomes + stable over time through a rolling window and only returns a result once that appears to be the + case. + 2. If we have any statistical data (former prints or a result from the GCODE analysis) + but no intelligent estimate yet, we'll use that for the next step. Otherwise, up to a certain percentage + in the print we do a percentage based weighing of the statistical data and the intelligent + estimate - the closer to the beginning of the print, the more precedence for the statistical + data, the closer to the cut off point, the more precendence for the intelligent estimate. This + is our preliminary total print time. + 3. If the total print time is set, we do a sanity check for it. Based on the total print time + estimate and the time we already spent printing, we calculate at what percentage we SHOULD be + and compare that to the percentage at which we actually ARE. If it's too far off, our total + can't be trusted and we fall back on the dumb estimate. Same if the time we spent printing is + already higher than our total estimate. + 4. If we do NOT have a total print time estimate yet but we've been printing for longer than + a configured amount of minutes or are further in the file than a configured percentage, we + also use the dumb estimate for now. + + Yes, all this still produces horribly inaccurate results. But we have to do this live during the print and + hence can't produce to much computational overhead, we do not have any insight into the firmware implementation + with regards to planner setup and acceleration settings, we might not even have access to the printed file's + contents and such we need to find something that works "mostly" all of the time without costing too many + resources. Feel free to propose a better solution within the above limitations (and I mean that, this solution + here makes me unhappy). + + Args: + progress (float or None): Current percentage in the printed file + printTime (float or None): Print time elapsed so far + cleanedPrintTime (float or None): Print time elapsed minus the time needed for getting up to temperature + (if detectable). + statisticalTotalPrintTime (float or None): Total print time of past prints against same printer profile, + or estimated total print time from GCODE analysis. + statisticalTotalPrintTimeType (str or None): Type of statistical print time, either "average" (total time + of former prints) or "analysis" + + Returns: + (2-tuple) estimated print time left or None if not proper estimate could be made at all, origin of estimation + """ + + if progress is None or printTime is None or cleanedPrintTime is None: + return None + + dumbTotalPrintTime = printTime / progress + estimatedTotalPrintTime = self._estimateTotalPrintTime(progress, cleanedPrintTime) + totalPrintTime = estimatedTotalPrintTime + + printTimeLeftOrigin = "estimate" + if statisticalTotalPrintTime is not None: + if estimatedTotalPrintTime is None: + # no estimate yet, we'll use the statistical total + totalPrintTime = statisticalTotalPrintTime + printTimeLeftOrigin = statisticalTotalPrintTimeType + + else: + if progress < self._timeEstimationStatsWeighingUntil: + # still inside weighing range, use part stats, part current estimate + sub_progress = progress * (1 / self._timeEstimationStatsWeighingUntil) + if sub_progress > 1.0: + sub_progress = 1.0 + printTimeLeftOrigin = "mixed-" + statisticalTotalPrintTimeType + else: + # use only the current estimate + sub_progress = 1.0 + printTimeLeftOrigin = "estimate" + + # combine + totalPrintTime = (1.0 - sub_progress) * statisticalTotalPrintTime \ + + sub_progress * estimatedTotalPrintTime + + printTimeLeft = None + if totalPrintTime is not None: + # sanity check current total print time estimate + assumed_progress = cleanedPrintTime / totalPrintTime + min_progress = progress - self._timeEstimationValidityRange + max_progress = progress + self._timeEstimationValidityRange + + if min_progress <= assumed_progress <= max_progress and totalPrintTime > cleanedPrintTime: + # appears sane, we'll use it + printTimeLeft = totalPrintTime - cleanedPrintTime + + else: + # too far from the actual progress or negative, + # we use the dumb print time instead + printTimeLeft = dumbTotalPrintTime - cleanedPrintTime + printTimeLeftOrigin = "linear" + + elif progress > self._timeEstimationForceDumbFromPercent or \ + cleanedPrintTime * 60 >= self._timeEstimationForceDumbAfterMin: + # more than x% or y min printed and still no real estimate, ok, we'll use the dumb variant :/ + printTimeLeft = dumbTotalPrintTime - cleanedPrintTime + printTimeLeftOrigin = "linear" + + if printTimeLeft < 0: + # shouldn't actually happen, but let's make sure + return None, None + + return printTimeLeft, printTimeLeftOrigin def _addTemperatureData(self, temp, bedTemp): currentTimeUtc = int(time.time()) @@ -781,9 +897,11 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): if averagePrintTime is not None: self._selectedFile["estimatedPrintTime"] = averagePrintTime + self._selectedFile["estimatedPrintTimeType"] = "average" elif estimatedPrintTime is not None: # TODO apply factor which first needs to be tracked! self._selectedFile["estimatedPrintTime"] = estimatedPrintTime + self._selectedFile["estimatedPrintTimeType"] = "analysis" self._stateMonitor.set_job_data({ "file": { @@ -839,6 +957,9 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): """ oldState = self._state + if self._comm is not None: + state_string = self._comm.getStateString() + # forward relevant state changes to gcode manager if oldState == comm.MachineCom.STATE_PRINTING: if self._selectedFile is not None: @@ -858,7 +979,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self._printerProfileManager.deselect() eventManager().fire(Events.DISCONNECTED) - self._setState(state) + self._setState(state, state_string=state_string) def on_comm_message(self, message): """ diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index b47b89b8..b3f35844 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -12,7 +12,6 @@ from flask.ext.login import LoginManager, current_user from flask.ext.principal import Principal, Permission, RoleNeed, identity_loaded, UserNeed from flask.ext.babel import Babel, gettext, ngettext from flask.ext.assets import Environment, Bundle -from flaskext.markdown import Markdown from babel import Locale from watchdog.observers import Observer from watchdog.observers.polling import PollingObserver @@ -600,7 +599,8 @@ class Server(object): response.headers.add("X-Clacks-Overhead", "GNU Terry Pratchett") return response - Markdown(app) + from octoprint.util.jinja import MarkdownFilter + MarkdownFilter(app) def _setup_i18n(self, app): global babel diff --git a/src/octoprint/server/api/files.py b/src/octoprint/server/api/files.py index a605bfd3..5279d5a4 100644 --- a/src/octoprint/server/api/files.py +++ b/src/octoprint/server/api/files.py @@ -278,7 +278,7 @@ def uploadGcodeFile(target): done = True else: filename = fileProcessingFinished(added_file, fileManager.path_on_disk(FileDestinations.LOCAL, added_file), target) - done = True + done = not sd if userdata is not None: # upload included userdata, add this now to the metadata diff --git a/src/octoprint/server/api/settings.py b/src/octoprint/server/api/settings.py index d55d1f47..be74a5ba 100644 --- a/src/octoprint/server/api/settings.py +++ b/src/octoprint/server/api/settings.py @@ -98,7 +98,10 @@ def getSettings(): "ignoreErrorsFromFirmware": s.getBoolean(["serial", "ignoreErrorsFromFirmware"]), "disconnectOnErrors": s.getBoolean(["serial", "disconnectOnErrors"]), "triggerOkForM29": s.getBoolean(["serial", "triggerOkForM29"]), - "supportResendsWithoutOk": s.getBoolean(["serial", "supportResendsWithoutOk"]) + "supportResendsWithoutOk": s.getBoolean(["serial", "supportResendsWithoutOk"]), + "maxTimeoutsIdle": s.getInt(["serial", "maxCommunicationTimeouts", "idle"]), + "maxTimeoutsPrinting": s.getInt(["serial", "maxCommunicationTimeouts", "printing"]), + "maxTimeoutsLong": s.getInt(["serial", "maxCommunicationTimeouts", "long"]) }, "folder": { "uploads": s.getBaseFolder("uploads"), @@ -259,6 +262,9 @@ def _saveSettings(data): if "disconnectOnErrors" in data["serial"]: s.setBoolean(["serial", "disconnectOnErrors"], data["serial"]["disconnectOnErrors"]) if "triggerOkForM29" in data["serial"]: s.setBoolean(["serial", "triggerOkForM29"], data["serial"]["triggerOkForM29"]) if "supportResendsWithoutOk" in data["serial"]: s.setBoolean(["serial", "supportResendsWithoutOk"], data["serial"]["supportResendsWithoutOk"]) + if "maxTimeoutsIdle" in data["serial"]: s.setInt(["serial", "maxCommunicationTimeouts", "idle"], data["serial"]["maxTimeoutsIdle"]) + if "maxTimeoutsPrinting" in data["serial"]: s.setInt(["serial", "maxCommunicationTimeouts", "printing"], data["serial"]["maxTimeoutsPrinting"]) + if "maxTimeoutsLong" in data["serial"]: s.setInt(["serial", "maxCommunicationTimeouts", "long"], data["serial"]["maxTimeoutsLong"]) oldLog = s.getBoolean(["serial", "log"]) if "log" in data["serial"].keys(): s.setBoolean(["serial", "log"], data["serial"]["log"]) diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index 7869e64d..34ef52a1 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -907,6 +907,7 @@ def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"): assets["js"] = [ 'js/app/bindings/allowbindings.js', 'js/app/bindings/contextmenu.js', + 'js/app/bindings/copywidth.js', 'js/app/bindings/invisible.js', 'js/app/bindings/popover.js', 'js/app/bindings/qrcode.js', diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py index 2d478191..08f17a19 100644 --- a/src/octoprint/settings.py +++ b/src/octoprint/settings.py @@ -94,6 +94,12 @@ default_settings = { "temperatureTargetSet": 2, "sdStatus": 1 }, + "maxCommunicationTimeouts": { + "idle": 2, + "printing": 5, + "long": 5 + }, + "maxWritePasses": 5, "additionalPorts": [], "additionalBaudrates": [], "longRunningCommands": ["G4", "G28", "G29", "G30", "G32", "M400", "M226"], @@ -293,6 +299,15 @@ default_settings = { } } }, + "estimation": { + "printTime": { + "statsWeighingUntil": 0.5, + "validityRange": 0.15, + "forceDumbFromPercent": 0.3, + "forceDumbAfterMin": 30, + "stableThreshold": 60 + } + }, "devel": { "stylesheet": "css", "cache": { diff --git a/src/octoprint/static/css/octoprint.css b/src/octoprint/static/css/octoprint.css index eb3b9127..ea19e431 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,.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;*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.active,.btn.disabled,.btn:active,.btn:focus,.btn:hover,.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:focus,.btn:hover{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:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;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{color:#fff;text-shadow:0 -1px 0 rgba(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;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary.active,.btn-primary.disabled,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.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,.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;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning.active,.btn-warning.disabled,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.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,.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;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger.active,.btn-danger.disabled,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.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,.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;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success.active,.btn-success.disabled,.btn-success:active,.btn-success:focus,.btn-success:hover,.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,.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;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info.active,.btn-info.disabled,.btn-info:active,.btn-info:focus,.btn-info:hover,.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,.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;border-color:#222 #222 #000;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse.active,.btn-inverse.disabled,.btn-inverse:active,.btn-inverse:focus,.btn-inverse:hover,.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:focus,.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover{color:#333;text-decoration:none}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{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 #ccc;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:focus .caret,#navbar .navbar-inner .brand:hover .caret,#navbar .navbar-inner .nav>li>a:focus .caret,#navbar .navbar-inner .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,.6)),to(rgba(204,204,204,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(255,255,255,.6),rgba(204,204,204,.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 #ccc;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:focus .caret,#navbar .navbar-inner.transparent .brand:hover .caret,#navbar .navbar-inner.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(224,224,224,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(204,204,204,.6)),to(rgba(255,255,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(204,204,204,.6),rgba(255,255,255,.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 #d86761;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:focus .caret,#navbar .navbar-inner.red .brand:hover .caret,#navbar .navbar-inner.red .nav>li>a:focus .caret,#navbar .navbar-inner.red .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(226,142,138,.6)),to(rgba(128,36,32,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(226,142,138,.6),rgba(128,36,32,.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 #d86761;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:focus .caret,#navbar .navbar-inner.red.transparent .brand:hover .caret,#navbar .navbar-inner.red.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.red.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(167,79,74,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(128,36,32,.6)),to(rgba(226,142,138,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(128,36,32,.6),rgba(226,142,138,.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:focus .caret,#navbar .navbar-inner.orange .brand:hover .caret,#navbar .navbar-inner.orange .nav>li>a:focus .caret,#navbar .navbar-inner.orange .nav>li>a:hover .caret{border-bottom-color:#f2d3bf;border-top-color:#f2d3bf}#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.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,195,160,.6)),to(rgba(194,83,12,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(249,195,160,.6),rgba(194,83,12,.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:focus .caret,#navbar .navbar-inner.orange.transparent .brand:hover .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:hover .caret{border-bottom-color:#f2d3bf;border-top-color:#f2d3bf}#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.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(216,128,71,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,83,12,.6)),to(rgba(249,195,160,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(194,83,12,.6),rgba(249,195,160,.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 #c2b00c;color:#f2f2f2}#navbar .navbar-inner.yellow .brand .caret,#navbar .navbar-inner.yellow .nav>li>a .caret{border-bottom-color:#f2e88d;border-top-color:#f2e88d}#navbar .navbar-inner.yellow .brand:focus .caret,#navbar .navbar-inner.yellow .brand:hover .caret,#navbar .navbar-inner.yellow .nav>li>a:focus .caret,#navbar .navbar-inner.yellow .nav>li>a:hover .caret{border-bottom-color:#f2edbf;border-top-color:#f2edbf}#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.yellow .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,240,160,.6)),to(rgba(194,176,12,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(249,240,160,.6),rgba(194,176,12,.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 #c2b00c;color:#f2f2f2}#navbar .navbar-inner.yellow.transparent .brand .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a .caret{border-bottom-color:#f2e88d;border-top-color:#f2e88d}#navbar .navbar-inner.yellow.transparent .brand:focus .caret,#navbar .navbar-inner.yellow.transparent .brand:hover .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:hover .caret{border-bottom-color:#f2edbf;border-top-color:#f2edbf}#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.yellow.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(216,202,71,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,176,12,.6)),to(rgba(249,240,160,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(194,176,12,.6),rgba(249,240,160,.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 #50da00;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:focus .caret,#navbar .navbar-inner.green .brand:hover .caret,#navbar .navbar-inner.green .nav>li>a:focus .caret,#navbar .navbar-inner.green .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,255,167,.6)),to(rgba(80,218,0,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,255,167,.6),rgba(80,218,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 #50da00;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:focus .caret,#navbar .navbar-inner.green.transparent .brand:hover .caret,#navbar .navbar-inner.green.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.green.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(128,233,67,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,218,0,.6)),to(rgba(200,255,167,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(80,218,0,.6),rgba(200,255,167,.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 #1a66ff;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:focus .caret,#navbar .navbar-inner.blue .brand:hover .caret,#navbar .navbar-inner.blue .nav>li>a:focus .caret,#navbar .navbar-inner.blue .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(77,136,255,.6)),to(rgba(0,43,128,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(77,136,255,.6),rgba(0,43,128,.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 #1a66ff;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:focus .caret,#navbar .navbar-inner.blue.transparent .brand:hover .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(31,80,179,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(0,43,128,.6)),to(rgba(77,136,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(0,43,128,.6),rgba(77,136,255,.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 #a774ff;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:focus .caret,#navbar .navbar-inner.violet .brand:hover .caret,#navbar .navbar-inner.violet .nav>li>a:focus .caret,#navbar .navbar-inner.violet .nav>li>a:hover .caret{border-bottom-color:#d3bff5;border-top-color:#d3bff5}#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.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,167,255,.6)),to(rgba(80,0,218,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,167,255,.6),rgba(80,0,218,.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 #a774ff;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:focus .caret,#navbar .navbar-inner.violet.transparent .brand:hover .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:hover .caret{border-bottom-color:#d3bff5;border-top-color:#d3bff5}#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.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(128,67,233,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,0,218,.6)),to(rgba(200,167,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(80,0,218,.6),rgba(200,167,255,.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 #5e5e5e;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:focus .caret,#navbar .navbar-inner.black .brand:hover .caret,#navbar .navbar-inner.black .nav>li>a:focus .caret,#navbar .navbar-inner.black .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(120,120,120,.6)),to(rgba(18,18,18,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(120,120,120,.6),rgba(18,18,18,.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 #5e5e5e;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:focus .caret,#navbar .navbar-inner.black.transparent .brand:hover .caret,#navbar .navbar-inner.black.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.black.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(59,59,59,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(18,18,18,.6)),to(rgba(120,120,120,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(18,18,18,.6),rgba(120,120,120,.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 #c8c8c8;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:focus .caret,#navbar .navbar-inner.white .brand:hover .caret,#navbar .navbar-inner.white .nav>li>a:focus .caret,#navbar .navbar-inner.white .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,.6)),to(rgba(200,200,200,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(255,255,255,.6),rgba(200,200,200,.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 #c8c8c8;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:focus .caret,#navbar .navbar-inner.white.transparent .brand:hover .caret,#navbar .navbar-inner.white.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.white.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(222,222,222,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,200,200,.6)),to(rgba(255,255,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,200,200,.6),rgba(255,255,255,.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:400}.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 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 td,table th{overflow:hidden}table td.gcode_files_name,table th.gcode_files_name{text-overflow:ellipsis;text-align:left;white-space:nowrap}table td.gcode_files_action,table th.gcode_files_action{width:90px;text-align:center;white-space:nowrap}table td.gcode_files_action a,table th.gcode_files_action a{text-decoration:none;color:#000}table td.gcode_files_action a.disabled,table th.gcode_files_action a.disabled{color:#ccc;cursor:default}table td.timelapse_files_name,table td.timelapse_unrendered_name,table th.timelapse_files_name,table th.timelapse_unrendered_name{text-overflow:ellipsis;text-align:left}table td.timelapse_files_size,table td.timelapse_unrendered_size,table th.timelapse_files_size,table th.timelapse_unrendered_size{text-align:right;width:55px}table td.timelapse_unrendered_count,table th.timelapse_unrendered_count{text-align:right;width:45px}table td.timelapse_files_action,table td.timelapse_unrendered_action,table th.timelapse_files_action,table th.timelapse_unrendered_action{width:45px;text-align:center;white-space:nowrap}table td.timelapse_files_action a,table td.timelapse_unrendered_action a,table th.timelapse_files_action a,table th.timelapse_unrendered_action a{text-decoration:none;color:#000}table td.timelapse_files_action a.disabled,table td.timelapse_unrendered_action a.disabled,table th.timelapse_files_action a.disabled,table th.timelapse_unrendered_action a.disabled{color:#ccc;cursor:default}table td.settings_users_name,table th.settings_users_name{text-overflow:ellipsis;text-align:left}table td.settings_users_active,table td.settings_users_admin,table th.settings_users_active,table th.settings_users_admin{text-align:center;width:55px}table td.settings_users_actions,table th.settings_users_actions{width:60px;text-align:center;white-space:nowrap}table td.settings_users_actions a,table th.settings_users_actions a{text-decoration:none;color:#000}table td.settings_users_actions a.disabled,table th.settings_users_actions a.disabled{color:#ccc;cursor:default}table td.settings_logs_name,table th.settings_logs_name{text-overflow:ellipsis;text-align:left}table td.settings_logs_size,table th.settings_logs_size{text-align:right;width:70px}table td.settings_logs_date,table th.settings_logs_date{text-align:left;width:130px}table td.settings_logs_action,table th.settings_logs_action{width:70px;text-align:center;white-space:nowrap}table td.settings_logs_action a,table th.settings_logs_action a{text-decoration:none;color:#000}table td.settings_logs_action a.disabled,table th.settings_logs_action a.disabled{color:#ccc;cursor:default}table td.settings_printerProfiles_profiles_name,table th.settings_printerProfiles_profiles_name{text-overflow:ellipsis;text-align:left}table td.settings_printerProfiles_profiles_model,table th.settings_printerProfiles_profiles_model{text-align:left;width:250px}table td.settings_printerProfiles_profiles_action,table th.settings_printerProfiles_profiles_action{width:80px;text-align:center;white-space:nowrap}table td.settings_printerProfiles_profiles_action a,table th.settings_printerProfiles_profiles_action a{text-decoration:none;color:#000}table td.settings_printerProfiles_profiles_action a.disabled,table th.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}#speed_fill,#speed_innerWall,#speed_outerWall,#speed_support,#temp_newBedTemp,#temp_newTemp,#webcam_timelapse_fps,#webcam_timelapse_interval,#webcam_timelapse_postRoll,#webcam_timelapse_retractionZHop{text-align:right}ul.dropdown-menu li a{cursor:pointer}#connection_baudrates,#connection_ports,#connection_printers{width:100%}#offline_overlay,#reloadui_overlay{position:fixed;top:0;left:0;width:100%;height:100%;display:none}#offline_overlay{z-index:10002}#reloadui_overlay{z-index:10001}#offline_overlay_background,#reloadui_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,#reloadui_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#offline_overlay_wrapper .container,#reloadui_overlay_wrapper .container{margin:auto}#webcam_container{width:100%;position:relative;outline:0}#webcam_container .keycontrol_overlay{position:absolute;left:10px;right:10px;bottom:10px;background:rgba(0,0,0,.5);font-size:85%;color:#fff;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:700}#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 .additionalInfo,#files .gcode_files .entry .size,#files .gcode_files .entry .uploaded{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}@keyframes highlightframes{0%{background:#ff0}100%{background:0 0}}#files .gcode_files .entry.highlight{animation:highlightframes 2s}#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 h1{cursor:pointer}#control .custom_section_horizontal>.custom_control{display:inline-block}#control .custom_section_vertical>.custom_control{display: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 .canvas_container{position:relative}#gcode .canvas_container:active,#gcode .canvas_container:hover{outline:0}#gcode #gcode_layer_slider{position:absolute;right:0;top:0;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,#term .terminal #terminal-output-lowfi{min-height:340px;margin-bottom:5px}#term #terminal-sendpanel{text-align:right}#settings_dialog .aboutlink{float:left}#settings_dialog_menu,#wizard_dialog_menu{margin-left:0}#wizard_firstrun_acl .acl_decision{margin-top:1em}#settings_appearance_managelanguagesdialog_emptylist{overflow:hidden;width:100%;height:300px;text-align:center;display:table}#settings_appearance_managelanguagesdialog_emptylist div{display:table-cell;vertical-align:middle}.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-danger a,.ui-pnotify .alert-error 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}.text-center{text-align:center}.overflow_visible{overflow:visible!important}.clickable{cursor:pointer}.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;-khtml-opacity:1;opacity:1}#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}.flipH{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1)}.flipV{-webkit-transform:scaleY(-1);-moz-transform:scaleY(-1);-ms-transform:scaleY(-1)}.flipH.flipV{-webkit-transform:scaleX(-1) scaleY(-1);-moz-transform:scaleX(-1) scaleY(-1);-ms-transform:scaleX(-1) scaleY(-1)}.rotate90{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.ui-pnotify a{text-decoration:underline}.slider .slider-selection{color:#fff;text-shadow:0 -1px 0 rgba(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;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.slider .slider-selection.active,.slider .slider-selection.disabled,.slider .slider-selection:active,.slider .slider-selection:focus,.slider .slider-selection:hover,.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,.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(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;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,.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;*background-color:#e6e6e6;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.active,.slider .slider-handle.disabled,.slider .slider-handle:active,.slider .slider-handle:focus,.slider .slider-handle:hover,.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:focus,.slider .slider-handle:hover{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:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;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%}.modal.large{width:975px;margin-left:-487px}.full-sized-box{position:absolute;bottom:0;left:0;right:0;top:0;padding:15px}.full-sized-box .row-fluid{height:100%}@media (max-width:979px){.full-sized-box{position:static}}:root .full-sized-box,_::-webkit-full-page-media,_:future{position:static}.scrollable{height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.input-append .add-on.add-on-limited,.input-prepend .add-on.add-on-limited{overflow-x:hidden;text-overflow:ellipsis;width:inherit}.control-group.error .input-append .fileinput-button,.control-group.error .input-prepend .fileinput-button{border-color:#b94a48}input[type=number]{text-align:right} \ 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,.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;*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.active,.btn.disabled,.btn:active,.btn:focus,.btn:hover,.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:focus,.btn:hover{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:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;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{color:#fff;text-shadow:0 -1px 0 rgba(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;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary.active,.btn-primary.disabled,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.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,.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;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning.active,.btn-warning.disabled,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.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,.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;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger.active,.btn-danger.disabled,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.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,.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;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success.active,.btn-success.disabled,.btn-success:active,.btn-success:focus,.btn-success:hover,.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,.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;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info.active,.btn-info.disabled,.btn-info:active,.btn-info:focus,.btn-info:hover,.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,.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;border-color:#222 #222 #000;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#222;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse.active,.btn-inverse.disabled,.btn-inverse:active,.btn-inverse:focus,.btn-inverse:hover,.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:focus,.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover{color:#333;text-decoration:none}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{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 #ccc;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:focus .caret,#navbar .navbar-inner .brand:hover .caret,#navbar .navbar-inner .nav>li>a:focus .caret,#navbar .navbar-inner .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,.6)),to(rgba(204,204,204,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(255,255,255,.6),rgba(204,204,204,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(255,255,255,.6),rgba(204,204,204,.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 #ccc;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:focus .caret,#navbar .navbar-inner.transparent .brand:hover .caret,#navbar .navbar-inner.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(224,224,224,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(204,204,204,.6)),to(rgba(255,255,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(204,204,204,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(204,204,204,.6),rgba(255,255,255,.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 #d86761;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:focus .caret,#navbar .navbar-inner.red .brand:hover .caret,#navbar .navbar-inner.red .nav>li>a:focus .caret,#navbar .navbar-inner.red .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.red .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(226,142,138,.6)),to(rgba(128,36,32,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(226,142,138,.6),rgba(128,36,32,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(226,142,138,.6),rgba(128,36,32,.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 #d86761;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:focus .caret,#navbar .navbar-inner.red.transparent .brand:hover .caret,#navbar .navbar-inner.red.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.red.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.red.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(167,79,74,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(128,36,32,.6)),to(rgba(226,142,138,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(128,36,32,.6),rgba(226,142,138,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(128,36,32,.6),rgba(226,142,138,.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:focus .caret,#navbar .navbar-inner.orange .brand:hover .caret,#navbar .navbar-inner.orange .nav>li>a:focus .caret,#navbar .navbar-inner.orange .nav>li>a:hover .caret{border-bottom-color:#f2d3bf;border-top-color:#f2d3bf}#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.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.orange .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,195,160,.6)),to(rgba(194,83,12,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(249,195,160,.6),rgba(194,83,12,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(249,195,160,.6),rgba(194,83,12,.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:focus .caret,#navbar .navbar-inner.orange.transparent .brand:hover .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.orange.transparent .nav>li>a:hover .caret{border-bottom-color:#f2d3bf;border-top-color:#f2d3bf}#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.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.orange.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(216,128,71,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,83,12,.6)),to(rgba(249,195,160,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(194,83,12,.6),rgba(249,195,160,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(194,83,12,.6),rgba(249,195,160,.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 #c2b00c;color:#f2f2f2}#navbar .navbar-inner.yellow .brand .caret,#navbar .navbar-inner.yellow .nav>li>a .caret{border-bottom-color:#f2e88d;border-top-color:#f2e88d}#navbar .navbar-inner.yellow .brand:focus .caret,#navbar .navbar-inner.yellow .brand:hover .caret,#navbar .navbar-inner.yellow .nav>li>a:focus .caret,#navbar .navbar-inner.yellow .nav>li>a:hover .caret{border-bottom-color:#f2edbf;border-top-color:#f2edbf}#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.yellow .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.yellow .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(249,240,160,.6)),to(rgba(194,176,12,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(249,240,160,.6),rgba(194,176,12,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(249,240,160,.6),rgba(194,176,12,.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 #c2b00c;color:#f2f2f2}#navbar .navbar-inner.yellow.transparent .brand .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a .caret{border-bottom-color:#f2e88d;border-top-color:#f2e88d}#navbar .navbar-inner.yellow.transparent .brand:focus .caret,#navbar .navbar-inner.yellow.transparent .brand:hover .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.yellow.transparent .nav>li>a:hover .caret{border-bottom-color:#f2edbf;border-top-color:#f2edbf}#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20-light.png)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi){#navbar .navbar-inner.yellow.transparent .brand span{background-image:url(../img/tentacle-20x20-light@2x.png)}}#navbar .navbar-inner.yellow.transparent .nav li.dropdown.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.yellow.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(216,202,71,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(194,176,12,.6)),to(rgba(249,240,160,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(194,176,12,.6),rgba(249,240,160,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(194,176,12,.6),rgba(249,240,160,.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 #50da00;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:focus .caret,#navbar .navbar-inner.green .brand:hover .caret,#navbar .navbar-inner.green .nav>li>a:focus .caret,#navbar .navbar-inner.green .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.green .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,255,167,.6)),to(rgba(80,218,0,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,255,167,.6),rgba(80,218,0,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,255,167,.6),rgba(80,218,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 #50da00;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:focus .caret,#navbar .navbar-inner.green.transparent .brand:hover .caret,#navbar .navbar-inner.green.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.green.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.green.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(128,233,67,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,218,0,.6)),to(rgba(200,255,167,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(80,218,0,.6),rgba(200,255,167,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(80,218,0,.6),rgba(200,255,167,.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 #1a66ff;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:focus .caret,#navbar .navbar-inner.blue .brand:hover .caret,#navbar .navbar-inner.blue .nav>li>a:focus .caret,#navbar .navbar-inner.blue .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.blue .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(77,136,255,.6)),to(rgba(0,43,128,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(77,136,255,.6),rgba(0,43,128,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(77,136,255,.6),rgba(0,43,128,.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 #1a66ff;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:focus .caret,#navbar .navbar-inner.blue.transparent .brand:hover .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.blue.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.blue.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(31,80,179,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(0,43,128,.6)),to(rgba(77,136,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(0,43,128,.6),rgba(77,136,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(0,43,128,.6),rgba(77,136,255,.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 #a774ff;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:focus .caret,#navbar .navbar-inner.violet .brand:hover .caret,#navbar .navbar-inner.violet .nav>li>a:focus .caret,#navbar .navbar-inner.violet .nav>li>a:hover .caret{border-bottom-color:#d3bff5;border-top-color:#d3bff5}#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.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.violet .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,167,255,.6)),to(rgba(80,0,218,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,167,255,.6),rgba(80,0,218,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,167,255,.6),rgba(80,0,218,.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 #a774ff;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:focus .caret,#navbar .navbar-inner.violet.transparent .brand:hover .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.violet.transparent .nav>li>a:hover .caret{border-bottom-color:#d3bff5;border-top-color:#d3bff5}#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.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.violet.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(128,67,233,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(80,0,218,.6)),to(rgba(200,167,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(80,0,218,.6),rgba(200,167,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(80,0,218,.6),rgba(200,167,255,.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 #5e5e5e;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:focus .caret,#navbar .navbar-inner.black .brand:hover .caret,#navbar .navbar-inner.black .nav>li>a:focus .caret,#navbar .navbar-inner.black .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.black .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(120,120,120,.6)),to(rgba(18,18,18,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(120,120,120,.6),rgba(18,18,18,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(120,120,120,.6),rgba(18,18,18,.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 #5e5e5e;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:focus .caret,#navbar .navbar-inner.black.transparent .brand:hover .caret,#navbar .navbar-inner.black.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.black.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.black.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(59,59,59,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(18,18,18,.6)),to(rgba(120,120,120,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(18,18,18,.6),rgba(120,120,120,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(18,18,18,.6),rgba(120,120,120,.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 #c8c8c8;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:focus .caret,#navbar .navbar-inner.white .brand:hover .caret,#navbar .navbar-inner.white .nav>li>a:focus .caret,#navbar .navbar-inner.white .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.white .nav li.dropdown.open>.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,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(255,255,255,.6)),to(rgba(200,200,200,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(255,255,255,.6),rgba(200,200,200,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(255,255,255,.6),rgba(200,200,200,.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 #c8c8c8;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:focus .caret,#navbar .navbar-inner.white.transparent .brand:hover .caret,#navbar .navbar-inner.white.transparent .nav>li>a:focus .caret,#navbar .navbar-inner.white.transparent .nav>li>a:hover .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.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open.active>.dropdown-toggle,#navbar .navbar-inner.white.transparent .nav li.dropdown.open>.dropdown-toggle{background-color:rgba(222,222,222,.6);background-image:"../img/trans-background.png";background-image:-moz-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-webkit-gradient(linear,0 0,0 100%,from(rgba(200,200,200,.6)),to(rgba(255,255,255,.6))),url(../img/trans-background.png);background-image:-webkit-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:-o-linear-gradient(top,rgba(200,200,200,.6),rgba(255,255,255,.6)),url(../img/trans-background.png);background-image:linear-gradient(to bottom,rgba(200,200,200,.6),rgba(255,255,255,.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:400}.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 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 td,table th{overflow:hidden}table td.gcode_files_name,table th.gcode_files_name{text-overflow:ellipsis;text-align:left;white-space:nowrap}table td.gcode_files_action,table th.gcode_files_action{width:90px;text-align:center;white-space:nowrap}table td.gcode_files_action a,table th.gcode_files_action a{text-decoration:none;color:#000}table td.gcode_files_action a.disabled,table th.gcode_files_action a.disabled{color:#ccc;cursor:default}table td.timelapse_files_name,table td.timelapse_unrendered_name,table th.timelapse_files_name,table th.timelapse_unrendered_name{text-overflow:ellipsis;text-align:left}table td.timelapse_files_size,table td.timelapse_unrendered_size,table th.timelapse_files_size,table th.timelapse_unrendered_size{text-align:right;width:55px}table td.timelapse_unrendered_count,table th.timelapse_unrendered_count{text-align:right;width:45px}table td.timelapse_files_action,table td.timelapse_unrendered_action,table th.timelapse_files_action,table th.timelapse_unrendered_action{width:45px;text-align:center;white-space:nowrap}table td.timelapse_files_action a,table td.timelapse_unrendered_action a,table th.timelapse_files_action a,table th.timelapse_unrendered_action a{text-decoration:none;color:#000}table td.timelapse_files_action a.disabled,table td.timelapse_unrendered_action a.disabled,table th.timelapse_files_action a.disabled,table th.timelapse_unrendered_action a.disabled{color:#ccc;cursor:default}table td.settings_users_name,table th.settings_users_name{text-overflow:ellipsis;text-align:left}table td.settings_users_active,table td.settings_users_admin,table th.settings_users_active,table th.settings_users_admin{text-align:center;width:55px}table td.settings_users_actions,table th.settings_users_actions{width:60px;text-align:center;white-space:nowrap}table td.settings_users_actions a,table th.settings_users_actions a{text-decoration:none;color:#000}table td.settings_users_actions a.disabled,table th.settings_users_actions a.disabled{color:#ccc;cursor:default}table td.settings_logs_name,table th.settings_logs_name{text-overflow:ellipsis;text-align:left}table td.settings_logs_size,table th.settings_logs_size{text-align:right;width:70px}table td.settings_logs_date,table th.settings_logs_date{text-align:left;width:130px}table td.settings_logs_action,table th.settings_logs_action{width:70px;text-align:center;white-space:nowrap}table td.settings_logs_action a,table th.settings_logs_action a{text-decoration:none;color:#000}table td.settings_logs_action a.disabled,table th.settings_logs_action a.disabled{color:#ccc;cursor:default}table td.settings_printerProfiles_profiles_name,table th.settings_printerProfiles_profiles_name{text-overflow:ellipsis;text-align:left}table td.settings_printerProfiles_profiles_model,table th.settings_printerProfiles_profiles_model{text-align:left;width:250px}table td.settings_printerProfiles_profiles_action,table th.settings_printerProfiles_profiles_action{width:80px;text-align:center;white-space:nowrap}table td.settings_printerProfiles_profiles_action a,table th.settings_printerProfiles_profiles_action a{text-decoration:none;color:#000}table td.settings_printerProfiles_profiles_action a.disabled,table th.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}#speed_fill,#speed_innerWall,#speed_outerWall,#speed_support,#temp_newBedTemp,#temp_newTemp,#webcam_timelapse_fps,#webcam_timelapse_interval,#webcam_timelapse_postRoll{text-align:right}ul.dropdown-menu li a{cursor:pointer}#connection_baudrates,#connection_ports,#connection_printers{width:100%}#offline_overlay,#reloadui_overlay{position:fixed;top:0;left:0;width:100%;height:100%;display:none}#offline_overlay{z-index:10002}#reloadui_overlay{z-index:10001}#offline_overlay_background,#reloadui_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,#reloadui_overlay_wrapper{position:absolute;top:0;bottom:0;left:0;right:0;padding-top:60px}#offline_overlay_wrapper .container,#reloadui_overlay_wrapper .container{margin:auto}#webcam_container{width:100%;position:relative;outline:0}#webcam_container .flipH{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1)}#webcam_container .flipV{-webkit-transform:scaleY(-1);-moz-transform:scaleY(-1);-ms-transform:scaleY(-1)}#webcam_container .flipH.flipV{-webkit-transform:scaleX(-1) scaleY(-1);-moz-transform:scaleX(-1) scaleY(-1);-ms-transform:scaleX(-1) scaleY(-1)}#webcam_container .rotate90{transform:rotate(-90deg)}#webcam_container .keycontrol_overlay{position:absolute;left:10px;right:10px;bottom:10px;background:rgba(0,0,0,.5);font-size:85%;color:#fff;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:700}#webcam_container .keycontrol_overlay .keycontrol_overlay_column{position:relative;width:45%;padding:10px;float:left}#state_wrapper hr{margin:5px 0}#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 .additionalInfo,#files .gcode_files .entry .size,#files .gcode_files .entry .uploaded{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}@keyframes highlightframes{0%{background:#ff0}100%{background:0 0}}#files .gcode_files .entry.highlight{animation:highlightframes 2s}#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 h1{cursor:pointer}#control .custom_section_horizontal>.custom_control{display:inline-block}#control .custom_section_vertical>.custom_control{display: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 .canvas_container{position:relative}#gcode #gcode_layer_slider{position:absolute;right:0;top:0;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,#term .terminal #terminal-output-lowfi{min-height:340px;margin-bottom:5px}#term #terminal-sendpanel{text-align:right}#settings_dialog .modal-body #settings_dialog_menu{margin-left:0}#settings_dialog .aboutlink{float:left}#settings_appearance_managelanguagesdialog_emptylist{overflow:hidden;width:100%;height:300px;text-align:center;display:table}#settings_appearance_managelanguagesdialog_emptylist div{display:table-cell;vertical-align:middle}.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-danger a,.ui-pnotify .alert-error 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;-khtml-opacity:1;opacity:1}#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}.ui-pnotify a{text-decoration:underline}.slider .slider-selection{color:#fff;text-shadow:0 -1px 0 rgba(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;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);*background-color:#04c;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.slider .slider-selection.active,.slider .slider-selection.disabled,.slider .slider-selection:active,.slider .slider-selection:focus,.slider .slider-selection:hover,.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,.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(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;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,.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;*background-color:#e6e6e6;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.active,.slider .slider-handle.disabled,.slider .slider-handle:active,.slider .slider-handle:focus,.slider .slider-handle:hover,.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:focus,.slider .slider-handle:hover{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:#333 dotted thin;outline:-webkit-focus-ring-color auto 5px;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%}.modal.large{width:975px;margin-left:-487px}.full-sized-box{position:absolute;bottom:0;left:0;right:0;top:0;padding:15px}.full-sized-box .row-fluid{height:100%}@media (max-width:979px){.full-sized-box{position:static}}:root .full-sized-box,_::-webkit-full-page-media,_:future{position:static}.scrollable{height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.input-append .add-on.add-on-limited,.input-prepend .add-on.add-on-limited{overflow-x:hidden;text-overflow:ellipsis;width:inherit}.control-group.error .input-append .fileinput-button,.control-group.error .input-prepend .fileinput-button{border-color:#b94a48}input[type=number]{text-align:right}.progress-text,.progress-text-centered{position:relative}.progress-text .progress-text-back,.progress-text .progress-text-front,.progress-text-centered .progress-text-back,.progress-text-centered .progress-text-front{white-space:nowrap}.progress-text .progress-text-front,.progress-text-centered .progress-text-front{box-sizing:border-box;padding:0 10px;width:100%;display:block}.progress-text .progress-text-back,.progress-text-centered .progress-text-back{position:absolute;font-size:12px;line-height:20px;display:block;box-sizing:border-box;text-align:center;padding:0 10px}.progress-text .bar,.progress-text-centered .bar{position:absolute;overflow:hidden}.progress-text-centered .progress-text-front{position:absolute;font-size:12px;line-height:20px;display:block;text-align:center;color:#fff}.progress-text-centered .progress-text-back{width:100%} \ No newline at end of file diff --git a/src/octoprint/static/js/app/bindings/copywidth.js b/src/octoprint/static/js/app/bindings/copywidth.js new file mode 100644 index 00000000..6a04a86b --- /dev/null +++ b/src/octoprint/static/js/app/bindings/copywidth.js @@ -0,0 +1,38 @@ +ko.bindingHandlers.copyWidth = { + init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + var node = ko.bindingHandlers.copyWidth._getReferenceNode(element, valueAccessor); + ko.bindingHandlers.copyWidth._setWidth(node, element); + }, + update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + var node = ko.bindingHandlers.copyWidth._getReferenceNode(element, valueAccessor); + ko.bindingHandlers.copyWidth._setWidth(node, element); + }, + _setWidth: function(node, element) { + var width = node.width(); + if (!width) return; + if ($(element).width() == width) return; + element.style.width = width + "px"; + }, + _getReferenceNode: function(element, valueAccessor) { + var value = ko.utils.unwrapObservable(valueAccessor()); + if (!value) return; + + var parts = value.split(" "); + var node = $(element); + while (parts.length > 0) { + var part = parts.shift(); + if (part == ":parent") { + node = node.parent(); + } else { + var selector = part; + if (parts.length > 0) { + selector += " " + parts.join(" "); + } + node = $(selector, node); + break; + } + } + return node; + } +}; + diff --git a/src/octoprint/static/js/app/dataupdater.js b/src/octoprint/static/js/app/dataupdater.js index 2ce2ca9b..410e57c4 100644 --- a/src/octoprint/static/js/app/dataupdater.js +++ b/src/octoprint/static/js/app/dataupdater.js @@ -177,48 +177,7 @@ function DataUpdater(allViewModels) { log.debug("Got event " + type + " with payload: " + JSON.stringify(payload)); - if (type == "SettingsUpdated") { - if (payload && payload.hasOwnProperty("config_hash")) { - self._configHash = payload.config_hash; - } - } else if (type == "SlicingStarted") { - gcodeUploadProgress.addClass("progress-striped").addClass("active"); - gcodeUploadProgressBar.css("width", "100%"); - if (payload.progressAvailable) { - gcodeUploadProgressBar.text(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: 0})); - } else { - gcodeUploadProgressBar.text(gettext("Slicing ...")); - } - } else if (type == "SlicingDone") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - new PNotify({title: gettext("Slicing done"), text: _.sprintf(gettext("Sliced %(stl)s to %(gcode)s, took %(time).2f seconds"), payload), type: "success"}); - } else if (type == "SlicingCancelled") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - } else if (type == "SlicingFailed") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - - html = _.sprintf(gettext("Could not slice %(stl)s to %(gcode)s: %(reason)s"), payload); - new PNotify({title: gettext("Slicing failed"), text: html, type: "error", hide: false}); - } else if (type == "TransferStarted") { - gcodeUploadProgress.addClass("progress-striped").addClass("active"); - gcodeUploadProgressBar.css("width", "100%"); - gcodeUploadProgressBar.text(gettext("Streaming ...")); - } else if (type == "TransferDone") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - new PNotify({ - title: gettext("Streaming done"), - text: _.sprintf(gettext("Streamed %(local)s to %(remote)s on SD, took %(time).2f seconds"), payload), - type: "success" - }); - } else if (type == "PrintCancelled") { + if (type == "PrintCancelled") { if (payload.firmwareError) { new PNotify({ title: gettext("Unhandled communication error"), diff --git a/src/octoprint/static/js/app/viewmodels/files.js b/src/octoprint/static/js/app/viewmodels/files.js index 340393f3..5db73bee 100644 --- a/src/octoprint/static/js/app/viewmodels/files.js +++ b/src/octoprint/static/js/app/viewmodels/files.js @@ -73,6 +73,7 @@ $(function() { self.allItems = ko.observable(undefined); self.listStyle = ko.observable("folders_files"); self.currentPath = ko.observable(""); + self.uploadProgressText = ko.observable(); // initialize list helper self.listHelper = new ItemListHelper( @@ -795,10 +796,60 @@ $(function() { self.requestData(undefined, undefined, self.currentPath()); }; + self.onEventSlicingStarted = function(payload) { + self.uploadProgress + .addClass("progress-striped") + .addClass("active"); + self.uploadProgressBar.css("width", "100%"); + if (payload.progressAvailable) { + self.uploadProgressText(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: 0})); + } else { + self.uploadProgressText(gettext("Slicing ...")); + } + }; + + self.onSlicingProgress = function(slicer, modelPath, machinecodePath, progress) { + self.uploadProgressText(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: Math.round(progress)})); + }; + + self.onEventSlicingCancelled = function(payload) { + self.uploadProgress + .removeClass("progress-striped") + .removeClass("active"); + self.uploadProgressBar + .css("width", "0%"); + self.uploadProgressText(""); + }; + self.onEventSlicingDone = function(payload) { + self.uploadProgress + .removeClass("progress-striped") + .removeClass("active"); + self.uploadProgressBar + .css("width", "0%"); + self.uploadProgressText(""); + + new PNotify({ + title: gettext("Slicing done"), + text: _.sprintf(gettext("Sliced %(stl)s to %(gcode)s, took %(time).2f seconds"), payload), + type: "success" + }); + self.requestData(undefined, undefined, self.currentPath()); }; + self.onEventSlicingFailed = function(payload) { + self.uploadProgress + .removeClass("progress-striped") + .removeClass("active"); + self.uploadProgressBar + .css("width", "0%"); + self.uploadProgressText(""); + + var html = _.sprintf(gettext("Could not slice %(stl)s to %(gcode)s: %(reason)s"), payload); + new PNotify({title: gettext("Slicing failed"), text: html, type: "error", hide: false}); + }; + self.onEventMetadataAnalysisFinished = function(payload) { self.requestData(undefined, undefined, self.currentPath()); }; @@ -807,7 +858,29 @@ $(function() { self.requestData(undefined, undefined, self.currentPath()); }; + self.onEventTransferStarted = function(payload) { + self.uploadProgress + .addClass("progress-striped") + .addClass("active"); + self.uploadProgressBar + .css("width", "100%"); + self.uploadProgressText(gettext("Streaming ...")); + }; + self.onEventTransferDone = function(payload) { + self.uploadProgress + .removeClass("progress-striped") + .removeClass("active"); + self.uploadProgressBar + .css("width", "0"); + self.uploadProgressText(""); + + new PNotify({ + title: gettext("Streaming done"), + text: _.sprintf(gettext("Streamed %(local)s to %(remote)s on SD, took %(time).2f seconds"), payload), + type: "success" + }); + self.requestData(undefined, payload.remote, "sdcard"); }; @@ -858,8 +931,8 @@ $(function() { self._setProgressBar = function(percentage, text, active) { self.uploadProgressBar - .css("width", percentage + "%") - .text(text); + .css("width", percentage + "%"); + self.uploadProgressText(text); if (active) { self.uploadProgress diff --git a/src/octoprint/static/js/app/viewmodels/printerstate.js b/src/octoprint/static/js/app/viewmodels/printerstate.js index 0a0fd0c3..411d1248 100644 --- a/src/octoprint/static/js/app/viewmodels/printerstate.js +++ b/src/octoprint/static/js/app/viewmodels/printerstate.js @@ -31,6 +31,7 @@ $(function() { self.filepos = ko.observable(undefined); self.printTime = ko.observable(undefined); self.printTimeLeft = ko.observable(undefined); + self.printTimeLeftOrigin = ko.observable(undefined); self.sd = ko.observable(undefined); self.timelapse = ko.observable(undefined); @@ -84,11 +85,61 @@ $(function() { return formatFuzzyEstimation(self.printTimeLeft()); } }); + self.printTimeLeftOriginString = ko.pureComputed(function() { + var value = self.printTimeLeftOrigin(); + switch (value) { + case "linear": { + return gettext("Based on a linear approximation (accuracy highly dependent on the model)"); + } + case "analysis": { + return gettext("Based on the estimate from analysis of file (medium accuracy)"); + } + case "mixed-analysis": { + return gettext("Based on a mix of estimate from analysis and calculation (medium accuracy)"); + } + case "average": { + return gettext("Based on the average total of past prints of this model with the same printer profile (usually good accuracy)"); + } + case "mixed-average": { + return gettext("Based on a mix of average total from past prints and calculation (usually good accuracy)"); + } + case "estimate": { + return gettext("Based on the calculated estimate (best accuracy)"); + } + default: { + return ""; + } + } + }); + self.printTimeLeftOriginClass = ko.pureComputed(function() { + var value = self.printTimeLeftOrigin(); + switch (value) { + default: + case "linear": { + return "text-error"; + } + case "analysis": + case "mixed-analysis": { + return "text-warning"; + } + case "average": + case "mixed-average": + case "estimate": { + return "text-success"; + } + } + }); self.progressString = ko.pureComputed(function() { if (!self.progress()) return 0; return self.progress(); }); + self.progressBarString = ko.pureComputed(function() { + if (!self.progress()) { + return ""; + } + return _.sprintf("%d%%", self.progress()); + }); self.pauseString = ko.pureComputed(function() { if (self.isPaused()) return gettext("Continue"); @@ -194,6 +245,7 @@ $(function() { self.filepos(data.filepos); self.printTime(data.printTime); self.printTimeLeft(data.printTimeLeft); + self.printTimeLeftOrigin(data.printTimeLeftOrigin); }; self._processZData = function(data) { diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index 54fad672..3a91f120 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -155,6 +155,9 @@ $(function() { self.serial_disconnectOnErrors = ko.observable(undefined); self.serial_triggerOkForM29 = ko.observable(undefined); self.serial_supportResendsWithoutOk = ko.observable(undefined); + self.serial_maxTimeoutsIdle = ko.observable(undefined); + self.serial_maxTimeoutsPrinting = ko.observable(undefined); + self.serial_maxTimeoutsLong = ko.observable(undefined); self.folder_uploads = ko.observable(undefined); self.folder_timelapse = ko.observable(undefined); diff --git a/src/octoprint/static/less/octoprint.less b/src/octoprint/static/less/octoprint.less index 9f2d2da2..398fdb54 100644 --- a/src/octoprint/static/less/octoprint.less +++ b/src/octoprint/static/less/octoprint.less @@ -491,6 +491,14 @@ ul.dropdown-menu li a { } } +/** State sidebar panel */ + +#state_wrapper { + hr { + margin: 5px 0; + } +} + /** GCODE file manager */ #files { @@ -1071,3 +1079,55 @@ _::-webkit-full-page-media, _:future, :root .full-sized-box { input[type=number] { text-align: right; } + +// Progress bars with text +// +// .progress-text-front will also need to have the full width of the enclosing +// progress wrapper applied (e.g. via copyWidth knockout binding) + +.progress-text, +.progress-text-centered { + position: relative; + + .progress-text-front, + .progress-text-back { + white-space: nowrap; + } + + .progress-text-front { + box-sizing: border-box; + padding: 0 10px; + width: 100%; + display: block; + } + + .progress-text-back { + position: absolute; + font-size: 12px; + line-height: 20px; + display: block; + box-sizing: border-box; + text-align: center; + padding: 0 10px; + } + + .bar { + position: absolute; + overflow: hidden; + } +} + +.progress-text-centered { + .progress-text-front { + position: absolute; + font-size: 12px; + line-height: 20px; + display: block; + text-align: center; + color: #fff; + } + + .progress-text-back { + width: 100%; + } +} diff --git a/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 b/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 index cfac73a4..c4c3a380 100644 --- a/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 +++ b/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 @@ -141,6 +141,24 @@ {{ _('Simulate an additional `ok` for resend requests') }} +
start on connect"
msgstr "Bei der Verbindung auf start warten"
#: src/octoprint/templates/dialogs/settings/features.jinja2:40
+msgid "Select SD files by relative path"
+msgstr "SD Dateien per relativem Pfad addressieren"
+
+#: src/octoprint/templates/dialogs/settings/features.jinja2:40
+msgid "RepRap Firmware"
+msgstr "RepRap Firmware"
+
+#: src/octoprint/templates/dialogs/settings/features.jinja2:47
msgid "Always assume SD card is present"
msgstr "Immer davon ausgehen, dass eine SD-Karte vorhanden ist"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:40
#: src/octoprint/templates/dialogs/settings/features.jinja2:47
#: src/octoprint/templates/dialogs/settings/features.jinja2:54
#: src/octoprint/templates/dialogs/settings/features.jinja2:61
#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Repetier"
msgstr "Repetier"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:47
+#: src/octoprint/templates/dialogs/settings/features.jinja2:54
msgid "Send a checksum with every command"
msgstr "Eine Prüfsumme mit jedem Befehl senden"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:54
+#: src/octoprint/templates/dialogs/settings/features.jinja2:61
msgid "Ignore consecutive resend requests for the same line"
msgstr "Aufeinanderfolgende Resend Requests für die selbe Zeilennummer ignorieren"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:61
+#: src/octoprint/templates/dialogs/settings/features.jinja2:68
#, python-format
msgid "Support TargetExtr%%n/TargetBed target temperature format"
msgstr "TargetExtr%%n/TargetBed Zieltemperaturformat unterstützen"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Disable detection of external heatups"
msgstr "Detektierung externer Aufheizvorgänge deaktivieren"
@@ -1985,7 +1978,7 @@ msgstr "Falls der freie Plattenplatz unter diese Schwellwerte fallen sollte wird
#: src/octoprint/templates/dialogs/settings/folders.jinja2:47
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:69
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:90
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:66
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:69
#: src/octoprint/templates/tabs/timelapse.jinja2:13
msgid "Warning"
msgstr "Warnung"
@@ -2261,6 +2254,30 @@ msgstr "Viele Marlin < v1.1.0"
msgid "Simulate an additional `ok` for resend requests"
msgstr "Zusätzliches `ok` für Resendrequests simulieren"
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:129
+msgid "Maximum consecutive communication timeouts while idle. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts im Idlezustand. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:130
+msgid "Max. consecutive timeouts while idle"
+msgstr "Max. aufeinanderfolgende Timeouts wenn idle"
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:135
+msgid "Maximum consecutive communication timeouts while printing. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts beim Drucken. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:136
+msgid "Max. consecutive timeouts while printing"
+msgstr "Max. aufeinanderfolgende Timeouts beim Drucken"
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:141
+msgid "Maximum consecutive communication timeouts while a long running command is active. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts wenn ein lang laufender Befehl aktiv ist. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:142
+msgid "Max. consecutive timeouts during long running commands"
+msgstr "Max. aufeinanderfolgende Timeouts während lang laufender Befehle"
+
#: src/octoprint/templates/dialogs/settings/server.jinja2:2
msgid "Commands"
msgstr "Befehle"
@@ -2385,6 +2402,10 @@ msgstr "Änderungen der Oberflächensprache werden erst nach einem Neuladen der
msgid "Remember me"
msgstr "Login merken"
+#: src/octoprint/templates/navbar/login.jinja2:16
+msgid "User Settings"
+msgstr "Nutzereinstellungen"
+
#: src/octoprint/templates/navbar/login.jinja2:17
msgid "Logout"
msgstr "Logout"
@@ -2465,7 +2486,7 @@ msgstr "Frei"
msgid "Total"
msgstr "Gesamt"
-#: src/octoprint/templates/sidebar/files.jinja2:64
+#: src/octoprint/templates/sidebar/files.jinja2:67
msgid "Hint: You can also drag and drop files on this page to upload them."
msgstr "Hinweis: Du kannst auch Dateien auf diese Seite ziehen um sie hochzuladen."
@@ -2529,39 +2550,39 @@ msgstr "SD-Karte auswerfen"
msgid "Machine State"
msgstr "Druckerstatus"
-#: src/octoprint/templates/sidebar/state.jinja2:2
+#: src/octoprint/templates/sidebar/state.jinja2:3
msgid "File"
msgstr "Datei"
-#: src/octoprint/templates/sidebar/state.jinja2:7
+#: src/octoprint/templates/sidebar/state.jinja2:8
msgid "Approx. Total Print Time"
msgstr "Ungefähre Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:8
+#: src/octoprint/templates/sidebar/state.jinja2:10
msgid "Print Time"
msgstr "Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:9
+#: src/octoprint/templates/sidebar/state.jinja2:11
msgid "Print Time Left"
msgstr "Verbleibende Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:10
+#: src/octoprint/templates/sidebar/state.jinja2:12
msgid "Printed"
msgstr "Gedruckt"
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Restart"
msgstr "Restart"
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Print"
msgstr "Drucken"
-#: src/octoprint/templates/sidebar/state.jinja2:18
+#: src/octoprint/templates/sidebar/state.jinja2:23
msgid "Resume"
msgstr "Weiter"
-#: src/octoprint/templates/sidebar/state.jinja2:19
+#: src/octoprint/templates/sidebar/state.jinja2:24
msgid "Cancels the print job"
msgstr "Bricht den Druckjob ab"
@@ -2637,51 +2658,51 @@ msgstr "Lüfter an"
msgid "Fan off"
msgstr "Lüfter aus"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:14
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:17
msgid "Model info"
msgstr "Modelinformationen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:21
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:24
msgid "Renderer options"
msgstr "Rendereroptionen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:25
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:28
msgid "Sync with job progress"
msgstr "Job mit Fortschritt synchronisieren"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:30
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
msgid "Center viewport on model"
msgstr "Ausschnitt auf Modell zentrieren"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:36
msgid "Zoom in on model"
msgstr "Auf Model zoomen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:39
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
msgid "Show moves"
msgstr "Bewegungen zeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:45
msgid "Show retracts"
msgstr "Retracts zeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:48
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
msgid "Also show previous layer"
msgstr "Auch vorherige Schicht anzeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:54
msgid "Also show next layer"
msgstr "Auch nächste Schicht anzeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:56
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:59
msgid "Reload"
msgstr "Neu laden"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:62
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:65
msgid "Note that the time estimates in this tab are calculated by the GCODE viewer in your browser and might differ from the values calculated by the server that are displayed in the \"State\" and \"Files\" panels in the sidebar due to slightly different implementations."
msgstr "Beachte, dass die geschätzten Zeiten in diesem Tab durch den GCODE Viewer in Deinem Browser berechnet werden und sich von den durch den Server berechneten Werten unterscheiden können, die im \"Status\" und \"Dateien\" Bereich der Seitenleiste angezeigt werden. Die Ursache hierfür sind leicht unterschiedliche Implementierungen."
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:67
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:70
msgid ""
"\n" " You've selected for printing which has a size of\n" @@ -2703,7 +2724,7 @@ msgstr "" " Bist Du sicher, dass du die Datei trotzdem visualisieren willst?\n" "
" -#: src/octoprint/templates/tabs/gcodeviewer.jinja2:78 +#: src/octoprint/templates/tabs/gcodeviewer.jinja2:81 #, python-format msgid "Yes, please visualize %(name)s regardless of its size" msgstr "Ja, bitte visualisiere %(name)s unabhängig seiner Größe" @@ -2927,3 +2948,24 @@ msgstr "Zeitrafferaufnahme rendern" #~ msgid "Show Announcements..." #~ msgstr "Ankündigungen anzeigen..." + +#~ msgid "Version" +#~ msgstr "Version" + +#~ msgid "Sourcecode" +#~ msgstr "Quellcode" + +#~ msgid "Documentation" +#~ msgstr "Dokumentation" + +#~ msgid "Bugs and Requests" +#~ msgstr "Bugs und Requests" + +#~ msgid "About" +#~ msgstr "Über" + +#~ msgid "About OctoPrint" +#~ msgstr "Über OctoPrint" + +#~ msgid "OctoPrint Settings" +#~ msgstr "OctoPrint Einstellungen" diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 133a8bc5..7d14bf56 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -249,6 +249,16 @@ class MachineCom(object): except: pass + self._consecutive_timeouts = 0 + self._consecutive_timeout_maximums = dict() + for key, value in settings().get(["serial", "maxCommunicationTimeouts"], merged=True, asdict=True).items(): + try: + self._consecutive_timeout_maximums[key] = int(value) + except: + pass + + self._max_write_passes = settings().getInt(["serial", "maxWritePasses"]) + self._hello_command = settings().get(["serial", "helloCommand"]) self._trigger_ok_for_m29 = settings().getBoolean(["serial", "triggerOkForM29"]) @@ -340,6 +350,10 @@ class MachineCom(object): def __del__(self): self.close() + @property + def _active(self): + return self._monitoring_active and self._send_queue_active + ##~~ internal state management def _changeState(self, newState): @@ -418,11 +432,11 @@ class MachineCom(object): if state == self.STATE_PAUSED: return "Paused" if state == self.STATE_CLOSED: - return "Closed" + return "Offline" if state == self.STATE_ERROR: return "Error: %s" % (self.getErrorString()) if state == self.STATE_CLOSED_WITH_ERROR: - return "Error: %s" % (self.getErrorString()) + return "Offline: %s" % (self.getErrorString()) if state == self.STATE_TRANSFERING_FILE: return "Transfering file to SD" return "Unknown State (%d)" % (self._state) @@ -591,15 +605,17 @@ class MachineCom(object): if not processed: cmd = process_gcode_line(cmd) if not cmd: - return + return False if self.isPrinting() and not self.isSdFileSelected(): try: self._command_queue.put((cmd, cmd_type), item_type=cmd_type) + return True except TypeAlreadyInQueue as e: self._logger.debug("Type already in command queue: " + e.type) + return False elif self.isOperational() or force: - self._sendCommand(cmd, cmd_type=cmd_type) + return self._sendCommand(cmd, cmd_type=cmd_type) def sendGcodeScript(self, scriptName, replacements=None): context = dict() @@ -917,6 +933,8 @@ class MachineCom(object): disable_external_heatup_detection = not settings().getBoolean(["feature", "externalHeatupDetection"]) + self._consecutive_timeouts = 0 + #Open the serial port. if not self._openSerial(): return @@ -952,6 +970,7 @@ class MachineCom(object): if line is None: break if line.strip() is not "": + self._consecutive_timeouts = 0 if self._heating: self._timeout = get_new_timeout("heatup", self._timeout_intervals) else: @@ -1218,6 +1237,7 @@ class MachineCom(object): elif line.startswith("ok"): self._onConnected() elif time.time() > self._timeout: + self._log("There was a timeout while trying to connect to the printer") self.close(wait=False) except: @@ -1226,8 +1246,8 @@ class MachineCom(object): errorMsg = "See octoprint.log for details" self._log(errorMsg) self._errorValue = errorMsg - self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) + self.close(is_error=True) self._log("Connection closed, closing down monitor") def _handle_ok(self): @@ -1257,29 +1277,66 @@ class MachineCom(object): return def _handle_timeout(self): - if self._state not in (self.STATE_PRINTING,): - return - - if self._long_running_command: - self._logger.debug("Ran into a communication timeout, but a command known to be a long runner is currently active") + if self._state not in (self.STATE_PRINTING, + self.STATE_PAUSED, + self.STATE_OPERATIONAL): return general_message = "Configure long running commands or increase communication timeout if that happens regularly on specific commands or long moves." - if self._resendActive: - self._log("Communication timeout while printing and during an active resend, resending same line again to trigger response from printer. " + general_message) - self._resendSameCommand() - self._clear_to_send.set() + + # figure out which consecutive timeout maximum we have to use + if self._long_running_command: + consecutive_max = self._consecutive_timeout_maximums.get("long", 0) + elif self._state in (self.STATE_PRINTING,): + consecutive_max = self._consecutive_timeout_maximums.get("printing", 0) + else: + consecutive_max = self._consecutive_timeout_maximums.get("idle", 0) + + # now increment the timeout counter + self._consecutive_timeouts += 1 + self._logger.debug("Now at {} consecutive timeouts".format(self._consecutive_timeouts)) + + if 0 < consecutive_max < self._consecutive_timeouts: + # too many consecutive timeouts, we give up + message = "No response from printer after {} consecutive communication timeouts, considering it dead.".format(consecutive_max + 1) + self._logger.info(message) + self._log(message + " " + general_message) + self._errorValue = "Too many consecutive timeouts, printer still connected and alive?" + eventManager().fire(Events.ERROR, {"error": self._errorValue}) + self.close(is_error=True) + + elif self._resendActive: + # resend active, resend same command instead of triggering a new one + message = "Communication timeout during an active resend, resending same line again to trigger response from printer." + self._logger.info(message) + self._log(message + " " + general_message) + if self._resendSameCommand(): + self._clear_to_send.set() elif self._heating: - self._logger.debug("Timeout while in an active heatup, considering heatup to be over then") + # blocking heatup active, consider that finished + message = "Timeout while in an active heatup, considering heatup to be over." + self._logger.info(message) self._finish_heatup() - else: - self._log("Communication timeout while printing, trying to trigger response from printer. " + general_message) - self._sendCommand("M105", cmd_type="temperature") - self._clear_to_send.set() + elif self._long_running_command: + # long running command active, ignore timeout + self._logger.debug("Ran into a communication timeout, but a command known to be a long runner is currently active") - return + elif self._state in (self.STATE_PRINTING, self.STATE_PAUSED): + # printing, try to tickle the printer + message = "Communication timeout while printing, trying to trigger response from printer." + self._logger.info(message) + self._log(message + " " + general_message) + if self._sendCommand("M105", cmd_type="temperature"): + self._clear_to_send.set() + + elif self._clear_to_send.blocked(): + # timeout while idle and no oks left, let's try to tickle the printer + message = "Communication timeout while idle, trying to trigger response from printer." + self._logger.info(message) + self._log(message + " " + general_message) + self._clear_to_send.set() def _track_heatup(self): self._heating = True @@ -1294,11 +1351,25 @@ class MachineCom(object): self._serial.timeout = settings().getFloat(["serial", "timeout", "communication"]) def _continue_sending(self): - if self._state == self.STATE_PRINTING: - if not self._sendFromQueue() and not self.isSdPrinting(): - self._sendNext() - elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED: - self._sendFromQueue() + while self._active: + + if self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED or self.isSdPrinting(): + # just send stuff from the command queue and be done with it + return self._sendFromQueue() + + elif self._state == self.STATE_PRINTING: + # we are printing, we really want to send either something from the command + # queue or the next line from our file, so we only return here if we actually DO + # send something + if self._sendFromQueue(): + # we found something in the queue to send + return True + + elif self._sendNext(): + # we sent the next line from the file + return True + + self._logger.debug("No command sent on ok while printing, doing another iteration") def _process_registered_message(self, line, feedback_matcher, feedback_controls, feedback_errors): feedback_match = feedback_matcher.search(line) @@ -1609,10 +1680,20 @@ class MachineCom(object): def _sendNext(self): with self._sendNextLock: - line = self._getNext() - if line is not None: - self._sendCommand(line) + while self._active: + # we loop until we've actually enqueued a line for sending + line = self._getNext() + if line is None: + # end of file, return false + return False + + result = self._sendCommand(line) self._callback.on_comm_progress() + if result: + # line sent, return true + return True + + self._logger.debug("Command \"{}\" from file not enqueued, doing another iteration".format(line)) def _handleResendRequest(self, line): try: @@ -1700,7 +1781,7 @@ class MachineCom(object): self._handle_ok() def _resendSameCommand(self): - self._resendNextCommand(again=True) + return self._resendNextCommand(again=True) def _resendNextCommand(self, again=False): self._lastCommError = None @@ -1721,7 +1802,7 @@ class MachineCom(object): cmd = self._lastLines[-self._resendDelta] lineNumber = self._currentLine - self._resendDelta - self._enqueue_for_sending(cmd, linenumber=lineNumber) + result = self._enqueue_for_sending(cmd, linenumber=lineNumber) self._resendDelta -= 1 if self._resendDelta <= 0: @@ -1729,6 +1810,8 @@ class MachineCom(object): self._lastResendNumber = None self._currentResendCount = 0 + return result + def _sendCommand(self, cmd, cmd_type=None): # Make sure we are only handling one sending job at a time with self._sendingLock: @@ -1749,11 +1832,11 @@ class MachineCom(object): eventManager().fire(gcodeToEvent[gcode]) # actually enqueue the command for sending - self._enqueue_for_sending(cmd, command_type=cmd_type) - - self._process_command_phase("queued", cmd, cmd_type, gcode=gcode) - - return True + if self._enqueue_for_sending(cmd, command_type=cmd_type): + self._process_command_phase("queued", cmd, cmd_type, gcode=gcode) + return True + else: + return False ##~~ send loop handling @@ -1769,8 +1852,10 @@ class MachineCom(object): try: self._send_queue.put((command, linenumber, command_type), item_type=command_type) + return True except TypeAlreadyInQueue as e: self._logger.debug("Type already in send queue: " + e.type) + return False def _send_loop(self): """ @@ -1955,8 +2040,11 @@ class MachineCom(object): cmd += "\n" written = 0 + passes = 0 while written < len(cmd): to_send = cmd[written:] + old_written = written + try: written += self._serial.write(to_send) except serial.SerialTimeoutException: @@ -1978,6 +2066,18 @@ class MachineCom(object): self.close(is_error=True) break + if old_written == written: + # nothing written this pass + passes += 1 + if passes > self._max_write_passes: + # nothing written in max consecutive passes, we give up + message = "Could not write anything to the serial port in {} tries, something appears to be wrong with the printer communication".format(self._max_write_passes) + self._logger.error(message) + self._log(message) + self._errorValue = "Could not write to serial port" + self.close(is_error=True) + break + ##~~ command handlers def _gcode_T_sent(self, cmd, cmd_type=None): diff --git a/src/octoprint/util/jinja.py b/src/octoprint/util/jinja.py index f458195f..ba55d58c 100644 --- a/src/octoprint/util/jinja.py +++ b/src/octoprint/util/jinja.py @@ -196,3 +196,18 @@ class ExceptionHandlerExtension(Extension): return "Unknown error" trycatch = ExceptionHandlerExtension + + +class MarkdownFilter(object): + + def __init__(self, app, **markdown_options): + self._markdown_options = markdown_options + app.jinja_env.filters.setdefault("markdown", self) + + def __call__(self, stream): + from jinja2 import Markup + from markdown import Markdown + + # Markdown is not thread safe + markdown = Markdown(**self._markdown_options) + return Markup(markdown.convert(stream)) diff --git a/translations/de/LC_MESSAGES/messages.mo b/translations/de/LC_MESSAGES/messages.mo index bcdcf24a..f2444b45 100644 Binary files a/translations/de/LC_MESSAGES/messages.mo and b/translations/de/LC_MESSAGES/messages.mo differ diff --git a/translations/de/LC_MESSAGES/messages.po b/translations/de/LC_MESSAGES/messages.po index 42e8da64..93701c1b 100644 --- a/translations/de/LC_MESSAGES/messages.po +++ b/translations/de/LC_MESSAGES/messages.po @@ -5,18 +5,19 @@ # msgid "" msgstr "" -"Project-Id-Version: OctoPrint\n" +"Project-Id-Version: OctoPrint\n" "Report-Msgid-Bugs-To: i18n@octoprint.org\n" -"POT-Creation-Date: 2016-06-16 12:18+0200\n" -"PO-Revision-Date: 2016-06-08 11:04+0100\n" +"POT-Creation-Date: 2016-07-28 11:50+0200\n" +"PO-Revision-Date: 2016-07-28 12:03+0100\n" "Last-Translator: Gina Häußgestart on connect"
msgstr "Bei der Verbindung auf start warten"
#: src/octoprint/templates/dialogs/settings/features.jinja2:40
+msgid "Select SD files by relative path"
+msgstr "SD Dateien per relativem Pfad addressieren"
+
+#: src/octoprint/templates/dialogs/settings/features.jinja2:40
+msgid "RepRap Firmware"
+msgstr "RepRap Firmware"
+
+#: src/octoprint/templates/dialogs/settings/features.jinja2:47
msgid "Always assume SD card is present"
msgstr "Immer davon ausgehen, dass eine SD-Karte vorhanden ist"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:40
#: src/octoprint/templates/dialogs/settings/features.jinja2:47
#: src/octoprint/templates/dialogs/settings/features.jinja2:54
#: src/octoprint/templates/dialogs/settings/features.jinja2:61
#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Repetier"
msgstr "Repetier"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:47
+#: src/octoprint/templates/dialogs/settings/features.jinja2:54
msgid "Send a checksum with every command"
msgstr "Eine Prüfsumme mit jedem Befehl senden"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:54
+#: src/octoprint/templates/dialogs/settings/features.jinja2:61
msgid "Ignore consecutive resend requests for the same line"
msgstr "Aufeinanderfolgende Resend Requests für die selbe Zeilennummer ignorieren"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:61
+#: src/octoprint/templates/dialogs/settings/features.jinja2:68
#, python-format
msgid "Support TargetExtr%%n/TargetBed target temperature format"
msgstr "TargetExtr%%n/TargetBed Zieltemperaturformat unterstützen"
-#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Disable detection of external heatups"
msgstr "Detektierung externer Aufheizvorgänge deaktivieren"
@@ -1984,7 +1978,7 @@ msgstr "Falls der freie Plattenplatz unter diese Schwellwerte fallen sollte wird
#: src/octoprint/templates/dialogs/settings/folders.jinja2:47
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:69
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:90
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:66
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:69
#: src/octoprint/templates/tabs/timelapse.jinja2:13
msgid "Warning"
msgstr "Warnung"
@@ -2260,6 +2254,30 @@ msgstr "Viele Marlin < v1.1.0"
msgid "Simulate an additional `ok` for resend requests"
msgstr "Zusätzliches `ok` für Resendrequests simulieren"
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:129
+msgid "Maximum consecutive communication timeouts while idle. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts im Idlezustand. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:130
+msgid "Max. consecutive timeouts while idle"
+msgstr "Max. aufeinanderfolgende Timeouts wenn idle"
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:135
+msgid "Maximum consecutive communication timeouts while printing. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts beim Drucken. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:136
+msgid "Max. consecutive timeouts while printing"
+msgstr "Max. aufeinanderfolgende Timeouts beim Drucken"
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:141
+msgid "Maximum consecutive communication timeouts while a long running command is active. More than this and the printer will be considered to be gone. Set to 0 to disable."
+msgstr "Maximale Anzahl aufeinanderfolgender Communication Timeouts wenn ein lang laufender Befehl aktiv ist. Mehr als das und es wird angenommen, dass der Drucker offline ist. Auf 0 setzen um das zu verhindern."
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:142
+msgid "Max. consecutive timeouts during long running commands"
+msgstr "Max. aufeinanderfolgende Timeouts während lang laufender Befehle"
+
#: src/octoprint/templates/dialogs/settings/server.jinja2:2
msgid "Commands"
msgstr "Befehle"
@@ -2384,6 +2402,10 @@ msgstr "Änderungen der Oberflächensprache werden erst nach einem Neuladen der
msgid "Remember me"
msgstr "Login merken"
+#: src/octoprint/templates/navbar/login.jinja2:16
+msgid "User Settings"
+msgstr "Nutzereinstellungen"
+
#: src/octoprint/templates/navbar/login.jinja2:17
msgid "Logout"
msgstr "Logout"
@@ -2464,7 +2486,7 @@ msgstr "Frei"
msgid "Total"
msgstr "Gesamt"
-#: src/octoprint/templates/sidebar/files.jinja2:64
+#: src/octoprint/templates/sidebar/files.jinja2:67
msgid "Hint: You can also drag and drop files on this page to upload them."
msgstr "Hinweis: Du kannst auch Dateien auf diese Seite ziehen um sie hochzuladen."
@@ -2528,39 +2550,39 @@ msgstr "SD-Karte auswerfen"
msgid "Machine State"
msgstr "Druckerstatus"
-#: src/octoprint/templates/sidebar/state.jinja2:2
+#: src/octoprint/templates/sidebar/state.jinja2:3
msgid "File"
msgstr "Datei"
-#: src/octoprint/templates/sidebar/state.jinja2:7
+#: src/octoprint/templates/sidebar/state.jinja2:8
msgid "Approx. Total Print Time"
msgstr "Ungefähre Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:8
+#: src/octoprint/templates/sidebar/state.jinja2:10
msgid "Print Time"
msgstr "Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:9
+#: src/octoprint/templates/sidebar/state.jinja2:11
msgid "Print Time Left"
msgstr "Verbleibende Druckdauer"
-#: src/octoprint/templates/sidebar/state.jinja2:10
+#: src/octoprint/templates/sidebar/state.jinja2:12
msgid "Printed"
msgstr "Gedruckt"
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Restart"
msgstr "Restart"
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Print"
msgstr "Drucken"
-#: src/octoprint/templates/sidebar/state.jinja2:18
+#: src/octoprint/templates/sidebar/state.jinja2:23
msgid "Resume"
msgstr "Weiter"
-#: src/octoprint/templates/sidebar/state.jinja2:19
+#: src/octoprint/templates/sidebar/state.jinja2:24
msgid "Cancels the print job"
msgstr "Bricht den Druckjob ab"
@@ -2636,51 +2658,51 @@ msgstr "Lüfter an"
msgid "Fan off"
msgstr "Lüfter aus"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:14
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:17
msgid "Model info"
msgstr "Modelinformationen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:21
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:24
msgid "Renderer options"
msgstr "Rendereroptionen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:25
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:28
msgid "Sync with job progress"
msgstr "Job mit Fortschritt synchronisieren"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:30
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
msgid "Center viewport on model"
msgstr "Ausschnitt auf Modell zentrieren"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:36
msgid "Zoom in on model"
msgstr "Auf Model zoomen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:39
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
msgid "Show moves"
msgstr "Bewegungen zeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:45
msgid "Show retracts"
msgstr "Retracts zeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:48
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
msgid "Also show previous layer"
msgstr "Auch vorherige Schicht anzeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:54
msgid "Also show next layer"
msgstr "Auch nächste Schicht anzeigen"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:56
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:59
msgid "Reload"
msgstr "Neu laden"
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:62
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:65
msgid "Note that the time estimates in this tab are calculated by the GCODE viewer in your browser and might differ from the values calculated by the server that are displayed in the \"State\" and \"Files\" panels in the sidebar due to slightly different implementations."
msgstr "Beachte, dass die geschätzten Zeiten in diesem Tab durch den GCODE Viewer in Deinem Browser berechnet werden und sich von den durch den Server berechneten Werten unterscheiden können, die im \"Status\" und \"Dateien\" Bereich der Seitenleiste angezeigt werden. Die Ursache hierfür sind leicht unterschiedliche Implementierungen."
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:67
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:70
msgid ""
"\n" " You've selected for printing which has a size of\n" @@ -2702,7 +2724,7 @@ msgstr "" " Bist Du sicher, dass du die Datei trotzdem visualisieren willst?\n" "
" -#: src/octoprint/templates/tabs/gcodeviewer.jinja2:78 +#: src/octoprint/templates/tabs/gcodeviewer.jinja2:81 #, python-format msgid "Yes, please visualize %(name)s regardless of its size" msgstr "Ja, bitte visualisiere %(name)s unabhängig seiner Größe" @@ -2927,3 +2949,23 @@ msgstr "Zeitrafferaufnahme rendern" #~ msgid "Show Announcements..." #~ msgstr "Ankündigungen anzeigen..." +#~ msgid "Version" +#~ msgstr "Version" + +#~ msgid "Sourcecode" +#~ msgstr "Quellcode" + +#~ msgid "Documentation" +#~ msgstr "Dokumentation" + +#~ msgid "Bugs and Requests" +#~ msgstr "Bugs und Requests" + +#~ msgid "About" +#~ msgstr "Über" + +#~ msgid "About OctoPrint" +#~ msgstr "Über OctoPrint" + +#~ msgid "OctoPrint Settings" +#~ msgstr "OctoPrint Einstellungen" diff --git a/translations/messages.pot b/translations/messages.pot index 36190803..99b9051c 100644 --- a/translations/messages.pot +++ b/translations/messages.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: OctoPrint 1.2.13.dev7+g6c20e58\n" +"Project-Id-Version: OctoPrint 1.2.14.dev70+gf671006\n" "Report-Msgid-Bugs-To: i18n@octoprint.org\n" -"POT-Creation-Date: 2016-06-16 12:18+0200\n" +"POT-Creation-Date: 2016-07-28 11:50+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAMEstart on connect"
msgstr ""
#: src/octoprint/templates/dialogs/settings/features.jinja2:40
-msgid "Always assume SD card is present"
+msgid "Select SD files by relative path"
msgstr ""
#: src/octoprint/templates/dialogs/settings/features.jinja2:40
+msgid "RepRap Firmware"
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/features.jinja2:47
+msgid "Always assume SD card is present"
+msgstr ""
+
#: src/octoprint/templates/dialogs/settings/features.jinja2:47
#: src/octoprint/templates/dialogs/settings/features.jinja2:54
#: src/octoprint/templates/dialogs/settings/features.jinja2:61
#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Repetier"
msgstr ""
-#: src/octoprint/templates/dialogs/settings/features.jinja2:47
+#: src/octoprint/templates/dialogs/settings/features.jinja2:54
msgid "Send a checksum with every command"
msgstr ""
-#: src/octoprint/templates/dialogs/settings/features.jinja2:54
+#: src/octoprint/templates/dialogs/settings/features.jinja2:61
msgid "Ignore consecutive resend requests for the same line"
msgstr ""
-#: src/octoprint/templates/dialogs/settings/features.jinja2:61
+#: src/octoprint/templates/dialogs/settings/features.jinja2:68
#, python-format
msgid ""
"Support TargetExtr%%n/TargetBed target "
"temperature format"
msgstr ""
-#: src/octoprint/templates/dialogs/settings/features.jinja2:68
+#: src/octoprint/templates/dialogs/settings/features.jinja2:75
msgid "Disable detection of external heatups"
msgstr ""
@@ -2099,7 +2095,7 @@ msgstr ""
#: src/octoprint/templates/dialogs/settings/folders.jinja2:47
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:69
#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:90
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:66
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:69
#: src/octoprint/templates/tabs/timelapse.jinja2:13
msgid "Warning"
msgstr ""
@@ -2417,6 +2413,37 @@ msgstr ""
msgid "Simulate an additional `ok` for resend requests"
msgstr ""
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:129
+msgid ""
+"Maximum consecutive communication timeouts while idle. More than this and"
+" the printer will be considered to be gone. Set to 0 to disable."
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:130
+msgid "Max. consecutive timeouts while idle"
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:135
+msgid ""
+"Maximum consecutive communication timeouts while printing. More than this"
+" and the printer will be considered to be gone. Set to 0 to disable."
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:136
+msgid "Max. consecutive timeouts while printing"
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:141
+msgid ""
+"Maximum consecutive communication timeouts while a long running command "
+"is active. More than this and the printer will be considered to be gone. "
+"Set to 0 to disable."
+msgstr ""
+
+#: src/octoprint/templates/dialogs/settings/serialconnection.jinja2:142
+msgid "Max. consecutive timeouts during long running commands"
+msgstr ""
+
#: src/octoprint/templates/dialogs/settings/server.jinja2:2
msgid "Commands"
msgstr ""
@@ -2545,6 +2572,10 @@ msgstr ""
msgid "Remember me"
msgstr ""
+#: src/octoprint/templates/navbar/login.jinja2:16
+msgid "User Settings"
+msgstr ""
+
#: src/octoprint/templates/navbar/login.jinja2:17
msgid "Logout"
msgstr ""
@@ -2629,7 +2660,7 @@ msgstr ""
msgid "Total"
msgstr ""
-#: src/octoprint/templates/sidebar/files.jinja2:64
+#: src/octoprint/templates/sidebar/files.jinja2:67
msgid "Hint: You can also drag and drop files on this page to upload them."
msgstr ""
@@ -2693,39 +2724,39 @@ msgstr ""
msgid "Machine State"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:2
+#: src/octoprint/templates/sidebar/state.jinja2:3
msgid "File"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:7
+#: src/octoprint/templates/sidebar/state.jinja2:8
msgid "Approx. Total Print Time"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:8
+#: src/octoprint/templates/sidebar/state.jinja2:10
msgid "Print Time"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:9
+#: src/octoprint/templates/sidebar/state.jinja2:11
msgid "Print Time Left"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:10
+#: src/octoprint/templates/sidebar/state.jinja2:12
msgid "Printed"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Restart"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:17
+#: src/octoprint/templates/sidebar/state.jinja2:22
msgid "Print"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:18
+#: src/octoprint/templates/sidebar/state.jinja2:23
msgid "Resume"
msgstr ""
-#: src/octoprint/templates/sidebar/state.jinja2:19
+#: src/octoprint/templates/sidebar/state.jinja2:24
msgid "Cancels the print job"
msgstr ""
@@ -2803,47 +2834,47 @@ msgstr ""
msgid "Fan off"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:14
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:17
msgid "Model info"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:21
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:24
msgid "Renderer options"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:25
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:28
msgid "Sync with job progress"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:30
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
msgid "Center viewport on model"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:33
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:36
msgid "Zoom in on model"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:39
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
msgid "Show moves"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:42
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:45
msgid "Show retracts"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:48
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
msgid "Also show previous layer"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:51
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:54
msgid "Also show next layer"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:56
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:59
msgid "Reload"
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:62
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:65
msgid ""
"Note that the time estimates in this tab are calculated by the GCODE "
"viewer in your browser and might differ from the values calculated by the"
@@ -2851,7 +2882,7 @@ msgid ""
"sidebar due to slightly different implementations."
msgstr ""
-#: src/octoprint/templates/tabs/gcodeviewer.jinja2:67
+#: src/octoprint/templates/tabs/gcodeviewer.jinja2:70
msgid ""
"\n" " You've selected " msgstr "" -#: src/octoprint/templates/tabs/gcodeviewer.jinja2:78 +#: src/octoprint/templates/tabs/gcodeviewer.jinja2:81 #, python-format msgid "Yes, please visualize %(name)s regardless of its size" msgstr ""