Initial commit of blenders buildbot configuration
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 14 Jun 2015 18:23:25 +0000 (20:23 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 14 Jun 2015 18:28:35 +0000 (20:28 +0200)
25 files changed:
.gitignore [new file with mode: 0644]
buildbot.tac [new file with mode: 0644]
maintenance/cleanup.sh [new file with mode: 0755]
master.cfg [new file with mode: 0644]
master_private_template.py [new file with mode: 0644]
master_unpack.py [new file with mode: 0644]
public_html/bg_gradient.jpg [new file with mode: 0644]
public_html/css/font-borg.css [new file with mode: 0644]
public_html/css/main.css [new file with mode: 0644]
public_html/default.css [new file with mode: 0644]
public_html/default.css.new [new file with mode: 0644]
public_html/favicon.ico [new file with mode: 0644]
public_html/lin.png [new file with mode: 0644]
public_html/osx.png [new file with mode: 0644]
public_html/robots.txt [new file with mode: 0644]
public_html/win.png [new file with mode: 0644]
state.sqlite [new file with mode: 0644]
templates/build.html [new file with mode: 0644]
templates/build_line.html [new file with mode: 0644]
templates/buildslave.html [new file with mode: 0644]
templates/buildslaves.html [new file with mode: 0644]
templates/directory.html [new file with mode: 0644]
templates/forms.html [new file with mode: 0644]
templates/layout.html [new file with mode: 0644]
templates/root.html [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..5e559b5
--- /dev/null
@@ -0,0 +1,30 @@
+# generic files to ignore
+.*
+
+# python temp paths
+__pycache__/
+*.py[cod]
+
+# editors
+*~
+*.swp
+*.swo
+*#
+
+# ms-windows
+Thumbs.db
+ehthumbs.db
+Desktop.ini
+
+# OSX
+.DS_storage
+
+# local patches
+/*.patch
+/*.diff
+
+# Buildbot specific files
+http.log
+master_private.py
+twistd.log
+linux_glibc211_x86_64_scons/
diff --git a/buildbot.tac b/buildbot.tac
new file mode 100644 (file)
index 0000000..f86049b
--- /dev/null
@@ -0,0 +1,37 @@
+
+import os
+
+from twisted.application import service
+from buildbot.master import BuildMaster
+
+basedir = r'.'
+rotateLength = 10000000
+maxRotatedFiles = 10
+umask = 002
+
+# if this is a relocatable tac file, get the directory containing the TAC
+if basedir == '.':
+    import os.path
+    basedir = os.path.abspath(os.path.dirname(__file__))
+
+# note: this line is matched against to check that this is a buildmaster
+# directory; do not edit it.
+application = service.Application('buildmaster')
+
+try:
+  from twisted.python.logfile import LogFile
+  from twisted.python.log import ILogObserver, FileLogObserver
+  logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
+                                 maxRotatedFiles=maxRotatedFiles)
+  application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
+except ImportError:
+  # probably not yet twisted 8.2.0 and beyond, can't set log yet
+  pass
+
+configfile = r'master.cfg'
+
+m = BuildMaster(basedir, configfile)
+m.setServiceParent(application)
+m.log_rotation.rotateLength = rotateLength
+m.log_rotation.maxRotatedFiles = maxRotatedFiles
+
diff --git a/maintenance/cleanup.sh b/maintenance/cleanup.sh
new file mode 100755 (executable)
index 0000000..a6f0b61
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+ROOT="/data/buildbot-master/"
+DIRS="linux_glibc211_i386_scons
+linux_glibc211_x86_64_scons
+mac_i386_10_6_scons
+mac_x86_64_10_6_scons
+mingw_win64_scons
+uploaded
+win32_cmake_vc2013
+win32_scons_vc2013
+win64_cmake_vc2013
+win64_scons_vc2013"
+
+for DIR in $DIRS; do
+  find "${ROOT}/$DIR" -type f -mtime +14 -exec rm -f {} \;
+done
+
diff --git a/master.cfg b/master.cfg
new file mode 100644 (file)
index 0000000..026d5e4
--- /dev/null
@@ -0,0 +1,372 @@
+# -*- python -*-
+# ex: set syntax=python:
+
+# <pep8 compliant>
+
+# List of the branches being built automatically overnight
+NIGHT_SCHEDULE_BRANCHES = [None, "gooseberry"]
+
+# List of the branches available for force build
+FORCE_SCHEDULE_BRANCHES = ["master", "gooseberry", "experimental-build"]
+
+"""
+Stock Twisted directory lister doesn't provide any information about last file
+modification time, we hack the class a bit in order to have such functionaliity
+:)
+"""
+
+from buildbot.status.web.base import DirectoryLister
+
+
+def get_files_and_directories(self, directory):
+    from twisted.web.static import (getTypeAndEncoding,
+                                    formatFileSize)
+    import urllib
+    import cgi
+    import time
+    import os
+    files = []
+    dirs = []
+    for path in directory:
+        url = urllib.quote(path, "/")
+        escapedPath = cgi.escape(path)
+        lastmodified = time.ctime(os.path.getmtime(
+            os.path.join(self.path, path)))
+        if os.path.isdir(os.path.join(self.path, path)):
+            url = url + '/'
+            dirs.append({'text': escapedPath + "/", 'href': url,
+                         'size': '', 'type': '[Directory]',
+                         'encoding': '',
+                         'lastmodified': lastmodified})
+        else:
+            mimetype, encoding = getTypeAndEncoding(path, self.contentTypes,
+                                                    self.contentEncodings,
+                                                    self.defaultType)
+            try:
+                size = os.stat(os.path.join(self.path, path)).st_size
+            except OSError:
+                continue
+            files.append({
+                'text': escapedPath, "href": url,
+                'type': '[%s]' % mimetype,
+                'encoding': (encoding and '[%s]' % encoding or ''),
+                'size': formatFileSize(size),
+                'lastmodified': lastmodified})
+    return dirs, files
+DirectoryLister._getFilesAndDirectories = get_files_and_directories
+
+# Dictionary that the buildmaster pays attention to.
+c = BuildmasterConfig = {}
+
+# BUILD SLAVES
+#
+# We load the slaves and their passwords from a separator file, so we can have
+# this one in SVN.
+
+from buildbot.buildslave import BuildSlave
+import master_private
+
+c['slaves'] = []
+
+for slave in master_private.slaves:
+    c['slaves'].append(BuildSlave(slave['name'], slave['password']))
+
+# TCP port through which slaves connect
+
+c['slavePortnum'] = 9989
+
+# CHANGE SOURCES
+
+from buildbot.changes.svnpoller import SVNPoller
+from buildbot.changes.gitpoller import GitPoller
+
+c['change_source'] = GitPoller(
+       'git://git.blender.org/blender.git',
+       pollinterval=1200)
+
+
+# CODEBASES
+#
+# Allow to controll separately things like branches for each repo and submodules.
+
+all_repositories = {
+    r'git://git.blender.org/blender.git': 'blender',
+    r'git://git.blender.org/blender-translations.git': 'blender-translations',
+    r'git://git.blender.org/blender-addons.git': 'blender-addons',
+    r'git://git.blender.org/blender-addons-contrib.git': 'blender-addons-contrib',
+    r'git://git.blender.org/scons.git': 'scons',
+    r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn',
+}
+
+
+def codebaseGenerator(chdict):
+    return all_repositories[chdict['repository']]
+
+c['codebaseGenerator'] = codebaseGenerator
+
+
+# SCHEDULERS
+#
+# Decide how to react to incoming changes.
+
+# from buildbot.scheduler import Scheduler
+from buildbot.schedulers import timed, forcesched
+
+c['schedulers'] = []
+
+
+def schedule_force_build(name):
+    c['schedulers'].append(forcesched.ForceScheduler(name='force ' + name,
+        builderNames=[name],
+        codebases=[forcesched.CodebaseParameter(
+                codebase="blender",
+                branch=forcesched.ChoiceStringParameter(
+                    name="branch", choices=FORCE_SCHEDULE_BRANCHES, default="master"),
+                # Do not hide revision, can be handy!
+                repository=forcesched.FixedParameter(name="repository", default="", hide=True),
+                project=forcesched.FixedParameter(name="project", default="", hide=True)),
+            # For now, hide other codebases.
+            forcesched.CodebaseParameter(hide=True, codebase="blender-translations"),
+            forcesched.CodebaseParameter(hide=True, codebase="blender-addons"),
+            forcesched.CodebaseParameter(hide=True, codebase="blender-addons-contrib"),
+            forcesched.CodebaseParameter(hide=True, codebase="scons"),
+            forcesched.CodebaseParameter(hide=True, codebase="lib svn")],
+        properties=[]))
+
+
+def schedule_build(name, hour, minute=0):
+    for current_branch in NIGHT_SCHEDULE_BRANCHES:
+        scheduler_name = "nightly " + name
+        if current_branch:
+            scheduler_name += ' ' + current_branch
+        c['schedulers'].append(timed.Nightly(name=scheduler_name,
+            codebases={
+                "blender": {"repository": ""},
+                "blender-translations": {"repository": "", "branch": "master"},
+                "blender-addons": {"repository": "", "branch": "master"},
+                "blender-addons-contrib": {"repository": "", "branch": "master"},
+                "scons": {"repository": "", "branch": "master"},
+                "lib svn": {"repository": "", "branch": "trunk"}},
+            branch=current_branch,
+            builderNames=[name],
+            hour=hour,
+            minute=minute))
+
+
+# BUILDERS
+#
+# The 'builders' list defines the Builders, which tell Buildbot how to
+# perform a build: what steps, and which slaves can execute them.
+# Note that any particular build will only take place on one slave.
+
+from buildbot.process.factory import BuildFactory
+from buildbot.process.properties import Interpolate
+from buildbot.steps.source import SVN
+from buildbot.steps.source import Git
+from buildbot.steps.shell import ShellCommand
+from buildbot.steps.shell import Compile
+from buildbot.steps.shell import Test
+from buildbot.steps.transfer import FileUpload
+from buildbot.steps.master import MasterShellCommand
+from buildbot.config import BuilderConfig
+
+# add builder utility
+
+c['builders'] = []
+buildernames = []
+
+
+def add_builder(c, name, libdir, factory, branch='',
+                rsync=False, hour=3, minute=0):
+    slavenames = []
+
+    for slave in master_private.slaves:
+        if name in slave['builders']:
+            slavenames.append(slave['name'])
+
+    if len(slavenames) > 0:
+        f = factory(name, libdir, branch, rsync)
+        c['builders'].append(BuilderConfig(name=name,
+                                           slavenames=slavenames,
+                                           factory=f,
+                                           category='blender'))
+        buildernames.append(name)
+
+        schedule_build(name, hour, minute)
+        schedule_force_build(name)
+
+# common steps
+
+
+def git_submodule_step(submodule):
+    return Git(name=submodule + '.git',
+               repourl='git://git.blender.org/' + submodule + '.git',
+               mode='update',
+               codebase=submodule,
+               workdir=submodule + '.git')
+
+
+def git_step(branch=''):
+    if branch:
+        return Git(name='blender.git',
+                   repourl='git://git.blender.org/blender.git',
+                   mode='update',
+                   branch=branch,
+                   codebase='blender',
+                   workdir='blender.git',
+                   submodules=True)
+    else:
+        return Git(name='blender.git',
+                   repourl='git://git.blender.org/blender.git',
+                   mode='update',
+                   codebase='blender',
+                   workdir='blender.git',
+                   submodules=True)
+
+
+def git_submodules_update():
+    command = ['git', 'submodule', 'foreach', '--recursive',
+               'git', 'pull', 'origin', 'master']
+    return ShellCommand(name='Submodules Update',
+                        command=command,
+                        description='updating',
+                        descriptionDone='up to date',
+                        workdir='blender.git')
+
+
+def lib_svn_step(dir):
+    return SVN(name='lib svn',
+               baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir,
+               codebase='lib svn',
+               mode='update',
+               defaultBranch='trunk',
+               workdir='lib/' + dir)
+
+
+def rsync_step(id, branch, rsync_script):
+    return ShellCommand(name='rsync',
+                        command=['python', rsync_script, id, branch],
+                        description='uploading',
+                        descriptionDone='uploaded',
+                        workdir='install')
+
+# generic builder
+
+
+def generic_builder(id, libdir='', branch='', rsync=False):
+    filename = 'uploaded/buildbot_upload_' + id + '.zip'
+    compile_script = '../blender.git/build_files/buildbot/slave_compile.py'
+    test_script = '../blender.git/build_files/buildbot/slave_test.py'
+    pack_script = '../blender.git/build_files/buildbot/slave_pack.py'
+    rsync_script = '../blender.git/build_files/buildbot/slave_rsync.py'
+    unpack_script = 'master_unpack.py'
+
+    f = BuildFactory()
+    if libdir != '':
+        f.addStep(lib_svn_step(libdir))
+
+    for submodule in ('blender-translations',
+                      'blender-addons',
+                      'blender-addons-contrib',
+                      'scons'):
+        f.addStep(git_submodule_step(submodule))
+
+    f.addStep(git_step(branch))
+    f.addStep(git_submodules_update())
+
+    f.addStep(Compile(command=['python', compile_script, id], timeout=3600))
+    f.addStep(Test(command=['python', test_script, id]))
+    f.addStep(ShellCommand(name='package',
+                           command=['python', pack_script, id, branch or Interpolate('%(src:blender:branch)s')],
+                           description='packaging',
+                           descriptionDone='packaged'))
+    if rsync:
+        f.addStep(rsync_step(id, branch, rsync_script))
+    elif id.find('cmake') != -1:
+        f.addStep(FileUpload(name='upload',
+                             slavesrc='buildbot_upload.zip',
+                             masterdest=filename,
+                             maxsize=150 * 1024 * 1024))
+    else:
+        f.addStep(FileUpload(name='upload',
+                             slavesrc='buildbot_upload.zip',
+                             masterdest=filename,
+                             maxsize=150 * 1024 * 1024,
+                             workdir='install'))
+    f.addStep(MasterShellCommand(name='unpack',
+                                 command=['python', unpack_script, filename],
+                                 description='unpacking',
+                                 descriptionDone='unpacked'))
+    return f
+
+# builders
+
+add_builder(c, 'mac_x86_64_10_6_scons', 'darwin-9.x.universal', generic_builder, hour=5)
+add_builder(c, 'mac_i386_10_6_scons', 'darwin-9.x.universal', generic_builder, hour=11)
+add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder, hour=1)
+add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder, hour=2)
+add_builder(c, 'win32_scons_vc2013', 'windows_vc12', generic_builder, hour=1)
+add_builder(c, 'win64_scons_vc2013', 'win64_vc12', generic_builder, hour=2)
+add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
+add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4)
+#add_builder(c, 'mingw_win32_scons', 'mingw32', generic_builder, hour=4)
+add_builder(c, 'mingw_win64_scons', 'mingw64', generic_builder, hour=3)
+#add_builder(c, 'freebsd_i386_cmake', '', generic_builder, hour=1)
+#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder, hour=2)
+
+# Multiview branch
+add_builder(c, 'multiview_win64_scons', 'win64', generic_builder, 'multiview', hour=4)
+add_builder(c, 'multiview_win32_scons', 'windows', generic_builder, 'multiview', hour=5)
+
+# STATUS TARGETS
+#
+# 'status' is a list of Status Targets. The results of each build will be
+# pushed to these targets. buildbot/status/*.py has a variety to choose from,
+# including web pages, email senders, and IRC bots.
+
+c['status'] = []
+
+from buildbot.status import html
+from buildbot.status.web import authz
+from buildbot.status.web import auth
+
+users = []
+for slave in master_private.slaves:
+    users += [(slave['name'], slave['password'])]
+
+authz_cfg = authz.Authz(
+    auth=auth.BasicAuth(users),
+    # change any of these to True to enable; see the manual for more
+    # options
+    gracefulShutdown=False,
+    forceBuild=True,  # use this to test your slave once it is set up
+    forceAllBuilds=False,
+    pingBuilder=False,
+    stopBuild=True,
+    stopAllBuilds=False,
+    cancelPendingBuild=True,
+)
+
+c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
+#c['status'].append(html.WebStatus(http_port=8010))
+
+# PROJECT IDENTITY
+
+c['projectName'] = "Blender"
+c['projectURL'] = "http://www.blender.org"
+
+# the 'buildbotURL' string should point to the location where the buildbot's
+# internal web server (usually the html.WebStatus page) is visible. This
+# typically uses the port number set in the Waterfall 'status' entry, but
+# with an externally-visible host name which the buildbot cannot figure out
+# without some help.
+
+c['buildbotURL'] = "http://builder.blender.org/"
+
+# DB URL
+#
+# This specifies what database buildbot uses to store change and scheduler
+# state.  You can leave this at its default for all but the largest
+# installations.
+
+c['db_url'] = "sqlite:///state.sqlite"
diff --git a/master_private_template.py b/master_private_template.py
new file mode 100644 (file)
index 0000000..8633fde
--- /dev/null
@@ -0,0 +1,5 @@
+slaves = [
+    {'name': 'linux_glibc211_x86_64_chroot',
+     'password': 'barbarianna',
+     'builders': ['linux_glibc211_x86_64_scons']}
+]
diff --git a/master_unpack.py b/master_unpack.py
new file mode 100644 (file)
index 0000000..ec44705
--- /dev/null
@@ -0,0 +1,148 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# Runs on Buildbot master, to unpack incoming unload.zip into latest
+# builds directory and remove older builds.
+
+# <pep8 compliant>
+
+import os
+import shutil
+import sys
+import zipfile
+
+
+# extension stripping
+def strip_extension(filename):
+    extensions = '.zip', '.tar', '.bz2', '.gz', '.tgz', '.tbz', '.exe'
+
+    for ext in extensions:
+        if filename.endswith(ext):
+            filename = filename[:-len(ext)]
+
+    return filename
+
+
+# extract platform from package name
+def get_platform(filename):
+    # name is blender-version-platform.extension. we want to get the
+    # platform out, but there may be some variations, so we fiddle a
+    # bit to handle current and hopefully future names
+    filename = strip_extension(filename)
+    filename = strip_extension(filename)
+
+    tokens = filename.split("-")
+    platforms = ('osx', 'mac', 'bsd',
+                 'win', 'linux', 'source',
+                 'irix', 'solaris', 'mingw')
+    platform_tokens = []
+    found = False
+
+    for i, token in enumerate(tokens):
+        if not found:
+            for platform in platforms:
+                if platform in token.lower():
+                    found = True
+                    break
+
+        if found:
+            platform_tokens += [token]
+
+    return '-'.join(platform_tokens)
+
+
+def get_branch(filename):
+    tokens = filename.split("-")
+    branch = ""
+
+    for token in tokens:
+        if token == "blender":
+            return branch
+
+        if branch == "":
+            branch = token
+        else:
+            branch = branch + "-" + token
+
+    return ""
+
+# get filename
+if len(sys.argv) < 2:
+    sys.stderr.write("Not enough arguments, expecting file to unpack\n")
+    sys.exit(1)
+
+filename = sys.argv[1]
+
+# open zip file
+if not os.path.exists(filename):
+    sys.stderr.write("File %r not found.\n" % filename)
+    sys.exit(1)
+
+try:
+    z = zipfile.ZipFile(filename, "r")
+except Exception as ex:
+    sys.stderr.write('Failed to open zip file: %s\n' % str(ex))
+    sys.exit(1)
+
+if len(z.namelist()) != 1:
+    sys.stderr.write("Expected one file in %r." % filename)
+    sys.exit(1)
+
+package = z.namelist()[0]
+packagename = os.path.basename(package)
+
+# detect platform and branch
+platform = get_platform(packagename)
+branch = get_branch(packagename)
+
+if platform == '':
+    sys.stderr.write('Failed to detect platform ' +
+        'from package: %r\n' % packagename)
+    sys.exit(1)
+
+# extract
+if not branch or branch == 'master':
+    directory = 'public_html/download'
+elif branch == 'experimental-build':
+    directory = 'public_html/download/experimental'
+else:
+    directory = 'public_html/download'
+
+try:
+    filename = os.path.join(directory, packagename)
+    zf = z.open(package)
+    f = file(filename, "wb")
+
+    shutil.copyfileobj(zf, f)
+    os.chmod(filename, 0644)
+
+    zf.close()
+    z.close()
+except Exception as ex:
+    sys.stderr.write('Failed to unzip package: %s\n' % str(ex))
+    sys.exit(1)
+
+# remove other files from the same platform and branch
+try:
+    for f in os.listdir(directory):
+        if get_platform(f) == platform and get_branch(f) == branch:
+            if f != packagename:
+                os.remove(os.path.join(directory, f))
+except Exception as ex:
+    sys.stderr.write('Failed to remove old packages: %s\n' % str(ex))
+    sys.exit(1)
diff --git a/public_html/bg_gradient.jpg b/public_html/bg_gradient.jpg
new file mode 100644 (file)
index 0000000..677b254
Binary files /dev/null and b/public_html/bg_gradient.jpg differ
diff --git a/public_html/css/font-borg.css b/public_html/css/font-borg.css
new file mode 100644 (file)
index 0000000..79c4fb1
--- /dev/null
@@ -0,0 +1,32 @@
+@font-face{
+       font-family:'FontBorg';
+       src:url('../fonts/font-borg-webfont.eot');
+       src:url('../fonts/font-borg-webfont.eot?#iefix') format('embedded-opentype'),
+               url('../fonts/font-borg-webfont.woff') format('woff'),
+               url('../fonts/font-borg-webfont.ttf') format('truetype'),
+        url('../fonts/font-borg-webfont.svg#fontborgregular') format('svg');
+       font-weight:normal;
+       font-style:normal;
+}
+
+[class^="bf-"],[class*=" bf-"]{
+       font-family:FontBorg;
+       font-weight:normal;
+       font-style:normal;
+       text-decoration:inherit;
+       -webkit-font-smoothing:antialiased;
+       display:inline;
+       width:auto;
+       height:auto;
+       line-height:normal;
+       vertical-align:baseline;
+       background-image:none;
+       background-position:0% 0%;
+       background-repeat:repeat;
+       margin-top:0;
+}
+
+.bf-blender:before{content:"\f000";}
+.bf-cloud:before{content:"\f001";}
+.bf-network:before{content:"\f002";}
+.bf-creativecommons:before{content:"\f003";}
\ No newline at end of file
diff --git a/public_html/css/main.css b/public_html/css/main.css
new file mode 100644 (file)
index 0000000..aca9528
--- /dev/null
@@ -0,0 +1,2782 @@
+@charset "UTF-8";
+/*!
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Blender Web Assets
+ * Design components for Blender.org websites
+ *
+ * Authors: Pablo Vazquez, Niklas Ravnsborg-Gjertsen
+ */
+/** Don't load the fonts here, do it on the local file
+ ** @import url(//fonts.googleapis.com/css?family=X);
+ ** @import url(font-borg.css); // import font-borg in the local file instead
+ */
+/* Defaults look like Blender.org
+ ** (without the condensed font, need to load it on the local file)
+ */
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
+ *    user zoom.
+ */
+html {
+  font-family: sans-serif;
+  /* 1 */
+  -ms-text-size-adjust: 100%;
+  /* 2 */
+  -webkit-text-size-adjust: 100%;
+  /* 2 */ }
+
+/**
+ * Remove default margin.
+ */
+body {
+  margin: 0; }
+
+/* HTML5 display definitions
+   ========================================================================== */
+/**
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
+ * and Firefox.
+ * Correct `block` display not defined for `main` in IE 11.
+ */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block; }
+
+/**
+ * 1. Correct `inline-block` display not defined in IE 8/9.
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ */
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  /* 1 */
+  vertical-align: baseline;
+  /* 2 */ }
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+audio:not([controls]) {
+  display: none;
+  height: 0; }
+
+/**
+ * Address `[hidden]` styling not present in IE 8/9/10.
+ * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
+ */
+[hidden],
+template {
+  display: none; }
+
+/* Links
+   ========================================================================== */
+/**
+ * Remove the gray background color from active links in IE 10.
+ */
+a {
+  background-color: transparent; }
+
+/**
+ * Improve readability when focused and also mouse hovered in all browsers.
+ */
+a:active,
+a:hover {
+  outline: 0; }
+
+/* Text-level semantics
+   ========================================================================== */
+/**
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ */
+abbr[title] {
+  border-bottom: 1px dotted; }
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ */
+b,
+strong {
+  font-weight: bold; }
+
+/**
+ * Address styling not present in Safari and Chrome.
+ */
+dfn {
+  font-style: italic; }
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari, and Chrome.
+ */
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0; }
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+mark {
+  background: #ff0;
+  color: #000; }
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+small {
+  font-size: 80%; }
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline; }
+
+sup {
+  top: -0.5em; }
+
+sub {
+  bottom: -0.25em; }
+
+/* Embedded content
+   ========================================================================== */
+/**
+ * Remove border when inside `a` element in IE 8/9/10.
+ */
+img {
+  border: 0; }
+
+/**
+ * Correct overflow not hidden in IE 9/10/11.
+ */
+svg:not(:root) {
+  overflow: hidden; }
+
+/* Grouping content
+   ========================================================================== */
+/**
+ * Address margin not present in IE 8/9 and Safari.
+ */
+figure {
+  margin: 1em 40px; }
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+hr {
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+  height: 0; }
+
+/**
+ * Contain overflow in all browsers.
+ */
+pre {
+  overflow: auto; }
+
+/**
+ * Address odd `em`-unit font size rendering in all browsers.
+ */
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em; }
+
+/* Forms
+   ========================================================================== */
+/**
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
+ * styling of `select`, unless a `border` property is set.
+ */
+/**
+ * 1. Correct color not being inherited.
+ *    Known issue: affects color of disabled elements.
+ * 2. Correct font properties not being inherited.
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ */
+button,
+input,
+optgroup,
+select,
+textarea {
+  color: inherit;
+  /* 1 */
+  font: inherit;
+  /* 2 */
+  margin: 0;
+  /* 3 */ }
+
+/**
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ */
+button {
+  overflow: visible; }
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+ * Correct `select` style inheritance in Firefox.
+ */
+button,
+select {
+  text-transform: none; }
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ *    and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ *    `input` and others.
+ */
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  /* 2 */
+  cursor: pointer;
+  /* 3 */ }
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+button[disabled],
+html input[disabled] {
+  cursor: default; }
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  border: 0;
+  padding: 0; }
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+input {
+  line-height: normal; }
+
+/**
+ * It's recommended that you don't attempt to style these elements.
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
+ *
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
+ * 2. Remove excess padding in IE 8/9/10.
+ */
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  /* 1 */
+  padding: 0;
+  /* 2 */ }
+
+/**
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
+ * `font-size` values of the `input`, it causes the cursor style of the
+ * decrement button to change from `default` to `text`.
+ */
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto; }
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
+ *    (include `-moz` to future-proof).
+ */
+input[type="search"] {
+  -webkit-appearance: textfield;
+  /* 1 */
+  -moz-box-sizing: content-box;
+  -webkit-box-sizing: content-box;
+  /* 2 */
+  box-sizing: content-box; }
+
+/**
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
+ * Safari (but not Chrome) clips the cancel button when the search input has
+ * padding (and `textfield` appearance).
+ */
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none; }
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em; }
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+legend {
+  border: 0;
+  /* 1 */
+  padding: 0;
+  /* 2 */ }
+
+/**
+ * Remove default vertical scrollbar in IE 8/9/10/11.
+ */
+textarea {
+  overflow: auto; }
+
+/**
+ * Don't inherit the `font-weight` (applied by a rule above).
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ */
+optgroup {
+  font-weight: bold; }
+
+/* Tables
+   ========================================================================== */
+/**
+ * Remove most spacing between table cells.
+ */
+table {
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+td,
+th {
+  padding: 0; }
+
+/* e.g. Links, the Bluish in borg */
+/* e.g. Active status of stuff, Orangish */
+/* $font_size: 1vw; /* too soon */
+/* Mobile Stuff */
+/* Just to do some math later */
+/* Featured (our own jumbotron) */
+/** CUSTOM MIXINS
+ ** This should be safe to use in other sites
+ */
+/* Smallest, like phones on portrait.
+ **  Menu is collapsed, columns stack, no brand */
+/* Small but wide: phablets, iPads
+ **  Menu is collapsed, columns stack, no brand */
+/* Tablets portrait.
+ **  Menu is expanded, but columns stack, brand is shown */
+.media-debug {
+  color: #444444; }
+  @media (max-width: 767px) {
+    .media-debug {
+      color: #e95d4f; } }
+
+/* Animations */
+@-webkit-keyframes blink {
+  0% {
+    opacity: 1; }
+  50% {
+    opacity: 0; }
+  100% {
+    opacity: 1; } }
+@-moz-keyframes blink {
+  0% {
+    opacity: 1; }
+  50% {
+    opacity: 0; }
+  100% {
+    opacity: 1; } }
+@-webkit-keyframes fade-in-pause-out /* Used for alerts */ {
+  0% {
+    opacity: 0; }
+  10% {
+    opacity: 1; }
+  90% {
+    opacity: 1; }
+  100% {
+    opacity: 0; } }
+html, body {
+  font-family: "Open Sans", "Lucida Sans", "Lucida Grande", sans-serif, sans-serif;
+  font-size: 14px;
+  color: #444444;
+  cursor: default;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  background-color: #dfdfdf;
+  -webkit-font-smoothing: antialiased; }
+
+body {
+  padding: 52px 0 0 0; }
+
+body.dark {
+  background-color: #b8b8b8; }
+
+.dark {
+  color: white; }
+
+.container-main {
+  background-color: #f0f0f0;
+  padding-bottom: 20px; }
+
+/* LINKS */
+a, a:visited, .link {
+  color: #109df0; }
+
+a:hover, .link:hover {
+  color: #ff8844;
+  text-decoration: none !important;
+  cursor: pointer; }
+
+a:active, .link, .link:active {
+  text-decoration: underline; }
+
+a:focus, .link:focus {
+  text-decoration: none; }
+
+a, button, button:focus,
+button::-moz-focus-inner {
+  outline: none !important; }
+
+/* // LINKS */
+header {
+  width: 100%;
+  border-bottom: thin solid rgba(248, 248, 248, 0.3); }
+
+header:nth-last-of-type(1) {
+  margin-bottom: 20px; }
+
+strong, b {
+  font-weight: 700; }
+
+.container-fluid.bright {
+  background-color: #f8f8f8;
+  padding: 0 0 1% 0 !important;
+  height: 100%;
+  min-height: 100%; }
+
+/* HEADINGS */
+h1, h2, h3, h4, h5, h6 {
+  font-family: "Open Sans Condensed", "Lucida Sans", "Lucida Grande", sans-serif, sans-serif !important;
+  font-weight: normal;
+  color: #2b2b2b;
+  text-shadow: 1px 1px 0px rgba(43, 43, 43, 0.2); }
+
+h1 {
+  font-size: 265%; }
+
+h2 {
+  font-size: 220%; }
+
+h3 {
+  font-size: 180%;
+  font-weight: lighter; }
+
+h4 {
+  font-size: 140%; }
+
+h5 {
+  font-size: 120%; }
+
+h1 small, h2 small, h3 small,
+h4 small, h5 small, h6 small {
+  text-shadow: none; }
+
+p + h1 {
+  margin-top: 32px; }
+
+p + h2, p + h3, p + h4 {
+  margin-top: 25px; }
+
+.dark h1, .dark h2, .dark h3, .dark h4, .dark h5, .dark h6 {
+  color: white; }
+
+hr {
+  clear: both;
+  width: 90%;
+  height: 1px;
+  border: none;
+  margin: 15px auto 10px auto;
+  background-color: #dfdfdf; }
+
+hr.dark {
+  background-color: rgba(184, 184, 184, 0.4); }
+
+/* FORM FIELDS / INPUTS */
+input, button, select, textarea {
+  font-family: "Open Sans", "Lucida Sans", "Lucida Grande", sans-serif !important;
+  font-weight: lighter;
+  transition: background-color 0.1s ease-in;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1);
+  border-radius: 3px !important; }
+
+textarea {
+  resize: vertical;
+  padding: 6px 6px 6px 10px !important;
+  min-height: 180px; }
+
+blockquote {
+  background-color: #f3f3f3;
+  font-size: 120%;
+  margin: 10px;
+  padding: 5px 15px;
+  font-size: initial; }
+
+blockquote p, .box blockquote p {
+  margin: 5px 15px 5px 0;
+  padding: 5px 15px 5px 0; }
+
+fieldset {
+  border: none;
+  margin: 0;
+  padding: 0; }
+
+.flex {
+  display: flex; }
+  @media (max-width: 767px) {
+    .flex {
+      display: block; } }
+  @media (min-width: 768px) and (max-width: 991px) {
+    .flex {
+      display: block; } }
+  .flex [class^="col-"] {
+    display: flex; }
+    @media (max-width: 767px) {
+      .flex [class^="col-"] {
+        display: block; } }
+    @media (min-width: 768px) and (max-width: 991px) {
+      .flex [class^="col-"] {
+        display: block; } }
+    .flex [class^="col-"] .box {
+      width: 100%; }
+
+/* INPUTS */
+.input-group {
+  width: 100%;
+  position: relative; }
+
+.input-append input, .input-prepend input,
+.input-append select, .input-prepend select,
+.input-append .uneditable-input, .input-prepend .uneditable-input {
+  background-color: white;
+  transition: background-color 0.1s ease-in; }
+
+.form-control {
+  top: 0;
+  color: #111111;
+  position: absolute;
+  background-color: white !important;
+  border: none;
+  margin-top: 30px;
+  border: thin solid #c4c4c4 !important;
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1);
+  transition: all 0.15s ease-in-out; }
+
+.form-control:focus,
+.form-control:hover {
+  background-color: white !important;
+  border: thin solid #f8f8f8 !important;
+  color: #0b6ea9;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.2); }
+
+/* Form with Errors */
+.has-error .form-control {
+  border: thin solid #ef877c !important; }
+
+.has-error.input-group .input-group-addon,
+.has-error.input-group .control-label {
+  color: #e95d4f !important; }
+
+.input-group-lg > .form-control, .input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+  padding: 0px 4px 0px 10px;
+  height: 40px;
+  font-size: 120%; }
+
+/* INPUT: Checkbox */
+.input-group input.form-control[type=checkbox],
+.input-group.input-group-lg input.form-control[type=checkbox] {
+  box-shadow: none !important; }
+
+.input-group input.form-control[type=checkbox] {
+  width: 15px; }
+
+.input-group.input-group-lg input.form-control[type=checkbox] {
+  width: 20px; }
+
+/* INPUT: Checkbox Labels */
+.input-group input.form-control[type=checkbox] + label.control-label,
+.input-group.input-group-lg input.form-control[type=checkbox] + label.control-label {
+  text-align: left;
+  cursor: pointer;
+  user-select: none;
+  transition: color 0.1s ease-out; }
+
+.input-group input.form-control[type=checkbox]:hover + label.control-label,
+.input-group.input-group-lg input.form-control[type=checkbox]:hover + label.control-label {
+  color: #ff8844; }
+
+.input-group input.form-control[type=checkbox]:checked + label.control-label,
+.input-group.input-group-lg input.form-control[type=checkbox]:checked + label.control-label {
+  color: #109df0; }
+  .input-group input.form-control[type=checkbox]:checked + label.control-label:hover,
+  .input-group.input-group-lg input.form-control[type=checkbox]:checked + label.control-label:hover {
+    color: #ff8844; }
+
+.input-group input.form-control[type=checkbox] + label.control-label {
+  padding-left: 22px;
+  padding-top: 3px; }
+
+.input-group.input-group-lg input.form-control[type=checkbox] + label.control-label {
+  padding-left: 30px;
+  padding-top: 6px; }
+
+/* INPUT: Checkbox Addon */
+.input-group input.form-control[type=checkbox] + label.control-label,
+.input-group.input-group-lg input.form-control[type=checkbox] + label.control-label {
+  user-select: none; }
+
+/* INPUT ADDONS */
+.input-group .input-group-addon {
+  position: absolute;
+  top: 30px;
+  z-index: 3;
+  padding: 10px 15px 10px 12px !important;
+  background: transparent;
+  border: 0;
+  color: #777777 !important; }
+
+.input-group .input-group-addon + .form-control,
+.input-group .input-group-addon + select.form-control {
+  padding-left: 35px !important; }
+
+.input-group .input-group-addon .bf-network {
+  font-size: 140% !important;
+  position: absolute;
+  left: 8px;
+  top: 8px; }
+
+.input-group .input-group-addon .bf-cloud {
+  font-size: 160% !important;
+  position: absolute;
+  left: 8px;
+  top: 4px; }
+
+.input-group.input-group-lg .input-group-addon .bf-cloud {
+  top: 6px; }
+
+.input-group.input-group-lg .input-group-addon {
+  top: 28px; }
+
+/* For addons on the right */
+.form-control + .input-group-addon {
+  float: right;
+  right: 10px; }
+
+/* For addons with button */
+.form-control + .input-group-addon > button {
+  position: relative;
+  margin-top: -6px;
+  right: 8px;
+  background-color: transparent;
+  border: none;
+  opacity: 0.5;
+  transition: opacity 0.2s ease;
+  box-shadow: none; }
+
+/* For addons with button */
+.form-control:focus + .input-group-addon > button,
+.form-control:hover + .input-group-addon > button,
+.form-control + .input-group-addon > button:hover {
+  opacity: 1; }
+
+.form-control + .input-group-addon.danger > button {
+  color: #e95d4f; }
+
+.error {
+  color: #e95d4f; }
+
+ul.error {
+  margin: 0 !important;
+  padding: 5px 0 0 0 !important;
+  display: inline-block; }
+  ul.error li:after {
+    content: "" !important; }
+
+.box ul.error li, .box ul.error li:last-child {
+  margin-bottom: 0; }
+
+.edit_box {
+  background-color: #6cc2e7;
+  float: right;
+  color: white;
+  padding: 8px 10px;
+  margin: 8px;
+  cursor: pointer;
+  user-select: none;
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1); }
+
+.edit_box:hover {
+  background-color: #56b9e4; }
+
+.edit_box:focus, .edit_box:active {
+  background-color: #ff8844; }
+
+/* Boostrap Panels Override */
+.panel {
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1); }
+
+.panel-default {
+  border: none; }
+  .panel-default a:focus {
+    text-decoration: none; }
+
+.panel-default > .panel-heading {
+  color: #444444;
+  margin: 0;
+  background-color: #ebebeb;
+  border: none;
+  border-bottom: 2px solid #dddddd; }
+
+.panel-title {
+  font-size: 160%;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5); }
+
+a.list-group-item, .panel > .list-group .list-group-item {
+  background-color: white;
+  color: #444444;
+  border: thin solid #eaeaea;
+  border-left: 2px solid #eaeaea;
+  padding: 5% 5% 5% 40px; }
+
+a.list-group-item:hover, a.list-group-item:focus {
+  background-color: #ebebeb;
+  color: #109df0 !important;
+  border: thin solid #dddddd;
+  border-left: 2px solid #70c4f6 !important; }
+
+a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus {
+  background-color: transparent;
+  color: #ff8844 !important;
+  border: thin solid #dddddd;
+  border-left: 2px solid #ff8844 !important; }
+
+.list-group-with-icon a.list-group-item i, .panel > .list-group.list-group-with-icon .list-group-item i {
+  padding: 3px 15px 5px;
+  position: absolute;
+  float: left;
+  left: 0; }
+
+.accordion .panel-heading {
+  border-bottom: thin solid #dfdfdf;
+  transition: border-bottom 0.2s ease-out; }
+
+.accordion .collapsed .panel-heading {
+  border-bottom: thin solid transparent; }
+
+.accordion a .panel-title {
+  color: #109df0;
+  transition: color 0.1s ease-out; }
+
+.accordion a:hover .panel-title {
+  color: #ff8844 !important; }
+
+.accordion a.collapsed .panel-title {
+  color: #777777; }
+
+.panel-collapse-widget {
+  font-family: "Open Sans", "Lucida Sans", "Lucida Grande", sans-serif;
+  color: #aaaaaa;
+  display: block;
+  float: right;
+  transform: rotate(45deg);
+  transition: all 0.25s ease-out; }
+
+.panel-collapse-widget:after {
+  content: "+"; }
+
+.collapsed .panel-collapse-widget {
+  transform: rotate(0deg); }
+
+.accordion .panel-body {
+  position: relative;
+  transform: translateY(-2px);
+  opacity: 0;
+  transition: opacity 0.2s ease-out;
+  transition: transform 0.2s ease-out; }
+
+.accordion .collapse.in .panel-body {
+  opacity: 1;
+  transform: translateY(0);
+  transition: opacity 0.2s ease-out;
+  transition: transform 0.2s ease-out; }
+
+.accordion .collapsed + .collapsing .panel-body {
+  opacity: 0;
+  transition: opacity 0.2s ease-out; }
+
+/* CKEditor Overrides */
+.cke_chrome {
+  font-family: "Open Sans", "Lucida Sans", "Lucida Grande", sans-serif !important;
+  font-weight: lighter;
+  color: #2b2b2b !important;
+  border: thin solid #aaaaaa !important;
+  background-color: white !important;
+  resize: vertical;
+  margin: 0 !important;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1);
+  border-radius: 3px; }
+
+span#cke_2_top {
+  padding: 5px !important;
+  border: none;
+  background-image: none;
+  background-color: transparent !important;
+  box-shadow: none; }
+
+span.cke_toolgroup {
+  border: none;
+  border-bottom: 2px solid transparent;
+  background-image: none;
+  background-color: white; }
+
+a.cke_button_off {
+  border-bottom: 2px solid transparent !important;
+  box-shadow: none; }
+
+a.cke_button_off:hover, a.cke_button_off:focus, a.cke_button_off:active,
+a.cke_button_disabled:hover, a.cke_button_disabled:focus, a.cke_button_disabled:active {
+  background-image: none !important;
+  background-color: transparent !important;
+  color: white !important;
+  border-bottom: 2px solid #109df0 !important; }
+
+a.cke_button_on, a.cke_button_on:hover, a.cke_button_on:focus, a.cke_button_on:active {
+  background-image: none !important;
+  background-color: transparent !important;
+  border-bottom: 2px solid #ff8844 !important;
+  color: white !important;
+  box-shadow: none; }
+
+/* PLACEHOLDERS */
+::-webkit-input-placeholder {
+  color: #aaaaaa !important; }
+
+:-moz-placeholder {
+  /* Mozilla Firefox 4 to 18 */
+  color: #aaaaaa !important;
+  opacity: 1; }
+
+::-moz-placeholder {
+  color: #aaaaaa !important;
+  opacity: 1; }
+
+:-ms-input-placeholder {
+  color: #aaaaaa !important; }
+
+/* CHECKBOXES */
+.input-group.input-checkbox {
+  margin-top: 25px;
+  margin-bottom: 25px; }
+
+.input-group.input-checkbox .control-label {
+  font-size: 100%;
+  text-align: left !important; }
+
+.input-group.input-checkbox .btn-group {
+  float: right; }
+
+.input-group.input-checkbox .btn-group .btn {
+  min-width: 45px;
+  font-weight: bolder;
+  color: white;
+  background-color: #109df0;
+  border-bottom-color: #095f91; }
+
+.input-group.input-checkbox .btn-group .btn.active {
+  background-color: #ff8844;
+  border-bottom-color: #dd5000; }
+
+.input-group.input-checkbox .btn-group .btn:before {
+  content: "";
+  font-family: "FontAwesome"; }
+
+.input-group.input-checkbox .btn-group .btn.active:before {
+  content: "";
+  font-family: "FontAwesome"; }
+
+.input-group.input-checkbox .btn-group .btn {
+  color: white;
+  border-left-color: white !important;
+  border-right-color: white !important; }
+
+.input-group.input-checkbox .btn-group .btn.active {
+  box-shadow: none; }
+
+.input-group.input-checkbox .btn-group .btn:hover {
+  color: white !important; }
+
+/* DROPDOWN TOGGLES */
+.btn-group.open .dropdown-toggle {
+  box-shadow: none; }
+
+.btn-group ul.dropdown-menu {
+  font-size: 100%; }
+
+/* FORM LABELS */
+label {
+  font-weight: normal; }
+
+.control-label {
+  font-size: 95%; }
+
+.input-group-lg .control-label {
+  font-size: 100%; }
+
+.input-group .control-label {
+  position: absolute;
+  left: 0;
+  top: 8px; }
+
+.form-horizontal .control-label {
+  padding-top: 0; }
+
+.input-group select:focus {
+  border: none;
+  box-shadow: none; }
+
+.input-group select {
+  height: auto !important;
+  padding: 6px 7px 7px !important;
+  text-transform: capitalize; }
+
+.input-group select:hover,
+.input-group select:focus {
+  color: inherit; }
+
+.input-group option {
+  margin: 0 4px 0 8px !important; }
+
+.input-group.disabled {
+  opacity: 0.5;
+  pointer-events: none; }
+
+.input-group.disabled .form-control {
+  border-color: transparent;
+  background-color: #e9e9e9; }
+
+.input-group .form-control[type='file'] {
+  padding-top: 5px; }
+
+.input-group.input-group-lg .form-control[type='file'] {
+  padding-top: 6px; }
+
+/* // FORM FIELDS / INPUTS */
+.disabled {
+  opacity: 0.65 !important;
+  pointer-events: none !important;
+  user-select: none; }
+
+.user-select-none {
+  user-select: none; }
+
+.pointer-events-none {
+  pointer-events: none; }
+
+.top {
+  position: absolute !important;
+  top: 0 !important; }
+
+.bottom {
+  position: absolute !important;
+  bottom: 0 !important; }
+
+.left {
+  float: left !important;
+  left: 0 !important; }
+
+.right {
+  float: right !important;
+  right: 0 !important; }
+
+.text-align-center {
+  text-align: center !important; }
+
+.text-align-left {
+  text-align: left !important; }
+
+.text-align-right {
+  text-align: right !important; }
+
+.text-transform-uppercase {
+  text-transform: uppercase !important; }
+
+.text-transform-lowercase {
+  text-transform: lowercase !important; }
+
+.text-transform-capitalize {
+  text-transform: capitalize !important; }
+
+.text-size-100 {
+  font-size: 100% !important; }
+
+.text-size-120 {
+  font-size: 120% !important; }
+
+.content-margin-center {
+  margin-left: auto !important;
+  margin-right: auto !important; }
+
+.margin-top-0 {
+  margin-top: 0 !important; }
+
+.margin-top-1 {
+  margin-top: 1% !important; }
+
+.margin-top-2 {
+  margin-top: 2% !important; }
+
+.margin-top-3 {
+  margin-top: 3% !important; }
+
+.margin-top-4 {
+  margin-top: 4% !important; }
+
+.margin-top-5 {
+  margin-top: 5% !important; }
+
+.margin-top-5px {
+  margin-top: 5px !important; }
+
+.margin-top-10px {
+  margin-top: 10px !important; }
+
+.margin-top-15px {
+  margin-top: 15px !important; }
+
+.margin-top-20px {
+  margin-top: 20px !important; }
+
+.margin-top-25px {
+  margin-top: 25px !important; }
+
+.margin-bottom-0 {
+  margin-bottom: 0 !important; }
+
+.margin-bottom-1 {
+  margin-bottom: 1% !important; }
+
+.margin-bottom-2 {
+  margin-bottom: 2% !important; }
+
+.margin-bottom-3 {
+  margin-bottom: 3% !important; }
+
+.margin-bottom-4 {
+  margin-bottom: 4% !important; }
+
+.margin-bottom-5 {
+  margin-bottom: 5% !important; }
+
+.margin-bottom-5px {
+  margin-bottom: 5px !important; }
+
+.margin-bottom-10px {
+  margin-bottom: 10px !important; }
+
+.margin-bottom-15px {
+  margin-bottom: 15px !important; }
+
+.margin-bottom-20px {
+  margin-bottom: 20px !important; }
+
+.margin-bottom-25px {
+  margin-bottom: 25px !important; }
+
+.margin-left-0 {
+  margin-left: 0 !important; }
+
+.margin-left-1 {
+  margin-left: 1% !important; }
+
+.margin-left-2 {
+  margin-left: 2% !important; }
+
+.margin-left-3 {
+  margin-left: 3% !important; }
+
+.margin-left-4 {
+  margin-left: 4% !important; }
+
+.margin-left-5 {
+  margin-left: 5% !important; }
+
+.margin-left-5px {
+  margin-left: 5px !important; }
+
+.margin-left-10px {
+  margin-left: 10px !important; }
+
+.margin-left-15px {
+  margin-left: 15px !important; }
+
+.margin-left-20px {
+  margin-left: 20px !important; }
+
+.margin-left-25px {
+  margin-left: 25px !important; }
+
+.margin-right-0 {
+  margin-right: 0 !important; }
+
+.margin-right-1 {
+  margin-right: 1% !important; }
+
+.margin-right-2 {
+  margin-right: 2% !important; }
+
+.margin-right-3 {
+  margin-right: 3% !important; }
+
+.margin-right-4 {
+  margin-right: 4% !important; }
+
+.margin-right-5 {
+  margin-right: 5% !important; }
+
+.margin-right-5px {
+  margin-right: 5px !important; }
+
+.margin-right-10px {
+  margin-right: 10px !important; }
+
+.margin-right-15px {
+  margin-right: 15px !important; }
+
+.margin-right-20px {
+  margin-right: 20px !important; }
+
+.margin-right-25px {
+  margin-right: 25px !important; }
+
+.padding-top-0 {
+  padding-top: 0 !important; }
+
+.padding-top-1 {
+  padding-top: 1% !important; }
+
+.padding-top-2 {
+  padding-top: 2% !important; }
+
+.padding-top-3 {
+  padding-top: 3% !important; }
+
+.padding-top-4 {
+  padding-top: 4% !important; }
+
+.padding-top-5 {
+  padding-top: 5% !important; }
+
+.padding-top-5px {
+  padding-top: 5px !important; }
+
+.padding-top-10px {
+  padding-top: 10px !important; }
+
+.padding-top-15px {
+  padding-top: 15px !important; }
+
+.padding-top-20px {
+  padding-top: 20px !important; }
+
+.padding-top-25px {
+  padding-top: 25px !important; }
+
+.padding-bottom-0 {
+  padding-bottom: 0 !important; }
+
+.padding-bottom-1 {
+  padding-bottom: 1% !important; }
+
+.padding-bottom-2 {
+  padding-bottom: 2% !important; }
+
+.padding-bottom-3 {
+  padding-bottom: 3% !important; }
+
+.padding-bottom-4 {
+  padding-bottom: 4% !important; }
+
+.padding-bottom-5 {
+  padding-bottom: 5% !important; }
+
+.padding-bottom-5px {
+  padding-bottom: 5px !important; }
+
+.padding-bottom-10px {
+  padding-bottom: 10px !important; }
+
+.padding-bottom-15px {
+  padding-bottom: 15px !important; }
+
+.padding-bottom-20px {
+  padding-bottom: 20px !important; }
+
+.padding-bottom-25px {
+  padding-bottom: 25px !important; }
+
+.padding-left-0 {
+  padding-left: 0 !important; }
+
+.padding-left-1 {
+  padding-left: 1% !important; }
+
+.padding-left-2 {
+  padding-left: 2% !important; }
+
+.padding-left-3 {
+  padding-left: 3% !important; }
+
+.padding-left-4 {
+  padding-left: 4% !important; }
+
+.padding-left-5 {
+  padding-left: 5% !important; }
+
+.padding-left-5px {
+  padding-left: 5px !important; }
+
+.padding-left-10px {
+  padding-left: 10px !important; }
+
+.padding-left-15px {
+  padding-left: 15px !important; }
+
+.padding-left-20px {
+  padding-left: 20px !important; }
+
+.padding-left-25px {
+  padding-left: 25px !important; }
+
+.padding-right-0 {
+  padding-right: 0 !important; }
+
+.padding-right-1 {
+  padding-right: 1% !important; }
+
+.padding-right-2 {
+  padding-right: 2% !important; }
+
+.padding-right-3 {
+  padding-right: 3% !important; }
+
+.padding-right-4 {
+  padding-right: 4% !important; }
+
+.padding-right-5 {
+  padding-right: 5% !important; }
+
+.padding-right-5px {
+  padding-right: 5px !important; }
+
+.padding-right-10px {
+  padding-right: 10px !important; }
+
+.padding-right-15px {
+  padding-right: 15px !important; }
+
+.padding-right-20px {
+  padding-right: 20px !important; }
+
+.padding-right-25px {
+  padding-right: 25px !important; }
+
+.width-full {
+  width: 100% !important;
+  max-width: 100% !important; }
+
+.width-75 {
+  width: 75% !important;
+  max-width: 75% !important; }
+
+.width-half {
+  width: 50% !important;
+  max-width: 50% !important; }
+
+.width-25 {
+  width: 25% !important;
+  max-width: 25% !important; }
+
+.opacity-full {
+  opacity: 1 !important; }
+
+.opacity-75 {
+  opacity: 0.75 !important; }
+
+.opacity-half {
+  opacity: 0.5 !important; }
+
+.opacity-25 {
+  opacity: 0.25 !important; }
+
+.opacity-0 {
+  opacity: 0 !important; }
+
+.relative {
+  position: relative !important; }
+
+.absolute {
+  position: absolute !important; }
+
+.inline-block {
+  display: inline-block !important; }
+
+.block {
+  display: block !important; }
+
+.height-full {
+  height: 100% !important; }
+
+.overflow-hidden {
+  overflow: hidden !important; }
+
+.overflow-visible {
+  overflow: visible !important; }
+
+.text-overflow-ellipsis {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis; }
+
+.text-overflow-clip {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: clip; }
+
+.vertical-align {
+  position: relative;
+  top: 50%;
+  transform: translateY(-50%); }
+
+.cursor-hover-pointer {
+  cursor: pointer !important; }
+
+.background-default {
+  background-color: #f8f8f8 !important; }
+
+.background-bright {
+  background-color: white !important; }
+
+.background-dark {
+  background-color: #b8b8b8 !important;
+  color: white; }
+
+.background-info {
+  background-color: #40b0e0 !important;
+  color: white; }
+
+.background-success {
+  background-color: #d5d644 !important;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.4); }
+
+.background-warning {
+  background-color: #faaf40 !important; }
+
+.background-danger {
+  background-color: #e95d4f !important;
+  color: white; }
+
+.background-info h1, .background-info h2, .background-info h3, .background-info h4,
+.background-danger h1, .background-danger h2, .background-danger h3, .background-danger h4,
+.background-dark h1, .background-dark h2, .background-dark h3, .background-dark h4 {
+  color: white; }
+
+.background-success h1, .background-success h2, .background-success h3,
+.background-success h4, .background-success h5, .background-success h6 {
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.4); }
+
+.background-info a, .background-danger a, .background-dark a {
+  color: white !important;
+  font-weight: bold; }
+
+.background-info .disabled label,
+.background-danger .disabled label,
+.background-dark .disabled label {
+  color: white; }
+
+input.form-control.background-danger {
+  color: white !important;
+  border-color: #d12b1a !important; }
+
+input.form-control:hover.background-danger,
+input.form-control:focus.background-danger {
+  color: white !important;
+  background-color: #d12b1a !important;
+  border-color: #a42214 !important; }
+
+.color-bright {
+  color: white !important; }
+
+.table-row-link:hover .background-info,
+.table-row-link:hover .background-danger,
+.table-row-link:hover .background-dark {
+  color: white !important;
+  font-weight: bold; }
+
+.z-index-2 {
+  z-index: 2; }
+
+/* List Generics */
+.list-margin-bottom-1 li {
+  margin-bottom: 1%; }
+
+.list-margin-bottom-2 li {
+  margin-bottom: 2%; }
+
+.list-margin-bottom-3 li {
+  margin-bottom: 3%; }
+
+.list-margin-bottom-4 li {
+  margin-bottom: 4%; }
+
+.list-margin-bottom-5 li {
+  margin-bottom: 5%; }
+
+/* Border generics */
+.border-left {
+  border-left: thin solid #d0d0d0; }
+
+.border-left.dark {
+  border-left-color: #eaeaea; }
+
+.border-left.bright {
+  border-left-color: #b7b7b7; }
+
+.border-right {
+  border-right: thin solid #d0d0d0; }
+
+.border-right.dark {
+  border-right-color: #eaeaea; }
+
+.border-right.bright {
+  border-right-color: #b7b7b7; }
+
+.border-top {
+  border-top: thin solid #d0d0d0; }
+
+.border-top.dark {
+  border-top-color: #eaeaea; }
+
+.border-top.bright {
+  border-top-color: #b7b7b7; }
+
+.border-bottom {
+  border-bottom: thin solid #d0d0d0; }
+
+.border-bottom.dark {
+  border-bottom-color: #eaeaea; }
+
+.border-bottom.bright {
+  border-bottom-color: #b7b7b7; }
+
+.border-none {
+  border: none !important; }
+
+.border-radius-3 {
+  border-radius: 3px; }
+
+.border-radius-none {
+  border-radius: 0; }
+
+/* Top Bar: Generics */
+.navbar {
+  color: #444444;
+  border: none;
+  z-index: 9 !important;
+  /* Top level, above all. Other levels override this with !important */
+  margin-bottom: 0;
+  font-size: 140%;
+  min-height: 44px; }
+  .navbar.navbar-secondlevel:nth-last-of-type(1), .navbar.navbar-thirdlevel:nth-last-of-type(1) {
+    box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1); }
+
+@media (max-width: 767px) {
+  .navbar-nav {
+    margin: 0 -15px; } }
+
+.navbar.dark {
+  color: white; }
+
+.navbar li:after, .navbar-nav li:after {
+  content: ""; }
+
+.navbar-nav > li > a {
+  color: #444444;
+  font-family: "Open Sans Condensed", "Lucida Sans", "Lucida Grande", sans-serif !important;
+  border-bottom: 2px solid transparent;
+  text-shadow: 1px 1px 2px #f8f8f8;
+  transition: border-color 0.1s ease-out; }
+
+.navbar-default.dark .nav > li > a {
+  color: white;
+  text-shadow: 1px 1px 2px #f8f8f8; }
+
+.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
+  color: #109df0;
+  border-color: #109df0; }
+
+.navbar-default.dark .navbar-nav > li > a:hover {
+  color: white; }
+
+.navbar-default {
+  background-color: white; }
+
+.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover,
+.navbar-default .navbar-nav > .active > a:focus {
+  font-weight: normal;
+  color: #f65a00;
+  background-color: transparent;
+  border-bottom-color: #ff9558; }
+
+.navbar-brand {
+  color: #444444 !important; }
+
+.navbar-brand:hover {
+  opacity: 0.9;
+  transition: opacity 0.1s ease; }
+
+.navbar li.current_page_item a,
+.navbar li.current-page-parent a,
+.navbar li.current-page-ancestor a,
+.navbar li.current_page_parent a {
+  font-weight: normal;
+  color: #ff782a;
+  border-bottom-color: rgba(255, 136, 68, 0.8); }
+
+.navbar li.current_page_item a:hover,
+.navbar li.current-page-parent a:hover,
+.navbar li.current-page-ancestor a:hover,
+.navbar li.current_page_parent a:hover,
+.navbar li.current_page_ancestor a:hover {
+  color: #ff8844;
+  border-bottom-color: rgba(255, 136, 68, 0.8);
+  cursor: default; }
+
+.navbar li.current-page-ancestor a,
+.navbar li.current_page_ancestor a {
+  color: rgba(255, 136, 68, 0.85); }
+
+.navbar li.current-page-ancestor a:hover,
+.navbar li.current_page_ancestor a:hover {
+  cursor: pointer; }
+
+.navbar-secondlevel.navbar {
+  z-index: 8 !important;
+  /* First level is 9 */ }
+
+.navbar-secondlevel.navbar,
+.navbar-thirdlevel.navbar {
+  background-color: white;
+  min-height: 41px; }
+
+.navbar-secondlevel .navbar-nav > li > a,
+.navbar-thirdlevel .navbar-nav > li > a {
+  padding: 10px 15px 8px 15px;
+  position: relative;
+  top: 3px; }
+
+.navbar-thirdlevel {
+  z-index: 7 !important;
+  /* Second level is 8 */
+  border-top: 1px solid #f0f0f0;
+  font-size: 140%; }
+
+ul.nav.navbar-nav.navbar-left {
+  /* Otherwise navbars with many items overlap the Email on BID enabled sites */ }
+  @media (min-width: 768px) and (max-width: 991px) {
+    ul.nav.navbar-nav.navbar-left {
+      max-width: 105%;
+      margin-bottom: 0; } }
+  @media (min-width: 768px) and (max-width: 991px) {
+    ul.nav.navbar-nav.navbar-left .dropdown-menu li {
+      margin: 10px 0 10px -15px;
+      font-size: 110%; } }
+
+.navbar-toggle {
+  font-size: 1em; }
+
+/* // Top Bar: Generics */
+/* DROPDOWN MENUS */
+.dropdown-menu {
+  border: 0;
+  min-width: 130px;
+  background: white;
+  font-size: 70%;
+  padding: 0;
+  border-radius: 0;
+  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
+  transition: opacity 0.1s ease; }
+
+.dropdown-menu > li > a {
+  padding: 6% 8% 6% 6%;
+  padding-right: 45px;
+  font-weight: normal;
+  line-height: 1.42857;
+  color: #444444;
+  transition: border-color 0.05s ease; }
+
+.dropdown-menu > li > a:hover {
+  background: transparent;
+  color: #40b1f3; }
+
+.dropdown-menu > .active > a {
+  background: transparent;
+  color: #ff8844; }
+
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus, .dropdown-menu > li > a:active {
+  background: transparent;
+  color: #ff6811;
+  cursor: default; }
+
+.dropdown-menu > li > a:focus, .dropdown-menu > li > a:active,
+.dropdown-menu > .active > a:focus, .dropdown-menu > li > a:active {
+  background: transparent;
+  color: #109df0; }
+
+.dropdown-menu .divider {
+  height: 1px;
+  margin: 0;
+  background: #f8f8f8; }
+
+.dropdown-menu i {
+  float: left;
+  width: 22px;
+  margin: 3px 0 0 2px; }
+
+.navbar-nav .open .dropdown-menu {
+  border-bottom-left-radius: 3px !important;
+  border-bottom-right-radius: 3px !important; }
+  @media (min-width: 768px) and (max-width: 991px) {
+    .navbar-nav .open .dropdown-menu {
+      float: left !important;
+      width: 100%; } }
+
+/* Special classes for mobile */
+@media (min-width: 768px) and (max-width: 991px) {
+  li.dropdown.absolute.right {
+    position: relative !important;
+    float: left !important;
+    width: 100%; } }
+
+/* // DROPDOWN MENUS */
+img.alignright {
+  float: right;
+  margin: 10px 0 10px 10px; }
+
+img.alignleft {
+  float: right;
+  margin: 10px 10px 10px 0; }
+
+/* Special Classes */
+.backicon {
+  z-index: 0;
+  position: absolute;
+  font-size: 1400%;
+  bottom: -50px;
+  right: -35px;
+  color: rgba(68, 68, 68, 0.08);
+  pointer-events: none;
+  user-select: none; }
+
+.divider {
+  margin: 20px auto;
+  width: 100%;
+  height: 2px;
+  border-top: thin solid #ebebeb; }
+
+.title {
+  position: relative;
+  margin: 5px 0;
+  padding: 10px 0;
+  color: white;
+  text-shadow: 2px 2px 0 rgba(43, 43, 43, 0.3); }
+
+i.title-icon {
+  position: relative;
+  float: right;
+  margin: 0 3%;
+  bottom: 0.1em;
+  font-size: 116%;
+  opacity: 0.2; }
+
+.info {
+  color: #40b0e0 !important; }
+
+.warning {
+  color: #faaf40 !important; }
+
+.danger {
+  color: #e95d4f !important; }
+
+.success {
+  color: #bcdd2a !important; }
+
+.text-color-brand-main {
+  color: #109df0 !important; }
+
+.text-color-brand-secondary {
+  color: #ff8844 !important; }
+
+.info h1, .info h2, .info h3, .info h4, .info h5, .info h6 {
+  color: #40b0e0 !important; }
+
+.danger h1, .danger h2, .danger h3, .danger h4, .danger h5, .danger h6 {
+  color: #e95d4f !important; }
+
+.warning h1, .warning h2, .warning h3, .warning h4, .warning h5, .warning h6 {
+  color: #faaf40 !important; }
+
+.success h1, .success h2, .success h3, .success h4, .success h5, .success h6 {
+  color: #d5d644 !important; }
+
+/* LISTS */
+ul {
+  margin: 0; }
+
+ul li {
+  margin-left: 0;
+  list-style-type: none;
+  position: relative;
+  transition: all 0.1s ease-out; }
+
+ul li:after {
+  content: "";
+  position: absolute;
+  left: -10px;
+  top: -2px;
+  text-align: right;
+  font-size: 120%;
+  color: rgba(68, 68, 68, 0.5);
+  transition: all 0.15s ease-in; }
+
+ul.list-bullets-check li:after {
+  content: "";
+  font-size: 75%;
+  top: 4px;
+  left: -15px;
+  font-family: "FontAwesome"; }
+
+ul.list-bullets-none li:after {
+  content: ""; }
+
+li [class^="fa-"] {
+  /* Override Font-Awesome props */
+  text-align: left; }
+
+ul.list-margin-none {
+  padding: 0 10px 0 28px; }
+
+ul ul {
+  padding-left: 10px; }
+
+ul li ul li:after {
+  content: "";
+  font-size: 85%;
+  top: 2px;
+  left: -11px;
+  font-family: "FontAwesome"; }
+
+/* // LISTS */
+/* Pagination */
+.pagination {
+  margin: 30px auto 0px auto;
+  width: 100%;
+  text-align: center; }
+
+.pagination .active span {
+  background-color: #ff8844; }
+
+/* // PAGINATION */
+/* BUTTONS
+ **  There are simple buttons, squishy, small, big, whole lot!
+ **  Squishy ones feel like you're pressing it, let's not over use them.
+ */
+a.btn, .btn, button {
+  background-color: #f1f1f1;
+  color: #444444;
+  font-family: "Open Sans Condensed", "Lucida Sans", "Lucida Grande", sans-serif !important;
+  font-size: 130%;
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.06);
+  border: thin solid #eaeaea;
+  border-bottom: 1px solid #d8d8d8;
+  border-radius: 3px;
+  transition: all 0.1s ease-in-out; }
+  a.btn:hover, .btn:hover, button:hover {
+    background-color: #f7f7f7;
+    border-color: #eaeaea;
+    border-bottom: 1px solid #8dd0f8;
+    color: #109df0 !important; }
+  a.btn:active, a.btn:focus, .btn:active, .btn:focus, button:active, button:focus {
+    background-color: #f7f7f7;
+    color: #ff8844 !important;
+    border-color: #eaeaea;
+    border-bottom-color: #ff8844;
+    outline: none !important;
+    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.1); }
+
+a.btn.btn-squishy, .btn.btn-squishy {
+  position: relative;
+  top: 0;
+  margin-bottom: 8px;
+  font-weight: 600;
+  border-radius: 3px;
+  box-shadow: 0 3px 0 #d8d8d8; }
+  a.btn.btn-squishy:hover, .btn.btn-squishy:hover {
+    background-color: #f7f7f7;
+    top: 2px;
+    box-shadow: 0 1px 0 #d8d8d8; }
+  a.btn.btn-squishy:active, a.btn.btn-squishy:focus, .btn.btn-squishy:active, .btn.btn-squishy:focus {
+    border-bottom-color: #ff8844;
+    color: #ff8844 !important;
+    background-color: #f7f7f7;
+    border-top-color: #f7f7f7; }
+
+.btn-group.open .dropdown-toggle {
+  border: thin solid #eaeaea; }
+
+a.btn.btn-outline, .btn.btn-outline {
+  background-color: transparent;
+  color: white;
+  border: 1px solid white;
+  padding: 5px 20px;
+  box-shadow: none; }
+  a.btn.btn-outline:hover, .btn.btn-outline:hover {
+    color: white !important;
+    border: 1px solid white;
+    background-color: rgba(255, 255, 255, 0.25); }
+  a.btn.btn-outline:active, a.btn.btn-outline:focus, .btn.btn-outline:active, .btn.btn-outline:focus {
+    color: white !important;
+    border: 1px solid white;
+    background-color: rgba(255, 255, 255, 0.5); }
+
+.box a.btn.btn-outline, .box .btn.btn-outline {
+  color: #444444;
+  border: 1px solid #aaaaaa; }
+  .box a.btn.btn-outline:hover, .box .btn.btn-outline:hover {
+    color: black !important;
+    border: 1px solid #777777;
+    background-color: rgba(255, 255, 255, 0.25); }
+  .box a.btn.btn-outline:active, .box a.btn.btn-outline:focus, .box .btn.btn-outline:active, .box .btn.btn-outline:focus {
+    color: black !important;
+    border: 1px solid #444444;
+    background-color: rgba(255, 255, 255, 0.5); }
+
+/* BUTTON SUCCESS */
+a.btn-success, .btn-success {
+  background-color: #d5d644;
+  color: #40400e;
+  border-color: #d0d12f;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.6); }
+
+a.btn-success:hover, .btn-success:hover {
+  color: #444444 !important;
+  background-color: #e3e483;
+  border-color: #d0d12f; }
+
+a.btn.btn-squishy.btn-success, .btn.btn-squishy.btn-success {
+  background-color: #d5d644;
+  border-color: #d0d12f;
+  border-bottom-color: #c5c62b;
+  box-shadow: 0 3px 0 #c5c62b; }
+
+a.btn.btn-squishy.btn-success:hover, .btn.btn-squishy.btn-success:hover {
+  background-color: #dadb59;
+  box-shadow: 0 1px 0 #c5c62b; }
+
+a.btn-success:focus, .btn-success:focus,
+a.btn-success:active, .btn-success:active,
+a.btn.btn-squishy.btn-success:focus, .btn.btn-squishy.btn-success:focus,
+a.btn.btn-squishy.btn-success:active, .btn.btn-squishy.btn-success:active {
+  color: #444444 !important;
+  background-color: #bcbd2a;
+  border-bottom-color: #bcbd2a; }
+
+/* BUTTON DANGER */
+a.btn-danger, .btn-danger {
+  color: white !important;
+  background-color: #ea6558;
+  border-color: #e64838;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4); }
+
+a.btn-danger:hover, .btn-danger:hover {
+  color: white !important;
+  background-color: #ec766a;
+  border-color: #e64838;
+  border-bottom-color: #e33322; }
+
+a.btn.btn-squishy.btn-danger, .btn.btn-squishy.btn-danger {
+  background-color: #ea6558;
+  border-bottom-color: #e33322;
+  box-shadow: 0 3px 0 #d64739; }
+
+a.btn.btn-squishy.btn-danger:hover, .btn.btn-squishy.btn-danger:hover {
+  border-color: #e74c3d;
+  background-color: #ec7266;
+  box-shadow: 0 1px 0 #d12b1a; }
+
+a.btn-danger:focus, .btn-danger:focus,
+a.btn-danger:active, .btn-danger:active,
+a.btn.btn-squishy.btn-danger:focus, .btn.btn-squishy.btn-danger:focus,
+a.btn.btn-squishy.btn-danger:active, .btn.btn-squishy.btn-danger:active {
+  color: white !important;
+  background-color: #e33322;
+  border-bottom-color: #df2e1c; }
+
+/* BUTTON WARNING */
+a.btn-warning, .btn-warning {
+  color: #523202;
+  background-color: #fbbb5e;
+  border-color: #faab36;
+  text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5); }
+
+a.btn-warning:hover, .btn-warning:hover {
+  color: #2b2b2b !important;
+  background-color: #fcc87c;
+  border-color: #faab36;
+  border-bottom-color: #e78d06; }
+
+a.btn.btn-squishy.btn-warning, .btn.btn-squishy.btn-warning {
+  background-color: #fbbb5e;
+  border-bottom-color: #f69606;
+  box-shadow: 0 3px 0 #e68e0c; }
+
+a.btn.btn-squishy.btn-warning:hover, .btn.btn-squishy.btn-warning:hover {
+  background-color: #fcc87c;
+  box-shadow: 0 1px 0 #e78d06; }
+
+a.btn-warning:focus, .btn-warning:focus,
+a.btn-warning:active, .btn-warning:active,
+a.btn.btn-squishy.btn-warning:focus, .btn.btn-squishy.btn-warning:focus,
+a.btn.btn-squishy.btn-warning:active, .btn.btn-squishy.btn-warning:active {
+  color: #444444 !important;
+  background-color: #f99a0e; }
+
+/* BUTTON INFO */
+a.btn-info, .btn-info {
+  color: white !important;
+  background-color: #52b7e3;
+  border-color: #37acdf;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.4); }
+
+a.btn-info:hover, .btn-info:hover {
+  color: white !important;
+  background-color: #6cc2e7;
+  border-color: #37acdf;
+  border-bottom-color: #1e88b6; }
+
+a.btn.btn-squishy.btn-info, .btn.btn-squishy.btn-info {
+  background-color: #52b7e3;
+  border-bottom-color: #2092c3;
+  box-shadow: 0 3px 0 #239fd5; }
+
+a.btn.btn-squishy.btn-info:hover, .btn.btn-squishy.btn-info:hover {
+  background-color: #6cc2e7;
+  box-shadow: 0 1px 0 #2aa7dc; }
+
+a.btn-info:focus, .btn-info:focus,
+a.btn-info:active, .btn-info:active,
+a.btn.btn-squishy.btn-info:focus, .btn.btn-squishy.btn-info:focus,
+a.btn.btn-squishy.btn-info:active, .btn.btn-squishy.btn-info:active {
+  color: white !important;
+  background-color: #2199cc;
+  border-bottom-color: #2092c3; }
+
+/* BUTTON EXTERNAL */
+a.btn.external {
+  border-bottom: 2px solid rgba(255, 136, 68, 0.2); }
+
+a.btn.external:after {
+  content: "";
+  float: right;
+  font-size: 75%;
+  color: rgba(68, 68, 68, 0.6);
+  position: absolute;
+  top: 6px;
+  right: 8px;
+  font-family: "FontAwesome"; }
+
+/* Tiny cute lil buttons */
+.btn-xs {
+  font-size: 90%; }
+
+/* // BUTTONS */
+/* TABS */
+.nav-tabs li:after {
+  content: ""; }
+
+/* Inactive tabs */
+.nav-tabs > li > a {
+  color: #444444;
+  border-color: transparent;
+  cursor: pointer;
+  transition: color 0.1s, opacity 0.1s; }
+
+/* Mouse over inactive tab */
+.nav-tabs > li > a:hover,
+.nav-tabs > li > a:focus,
+.nav-tabs.nav-justified > li > a:hover,
+.nav-tabs.nav-justified > li > a:focus {
+  border: none;
+  background-color: transparent;
+  color: #0c7ec1;
+  border-color: transparent;
+  border-bottom: 2px solid #40b1f3 !important; }
+
+/* Active tab */
+.nav-tabs > li.active > a,
+.nav-tabs > li.active > a:hover,
+.nav-tabs > li.active > a:focus,
+.nav-tabs.nav-justified > li.active > a,
+.nav-tabs.nav-justified > li.active > a:hover,
+.nav-tabs.nav-justified > li.active > a:focus {
+  border: none;
+  background-color: transparent;
+  color: #109df0;
+  border-color: transparent;
+  border-bottom: 2px solid #109df0 !important;
+  cursor: default; }
+
+.nav-tabs.nav-justified > li > a {
+  border-bottom: 2px solid #dfdfdf !important; }
+
+/* Tab content */
+.tab-content {
+  position: relative;
+  height: 100%;
+  background-color: white;
+  border: none;
+  overflow: hidden;
+  /* for backicons */
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1); }
+
+.tab-content p {
+  padding: 10px; }
+
+/* LABELS */
+.label {
+  padding: 0.2em 0.7em 0.3em;
+  font-size: 90%;
+  font-weight: normal;
+  color: white;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
+  box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.1);
+  border-radius: 3px; }
+
+.label.label-2x {
+  font-size: 100%; }
+
+.label-info {
+  background-color: #40b0e0;
+  color: white;
+  font-weight: bold;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
+  border: thin solid #2aa7dc; }
+
+.label-danger {
+  background-color: #e95d4f;
+  color: white;
+  font-weight: bold;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
+  border: thin solid #e64838; }
+
+.label-warning {
+  background-color: #faaf40;
+  color: #523202;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
+  border: thin solid #f9a527; }
+
+.label-success {
+  background-color: #d5d644;
+  color: #40400e;
+  text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
+  border: thin solid #d0d12f; }
+
+.disabled label {
+  color: #515151; }
+
+/* // LABELS */
+/* CARDS */
+ ** swap a "front" div with a "back" div
+ ** both inside a "card" div, with a nice flip effect. */
+.flip {
+  -webkit-perspective: 1170px;
+  -moz-perspective: 0;
+  -o-perspective: 1170px;
+  perspective: 1170px;
+  position: relative;
+  clear: both; }
+
+.flip .card {
+  height: 100%;
+  -webkit-transform-style: preserve-3d;
+  -moz-transform-style: preserve-3d;
+  -o-transform-style: preserve-3d;
+  transform-style: preserve-3d;
+  -webkit-transition: 0.3s;
+  -moz-transition: 0.3s;
+  -o-transition: 0.3s;
+  transition: 0.3s; }
+
+.flip .card .face {
+  -webkit-backface-visibility: hidden;
+  -moz-backface-visibility: hidden;
+  -o-backface-visibility: hidden;
+  backface-visibility: hidden;
+  z-index: 3; }
+
+.flip .card .front {
+  position: absolute;
+  width: 100%;
+  z-index: 2;
+  -webkit-backface-visibility: hidden !important;
+  -moz-backface-visibility: hidden !important;
+  -o-backface-visibility: hidden !important;
+  backface-visibility: hidden !important;
+  transition: opacity 0.15s ease-in-out; }
+
+.flip .card .back {
+  -webkit-transform: rotatey(-180deg);
+  -moz-transform: rotatey(-180deg);
+  -o-transform: rotatey(-180deg);
+  transform: rotatey(-180deg); }
+
+.flip .face > h1, .flip .face > h2,
+.flip .face > h3, .flip .face > h4 {
+  /* Special case when card starts with a title */
+  margin-top: 0; }
+
+.flip .card.flipped {
+  -webkit-transform: rotatey(-180deg);
+  -moz-transform: rotatey(-180deg);
+  -o-transform: rotatey(-180deg);
+  transform: rotatey(-180deg); }
+
+.flipped .front {
+  /* FF */
+  opacity: 0;
+  -webkit-backface-visibility: hidden !important;
+  -moz-backface-visibility: hidden !important;
+  -o-backface-visibility: hidden !important;
+  backface-visibility: hidden !important; }
+
+.flip_toggle {
+  display: block;
+  position: absolute;
+  right: 0;
+  top: 5px;
+  padding: 2px;
+  min-width: 40px;
+  min-height: 40px;
+  z-index: 2;
+  transition: color 0.15s ease-in-out; }
+
+.flip_toggle:hover {
+  cursor: pointer;
+  color: #40b1f3; }
+
+.flip_toggle:before {
+  content: "";
+  font-family: "FontAwesome";
+  right: 12px;
+  position: absolute; }
+
+/* BOX
+ **  Use it to put content inside a neat little box
+ */
+.box, .breadcrumb {
+  position: relative;
+  background-color: white;
+  border: thin solid #f1f1f1;
+  overflow: hidden;
+  word-break: break-word;
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1); }
+
+@media (max-width: 767px) {
+  .box {
+    margin-bottom: 14px; } }
+@media (min-width: 768px) and (max-width: 991px) {
+  .box {
+    margin-bottom: 14px; } }
+.box p {
+  position: relative;
+  margin: 15px; }
+.box p + ul {
+  margin-top: -7px; }
+.box a {
+  text-shadow: none; }
+.box h1 {
+  margin: 10px 10px 0 15px;
+  text-shadow: none; }
+.box h2 {
+  margin: 10px 10px 0 15px;
+  text-shadow: none; }
+.box h3, .box h4, .box h5, .box h6 {
+  margin: 10px 0 0 15px;
+  text-shadow: none; }
+.box h2 + p {
+  margin-top: 10px; }
+.box h3 + p, .box h4 + p, .box h5 + p {
+  margin-top: 5px; }
+.box hr {
+  width: 95%;
+  opacity: 0.8; }
+.box ul {
+  margin-top: 10px;
+  margin-left: 0;
+  padding-left: 30px; }
+  .box ul li {
+    margin-bottom: 10px;
+    padding-right: 15px; }
+    .box ul li:after {
+      content: "·";
+      top: -1px;
+      left: -13px;
+      color: #aaaaaa; }
+    .box ul li:last-child {
+      margin-bottom: 35px; }
+.box .bottom {
+  width: 100%; }
+.box + .box {
+  margin-top: 20px; }
+.box ul.nav.nav-tabs {
+  margin: 0;
+  padding: 0;
+  list-style: none; }
+  .box ul.nav.nav-tabs li {
+    margin: 0;
+    padding: 0;
+    background-color: #ebebeb;
+    text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.8); }
+    .box ul.nav.nav-tabs li:first-child {
+      border-top-left-radius: 3px; }
+    .box ul.nav.nav-tabs li:last-child {
+      border-top-right-radius: 3px; }
+    .box ul.nav.nav-tabs li:after {
+      content: ""; }
+    .box ul.nav.nav-tabs li.active {
+      background-color: white; }
+    .box ul.nav.nav-tabs li a {
+      border: none;
+      border-right-color: white;
+      border-bottom-color: white;
+      text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.8); }
+
+/* // BOX */
+/* FEATURED - (our own jumbotron) */
+.featured {
+  height: 350px;
+  overflow: hidden;
+  position: relative;
+  background-color: white;
+  border: none;
+  border-bottom: thin solid #eaeaea;
+  background-image: url(https://www.blender.org/wp-content/themes/bthree/assets/images/placeholder_background.jpg);
+  background-size: cover;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.1); }
+  @media (max-width: 767px) {
+    .featured {
+      height: 160px; } }
+
+.featured-xs {
+  height: 100px; }
+
+.featured-sm {
+  height: 160px; }
+
+.featured-md {
+  height: 250px; }
+
+.featured-lg {
+  height: 350px; }
+
+.featured-xl {
+  height: 450px; }
+
+.featured h1, .featured h2, .featured h3,
+.featured h4, .featured h5, .featured h6 {
+  color: white; }
+
+.featured h1 {
+  font-size: 360%; }
+  @media (max-width: 767px) {
+    .featured h1 {
+      font-size: 200%;
+      padding: 0;
+      margin: 0; } }
+
+.featured h3 {
+  font-size: 180%; }
+  @media (max-width: 767px) {
+    .featured h3 {
+      font-size: 130%;
+      padding: 0;
+      margin: 0; } }
+
+.featured .backicon {
+  font-size: 2500%;
+  top: 116.66667px; }
+
+.featured-xs .backicon {
+  top: -50px; }
+
+.featured-sm .backicon {
+  top: -40px; }
+
+.featured-md .backicon {
+  top: 31.25px; }
+
+.featured-lg .backicon {
+  top: 116.66667px; }
+
+.featured-xl .backicon {
+  top: 180px; }
+
+/* THUMBNAILS */
+.thumbnail {
+  padding: 4px;
+  border: none;
+  background-color: white;
+  box-shadow: 1px 1px 0 rgba(68, 68, 68, 0.25);
+  transition: all 0.1s ease-out; }
+
+a img.thumbnail:hover {
+  opacity: 0.9; }
+
+/* // THUMBNAILS */
+/* ADMIN POWERS */
+.soyadmin {
+  float: right;
+  color: #444444;
+  font-size: 150%;
+  position: fixed;
+  right: 17px;
+  top: 12px;
+  z-index: 10;
+  opacity: 0.3; }
+
+.soyadmin:hover {
+  color: #109df0;
+  opacity: 1; }
+
+/* // ADMIN POWERS */
+/* ALERTS */
+.alert {
+  margin-bottom: 0;
+  border: none;
+  position: fixed;
+  z-index: 9;
+  width: 100%;
+  border-radius: 0;
+  text-align: center;
+  color: #2b2b2b;
+  font-size: 110%;
+  padding: 0;
+  -webkit-animation: fade-in-pause-out 6s;
+  -webkit-animation-fill-mode: both;
+  -moz-animation: fade-in-pause-out 6s;
+  -moz-animation-fill-mode: both;
+  -o-animation: fade-in-pause-out 6s;
+  -o-animation-fill-mode: both;
+  -ms-animation: fade-in-pause-out 6s;
+  -ms-animation-fill-mode: both; }
+
+.alert .container {
+  padding: 0.5em 0; }
+
+.alert-info, .alert-warning,
+.alert-danger, .alert-success {
+  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); }
+
+.alert-info {
+  background-color: rgba(64, 176, 224, 0.9);
+  color: white;
+  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); }
+
+.alert-warning {
+  background-color: #ff9b08;
+  color: white;
+  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4); }
+  .alert-warning .close {
+    color: #444444; }
+    .alert-warning .close:hover {
+      color: #2b2b2b !important; }
+
+.alert-danger {
+  background-color: rgba(233, 93, 79, 0.9);
+  color: white;
+  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); }
+
+.alert-success {
+  background-color: rgba(239, 240, 83, 0.9);
+  text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5); }
+  .alert-success .close {
+    color: #444444; }
+    .alert-success .close:hover {
+      color: #2b2b2b !important; }
+
+.alert button.close {
+  font-size: 90%;
+  padding: 0.2em 0.5em 0 0; }
+
+.alert-info h1, .alert-info h2, .alert-info h3, .alert-info h4,
+.alert-danger h1, .alert-danger h2, .alert-danger h3, .alert-danger h4 {
+  color: white; }
+
+.close {
+  color: white;
+  text-shadow: none;
+  opacity: 0.5; }
+
+.close:hover {
+  color: white !important;
+  background-color: transparent;
+  opacity: 1; }
+
+.alert button.close {
+  box-shadow: none; }
+
+.alert button.close:hover {
+  border: none;
+  box-shadow: none; }
+
+/* // ALERTS */
+/* TABLES (yeah they're still used every now and then */
+.table {
+  border-collapse: initial; }
+
+/* No ugly borders! */
+.table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th,
+.table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td {
+  border-top: thin solid transparent;
+  border-bottom: thin solid transparent; }
+
+/* Only on mouse over */
+.table tr:hover td {
+  border-top: thin solid #d8d8d8 !important;
+  border-bottom: thin solid #d8d8d8 !important; }
+
+.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th {
+  background-color: #f0f0f0; }
+
+/* First odd, then even */
+.table-striped > tbody > tr:nth-child(2n+1):hover > td, .table-striped > tbody > tr:nth-child(2n+1):hover > th,
+.table-striped > tbody > tr:nth-child(2n):hover > td, .table-striped > tbody > tr:nth-child(2n):hover > th {
+  background-color: #eeeeee; }
+
+.table .table-row-link:hover > tr, .table .table-row-link:hover > td {
+  color: #109df0;
+  cursor: pointer; }
+
+/* Tables with status */
+tbody > tr.danger > td a, tbody > tr.info > td a,
+tbody > tr.warning > td a, tbody > tr.success > td a {
+  font-weight: bold; }
+
+tbody > tr.danger > td a:hover, tbody > tr.info > td a:hover,
+tbody > tr.warning > td a:hover, tbody > tr.success > td a:hover {
+  text-decoration: underline !important; }
+
+tbody > tr.danger > td a, tbody > tr.info > td a {
+  color: white; }
+
+tbody > tr.warning > td a, tbody > tr.success > td a {
+  color: #444444; }
+
+.table tr.info:hover td {
+  background-color: #2199cc !important;
+  border-top: thin solid #2199cc !important;
+  border-bottom: thin solid #2199cc !important; }
+
+.table tr.danger:hover td {
+  background-color: #e64838 !important;
+  border-top: thin solid #e95d4f !important;
+  border-bottom: thin solid #e95d4f !important; }
+
+.table tr.warning:hover td {
+  background-color: #f9a527 !important;
+  border-top: thin solid #faaf40 !important;
+  border-bottom: thin solid #faaf40 !important; }
+
+.table tr.success:hover td {
+  background-color: #d0d12f !important;
+  border-top: thin solid #d5d644 !important;
+  border-bottom: thin solid #d5d644 !important; }
+
+.table-striped > tbody > tr.danger:nth-child(2n) > td, .table-striped > tbody > tr.danger:nth-child(2n) > th,
+.table-striped > tbody > tr.danger:nth-child(2n+1) > td, .table-striped > tbody > tr.danger:nth-child(2n+1) > th,
+.table-striped > tbody > tr.info:nth-child(2n) > td, .table-striped > tbody > tr.info:nth-child(2n) > th,
+.table-striped > tbody > tr.info:nth-child(2n+1) > td, .table-striped > tbody > tr.info:nth-child(2n+1) > th {
+  color: white; }
+
+.table > tbody > tr.success > td,
+.table-striped > tbody > tr.success:nth-child(2n) > td, .table-striped > tbody > tr.success:nth-child(2n) > th,
+.table-striped > tbody > tr.success:nth-child(2n+1) > td, .table-striped > tbody > tr.success:nth-child(2n+1) > th,
+.table-striped > tbody > tr.warning:nth-child(2n) > td, .table-striped > tbody > tr.warning:nth-child(2n) > th,
+.table-striped > tbody > tr.warning:nth-child(2n+1) > td, .table-striped > tbody > tr.warning:nth-child(2n+1) > th {
+  color: #444444; }
+
+/* Danger */
+.table-striped > tbody > tr.danger:nth-child(2n) > td,
+.table-striped > tbody > tr.danger:nth-child(2n) > th {
+  background-color: #ec7266; }
+
+.table-striped > tbody > tr.danger:nth-child(2n+1) > td,
+.table-striped > tbody > tr.danger:nth-child(2n+1) > th {
+  background-color: #e95d4f; }
+
+/* Success */
+.table-striped > tbody > tr.success:nth-child(2n) > td,
+.table-striped > tbody > tr.success:nth-child(2n) > th {
+  background-color: #d0d12f; }
+
+.table > tbody > tr.success > td,
+.table-striped > tbody > tr.success:nth-child(2n+1) > td,
+.table-striped > tbody > tr.success:nth-child(2n+1) > th {
+  background-color: #d5d644; }
+
+/* Warning */
+.table-striped > tbody > tr.warning:nth-child(2n) > td,
+.table-striped > tbody > tr.warning:nth-child(2n) > th {
+  background-color: #fbc472; }
+
+.table-striped > tbody > tr.warning:nth-child(2n+1) > td,
+.table-striped > tbody > tr.warning:nth-child(2n+1) > th {
+  background-color: #faaf40; }
+
+/* Info */
+.table-striped > tbody > tr.info:nth-child(2n) > td,
+.table-striped > tbody > tr.info:nth-child(2n) > th {
+  background-color: #6cc2e7; }
+
+.table-striped > tbody > tr.info:nth-child(2n+1) > td,
+.table-striped > tbody > tr.info:nth-child(2n+1) > th {
+  background-color: #40b0e0; }
+
+/* Data Tables */
+.dataTable .group {
+  font-size: 200%;
+  font-family: "Open Sans Condensed", "Lucida Sans", "Lucida Grande", sans-serif;
+  text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2); }
+
+.dataTable .group td,
+.dataTable .group td:hover {
+  background-color: #40b0e0 !important;
+  color: white !important;
+  border: none !important;
+  border-bottom: 2px solid #2199cc !important;
+  padding-top: 7px;
+  padding-bottom: 0; }
+
+.dataTable .sorting {
+  position: relative; }
+
+.dataTable .fa-sort {
+  font-size: 80%;
+  position: absolute;
+  color: #aaaaaa;
+  top: 12px;
+  right: 2px; }
+
+/* // Data Tables */
+/* LOGO */
+header a.logo {
+  display: block;
+  position: relative;
+  float: left;
+  height: 36px;
+  font-family: "Open Sans Condensed", "Lucida Sans", "Lucida Grande", sans-serif !important;
+  color: #515151;
+  text-align: right;
+  font-size: 120%;
+  background: url(https://www.blender.org/wp-content/themes/bthree/assets/images/logo.png) no-repeat;
+  font-weight: lighter;
+  line-height: 180%;
+  width: 123px;
+  opacity: 1;
+  margin: 8px 0 0 0;
+  background-size: 123px 36px;
+  transition: opacity 0.2s ease-in; }
+  @media (max-width: 767px) {
+    header a.logo {
+      margin: 12px 0 0 15px; } }
+  header a.logo:hover {
+    color: #444444;
+    opacity: 0.8; }
+
+/* // LOGO */
+/* FOOTER */
+/* Footer Navigation */
+footer {
+  font-size: 80%; }
+
+footer a {
+  color: #777777 !important; }
+
+footer a:hover {
+  color: #109df0 !important; }
+
+#footer-navigation {
+  font-size: 85%;
+  margin-bottom: 5px;
+  color: #6a6a6a;
+  border-top: thick solid #dddddd; }
+
+#footer-navigation ul {
+  position: relative;
+  margin: 0;
+  padding: 0 0 10px 16px;
+  list-style-type: none; }
+
+#footer-navigation li {
+  position: relative; }
+
+#footer-navigation a {
+  color: #6a6a6a; }
+
+#footer-navigation a:hover {
+  color: #109df0; }
+
+#footer-navigation i {
+  font-size: 80%;
+  position: absolute;
+  left: -14px;
+  top: 20%; }
+
+#footer-navigation h4 {
+  color: #585858;
+  margin-bottom: 5px; }
+
+/* Bootstrap Overrides */
+/* Breadcrumb */
+.breadcrumb > li + li:before {
+  content: "";
+  font-family: "FontAwesome"; }
+
+.breadcrumb > .active {
+  color: #919191; }
+
+/* // Breadcrumb */
+.well {
+  overflow: hidden; }
+
+.tooltip {
+  font-size: 14px;
+  position: absolute; }
+
+.tooltip.in {
+  opacity: 1; }
+
+.tooltip-inner {
+  margin: 0 auto;
+  background-color: #f8f8f8;
+  color: #444444;
+  border-radius: 3px;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.2); }
+
+.tooltip.bottom .tooltip-arrow {
+  border-bottom-color: #f8f8f8;
+  border-radius: 6px; }
+
+.tooltip.top .tooltip-arrow {
+  border-top-color: #f8f8f8; }
+
+.tooltip.bottom .tooltip-arrow {
+  border-bottom-color: #f8f8f8; }
+
+.tooltip.left .tooltip-arrow {
+  border-left-color: #f8f8f8; }
+
+.tooltip.right .tooltip-arrow {
+  border-left-color: #f8f8f8; }
+
+.popover .arrow {
+  display: none; }
+
+.popover {
+  min-width: 250px;
+  background-color: transparent;
+  border: none;
+  border-radius: 3px; }
+
+.popover-title {
+  background-color: #f8f8f8;
+  font-size: 110%;
+  border-radius: 0;
+  display: none; }
+
+.popover-content {
+  font-size: 14px;
+  border-radius: 3px;
+  background-color: #f8f8f8;
+  box-shadow: 2px 2px 0 rgba(95, 95, 95, 0.2); }
+
+.blink {
+  transition: all 2s ease-in-out;
+  animation: blink 2s infinite ease-in-out;
+  animation-name: blink;
+  -moz-animation-name: blink;
+  animation-direction: normal;
+  animation-duration: 2s;
+  animation-iteration-count: infinite;
+  animation-timing-function: ease-in-out; }
+
+.blink.slowest {
+  animation-duration: 12s; }
+
+.blink.slow {
+  animation-duration: 6s; }
+
+.blink.fast {
+  animation-duration: 1s; }
+
+.blink.fastest {
+  animation-duration: 0.5s; }
diff --git a/public_html/default.css b/public_html/default.css
new file mode 100644 (file)
index 0000000..7236da8
--- /dev/null
@@ -0,0 +1,622 @@
+
+.auth {
+position:absolute;
+top:5px;
+right:40px;
+}
+
+.alert {
+  color: #c30000;
+  background-color: #f2dcdc;
+  padding: 5px 5px 5px 25px;
+  margin-bottom: 20px;
+  border-top:1px solid #ccc;
+  border-bottom:1px solid #ccc;
+  border-color: #c30000;
+  font-size: 20px;
+}
+a:link,a:visited,a:active {
+       color: #444;
+}
+
+.Project {
+       min-width: 6em;
+}
+
+.LastBuild,.Activity {
+       padding: 0 0 0 4px;
+}
+
+.LastBuild,.Activity,.Builder,.BuildStep {
+       min-width: 5em;
+}
+
+/* Chromium Specific styles */
+div.BuildResultInfo {
+       color: #444;
+}
+
+div.Announcement {
+       margin-bottom: 1em;
+}
+
+div.Announcement>a:hover {
+       color: black;
+}
+
+div.Announcement>div.Notice {
+       background-color: #afdaff;
+       padding: 0.5em;
+       font-size: 16px;
+       text-align: center;
+}
+
+div.Announcement>div.Open {
+       border: 3px solid #8fdf5f;
+       padding: 0.5em;
+       font-size: 16px;
+       text-align: center;
+}
+
+div.Announcement>div.Closed {
+       border: 5px solid #e98080;
+       padding: 0.5em;
+       font-size: 24px;
+       font-weight: bold;
+       text-align: center;
+}
+
+td.Time {
+       color: #000;
+       border-bottom: 1px solid #aaa;
+       background-color: #eee;
+}
+
+td.Activity,td.Change,td.Builder {
+       color: #333333;
+       background-color: #CCCCCC;
+}
+
+td.Change {
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+}
+
+td.Event {
+       color: #777;
+       background-color: #ddd;
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+}
+
+td.Activity {
+       border-top-left-radius: 10px;
+       -webkit-border-top-left-radius: 10px;
+       -moz-border-radius-topleft: 10px;
+       min-height: 20px;
+       padding: 2px 0 2px 0;
+}
+
+td.idle,td.waiting,td.offline,td.building {
+       border-top-left-radius: 0px;
+       -webkit-border-top-left-radius: 0px;
+       -moz-border-radius-topleft: 0px;
+}
+
+.LastBuild {
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+       border-top-right-radius: 5px;
+       -webkit-border-top-right-radius: 5px;
+       -moz-border-radius-topright: 5px;
+}
+
+/* Console view styles */
+td.DevStatus > table {
+       table-layout: fixed;
+}
+
+td.DevRev {
+       padding: 4px 8px 4px 8px;
+       color: #333333;
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+       background-color: #eee;
+       width: 1%;
+}
+
+td.DevRevCollapse {
+       border-bottom-left-radius: 5px;
+       -webkit-border-bottom-left-radius: 5px;
+       -moz-border-radius-bottomleft: 5px;
+}
+
+td.DevName {
+       padding: 4px 8px 4px 8px;
+       color: #333333;
+       background-color: #eee;
+       width: 1%;
+       text-align: left;
+}
+
+td.DevStatus {
+       padding: 4px 4px 4px 4px;
+       color: #333333;
+       background-color: #eee;
+}
+
+td.DevSlave {
+       padding: 4px 4px 4px 4px;
+       color: #333333;
+       background-color: #eee;
+}
+
+td.first {
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+}
+
+td.last {
+       border-top-right-radius: 5px;
+       -webkit-border-top-right-radius: 5px;
+       -moz-border-radius-topright: 5px;
+}
+
+td.DevStatusCategory {
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+       border-width: 1px;
+       border-style: solid;
+}
+
+td.DevStatusCollapse {
+       border-bottom-right-radius: 5px;
+       -webkit-border-bottom-right-radius: 5px;
+       -moz-border-radius-bottomright: 5px;
+}
+
+td.DevDetails {
+       font-weight: normal;
+       padding: 8px 8px 8px 8px;
+       color: #333333;
+       background-color: #eee;
+       text-align: left;
+}
+
+td.DevDetails li a {
+       padding-right: 5px;
+}
+
+td.DevComment {
+       font-weight: normal;
+       padding: 8px 8px 8px 8px;
+       color: #333333;
+       background-color: #eee;
+       text-align: left;
+}
+
+td.DevBottom {
+       border-bottom-right-radius: 5px;
+       -webkit-border-bottom-right-radius: 5px;
+       -moz-border-radius-bottomright: 5px;
+       border-bottom-left-radius: 5px;
+       -webkit-border-bottom-left-radius: 5px;
+       -moz-border-radius-bottomleft: 5px;
+}
+
+td.Alt {
+       background-color: #ddd;
+}
+
+.legend {
+       border-radius: 5px !important;
+       -webkit-border-radius: 5px !important;
+       -moz-border-radius: 5px !important;
+       width: 100px;
+       max-width: 100px;
+       text-align: center;
+       padding: 2px 2px 2px 2px;
+       height: 14px;
+       white-space: nowrap;
+}
+
+.DevStatusBox {
+       text-align: center;
+       height: 20px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.DevStatusBox a {
+       opacity: 0.85;
+       border-width: 1px;
+       border-style: solid;
+       border-radius: 4px;
+       -webkit-border-radius: 4px;
+       -moz-border-radius: 4px;
+       display: block;
+       width: 90%;
+       height: 20px;
+       line-height: 20px;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+.DevStatusBox a.notinbuilder {
+       border-style: none;
+}
+
+.DevSlaveBox {
+       text-align: center;
+       height: 10px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.DevSlaveBox a {
+       opacity: 0.85;
+       border-width: 1px;
+       border-style: solid;
+       border-radius: 4px;
+       -webkit-border-radius: 4px;
+       -moz-border-radius: 4px;
+       display: block;
+       width: 90%;
+       height: 10px;
+       line-height: 20px;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+a.noround {
+       border-radius: 0px;
+       -webkit-border-radius: 0px;
+       -moz-border-radius: 0px;
+       position: relative;
+       margin-top: -8px;
+       margin-bottom: -8px;
+       height: 36px;
+       border-top-width: 0;
+       border-bottom-width: 0;
+}
+
+a.begin {
+       border-top-width: 1px;
+       position: relative;
+       margin-top: 0px;
+       margin-bottom: -7px;
+       height: 27px;
+       border-top-left-radius: 4px;
+       -webkit-border-top-left-radius: 4px;
+       -moz-border-radius-topleft: 4px;
+       border-top-right-radius: 4px;
+       -webkit-border-top-right-radius: 4px;
+       -moz-border-radius-topright: 4px;
+}
+
+a.end {
+       border-bottom-width: 1px;
+       position: relative;
+       margin-top: -7px;
+       margin-bottom: 0px;
+       height: 27px;
+       border-bottom-left-radius: 4px;
+       -webkit-border-bottom-left-radius: 4px;
+       -moz-border-radius-bottomleft: 4px;
+       border-bottom-right-radius: 4px;
+       -webkit-border-bottom-right-radius: 4px;
+       -moz-border-radius-bottomright: 4px;
+}
+
+.center_align {
+       text-align: center;
+}
+
+.right_align {
+       text-align: right;
+}
+
+.left_align {
+       text-align: left;
+}
+
+div.BuildWaterfall {
+       border-radius: 7px;
+       -webkit-border-radius: 7px;
+       -moz-border-radius: 7px;
+       position: absolute;
+       left: 0px;
+       top: 0px;
+       background-color: #FFFFFF;
+       padding: 4px 4px 4px 4px;
+       float: left;
+       display: none;
+       border-width: 1px;
+       border-style: solid;
+}
+
+/* LastBuild, BuildStep states /
+.success {
+    background-color: #D5D644;
+    color: #40400E;
+    text-shadow: 1px 1px 0px rgba(255, 255, 255, 0.5);
+    border: thin solid #D0D12F;
+}
+
+.failure {
+       color: #000;
+       background-color: #e88;
+       border-color: #A77272;
+}
+
+.failure-again {
+       color: #000;
+       background-color: #eA9;
+       border-color: #A77272;
+}
+
+.warnings {
+       color: #FFFFFF;
+       background-color: #fa3;
+       border-color: #C29D46;
+}
+
+.skipped {
+       color: #000;
+       background: #AADDEE;
+       border-color: #AADDEE;
+}
+
+.exception,.retry {
+       color: #FFFFFF;
+       background-color: #c6c;
+       border-color: #ACA0B3;
+}
+
+.start {
+       color: #000;
+       background-color: #ccc;
+       border-color: #ccc;
+}
+
+.running,.waiting,td.building {
+       color: #000;
+       background-color: #fd3;
+       border-color: #C5C56D;
+}
+
+.paused {
+    color: #FFFFFF;
+    background-color: #8080FF;
+    border-color: #dddddd;
+}
+
+.offline,td.offline {
+    color: #FFFFFF;
+    background-color: #777777;
+    border-color: #dddddd;
+}
+
+
+.start {
+       border-bottom-left-radius: 10px;
+       -webkit-border-bottom-left-radius: 10px;
+       -moz-border-radius-bottomleft: 10px;
+       border-bottom-right-radius: 10px;
+       -webkit-border-bottom-right-radius: 10px;
+       -moz-border-radius-bottomright: 10px;
+}
+
+.notstarted {
+       border-width: 1px;
+       border-style: solid;
+       border-color: #aaa;
+    background-color: #fff;
+}
+
+.closed {
+       background-color: #ff0000;
+}
+
+.closed .large {
+       font-size: 1.5em;
+       font-weight: bolder;
+}
+
+*/
+td.Project a:hover,td.start a:hover {
+       color: #000;
+}
+
+.mini-box {
+       text-align: center;
+       height: 20px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.mini-box a {
+       border-radius: 0;
+       -webkit-border-radius: 0;
+       -moz-border-radius: 0;
+       display: block;
+       width: 100%;
+       height: 20px;
+       line-height: 20px;
+       margin-top: -30px;
+}
+
+.mini-closed {
+       -box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+       border: 4px solid red;
+}
+
+/* grid styles */
+table.Grid {
+       border-collapse: collapse;
+}
+
+table.Grid tr td {
+       padding: 0.2em;
+       margin: 0px;
+       text-align: center;
+}
+
+table.Grid tr td.title {
+       font-size: 90%;
+       border-right: 1px gray solid;
+       border-bottom: 1px gray solid;
+}
+
+table.Grid tr td.sourcestamp {
+       font-size: 90%;
+}
+
+table.Grid tr td.builder {
+       text-align: right;
+       font-size: 90%;
+}
+
+table.Grid tr td.build {
+       border: 1px gray solid;
+}
+
+/* column container/
+div.column {
+       margin: 0 2em 2em 0;
+       float: left;
+}
+*/
+/* info tables */
+table.info {
+       border-spacing: 1px;
+}
+
+table.info td {
+       padding: 0.1em 1em 0.1em 1em;
+       text-align: center;
+}
+
+table.info th {
+       padding: 0.2em 1.5em 0.2em 1.5em;
+       text-align: center;
+}
+
+table.info td.left {
+       text-align: left
+}
+
+table.info td .reason {
+    display:block;
+    font-weight: bold;
+}
+
+.alt {
+       background-color: #f6f6f6;
+}
+
+li {
+       padding: 0.1em 1em 0.1em 1em;
+}
+
+.result {
+       padding: 0.3em 1em 0.3em 1em;
+}
+
+/* log view */
+.log * {
+       vlink: #800080;
+       font-family: "Courier New", courier, monotype, monospace;
+}
+
+span.stdout {
+       color: black;
+}
+
+span.stderr {
+       color: red;
+}
+
+span.header {
+       color: blue;
+}
+span.ansi30 {
+       color: black;
+}
+span.ansi31 {
+       color: red;
+}
+span.ansi32 {
+       color: green;
+}
+span.ansi33 {
+       color: orange;
+}
+span.ansi34 {
+       color: yellow;
+}
+span.ansi35 {
+       color: purple;
+}
+span.ansi36 {
+       color: blue;
+}
+span.ansi37 {
+       color: white;
+}
+
+/* revision & email */
+.revision .full {
+       display: none;
+}
+
+.user .email {
+       display: none;
+}
+
+pre {
+       white-space: pre-wrap;
+}
+
+/* change comments (use regular colors here) */
+pre.comments>a:link,pre.comments>a:visited {
+       color: blue;
+}
+
+pre.comments>a:active {
+       color: purple;
+}
+
+form.command_forcebuild {
+    border-top: 1px solid black;
+    padding: .5em;
+    margin: .5em;
+}
+
+form.command_forcebuild > .row {
+    border-top: 1px dotted gray;
+    padding: .5em 0;
+}
+
+form.command_forcebuild .force-textarea > .label {
+    display: block;
+}
+
+form.command_forcebuild .force-nested > .label {
+    font-weight: bold;
+    display: list-item;
+}
+
+form.command_forcebuild .force-any .force-text {
+    display: inline;
+}
diff --git a/public_html/default.css.new b/public_html/default.css.new
new file mode 100644 (file)
index 0000000..14f206d
--- /dev/null
@@ -0,0 +1,641 @@
+body.interface {
+       margin-left: 30px;
+       margin-right: 30px;
+       margin-top: 20px;
+       margin-bottom: 50px;
+       padding: 0;
+       background: url(bg_gradient.jpg) repeat-x;
+       font-family: Verdana, sans-serif;
+       font-size: 10px;
+       background-color: #fff;
+       color: #333;
+}
+
+.auth {
+position:absolute;
+top:5px;
+right:40px;
+}
+
+.alert {
+  color: #c30000;
+  background-color: #f2dcdc;
+  padding: 5px 5px 5px 25px;
+  margin-bottom: 20px;
+  border-top:1px solid #ccc;
+  border-bottom:1px solid #ccc;
+  border-color: #c30000;
+  font-size: 20px;
+}
+a:link,a:visited,a:active {
+       color: #444;
+}
+
+table {
+       border-spacing: 1px 1px;
+}
+
+table td {
+       padding: 3px 4px 3px 4px;
+       text-align: center;
+}
+
+.Project {
+       min-width: 6em;
+}
+
+.LastBuild,.Activity {
+       padding: 0 0 0 4px;
+}
+
+.LastBuild,.Activity,.Builder,.BuildStep {
+       min-width: 5em;
+}
+
+/* Chromium Specific styles */
+div.BuildResultInfo {
+       color: #444;
+}
+
+div.Announcement {
+       margin-bottom: 1em;
+}
+
+div.Announcement>a:hover {
+       color: black;
+}
+
+div.Announcement>div.Notice {
+       background-color: #afdaff;
+       padding: 0.5em;
+       font-size: 16px;
+       text-align: center;
+}
+
+div.Announcement>div.Open {
+       border: 3px solid #8fdf5f;
+       padding: 0.5em;
+       font-size: 16px;
+       text-align: center;
+}
+
+div.Announcement>div.Closed {
+       border: 5px solid #e98080;
+       padding: 0.5em;
+       font-size: 24px;
+       font-weight: bold;
+       text-align: center;
+}
+
+td.Time {
+       color: #000;
+       border-bottom: 1px solid #aaa;
+       background-color: #eee;
+}
+
+td.Activity,td.Change,td.Builder {
+       color: #333333;
+       background-color: #CCCCCC;
+}
+
+td.Change {
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+}
+
+td.Event {
+       color: #777;
+       background-color: #ddd;
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+}
+
+td.Activity {
+       border-top-left-radius: 10px;
+       -webkit-border-top-left-radius: 10px;
+       -moz-border-radius-topleft: 10px;
+       min-height: 20px;
+       padding: 2px 0 2px 0;
+}
+
+td.idle,td.waiting,td.offline,td.building {
+       border-top-left-radius: 0px;
+       -webkit-border-top-left-radius: 0px;
+       -moz-border-radius-topleft: 0px;
+}
+
+.LastBuild {
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+       border-top-right-radius: 5px;
+       -webkit-border-top-right-radius: 5px;
+       -moz-border-radius-topright: 5px;
+}
+
+/* Console view styles */
+td.DevStatus > table {
+       table-layout: fixed;
+}
+
+td.DevRev {
+       padding: 4px 8px 4px 8px;
+       color: #333333;
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+       background-color: #eee;
+       width: 1%;
+}
+
+td.DevRevCollapse {
+       border-bottom-left-radius: 5px;
+       -webkit-border-bottom-left-radius: 5px;
+       -moz-border-radius-bottomleft: 5px;
+}
+
+td.DevName {
+       padding: 4px 8px 4px 8px;
+       color: #333333;
+       background-color: #eee;
+       width: 1%;
+       text-align: left;
+}
+
+td.DevStatus {
+       padding: 4px 4px 4px 4px;
+       color: #333333;
+       background-color: #eee;
+}
+
+td.DevSlave {
+       padding: 4px 4px 4px 4px;
+       color: #333333;
+       background-color: #eee;
+}
+
+td.first {
+       border-top-left-radius: 5px;
+       -webkit-border-top-left-radius: 5px;
+       -moz-border-radius-topleft: 5px;
+}
+
+td.last {
+       border-top-right-radius: 5px;
+       -webkit-border-top-right-radius: 5px;
+       -moz-border-radius-topright: 5px;
+}
+
+td.DevStatusCategory {
+       border-radius: 5px;
+       -webkit-border-radius: 5px;
+       -moz-border-radius: 5px;
+       border-width: 1px;
+       border-style: solid;
+}
+
+td.DevStatusCollapse {
+       border-bottom-right-radius: 5px;
+       -webkit-border-bottom-right-radius: 5px;
+       -moz-border-radius-bottomright: 5px;
+}
+
+td.DevDetails {
+       font-weight: normal;
+       padding: 8px 8px 8px 8px;
+       color: #333333;
+       background-color: #eee;
+       text-align: left;
+}
+
+td.DevDetails li a {
+       padding-right: 5px;
+}
+
+td.DevComment {
+       font-weight: normal;
+       padding: 8px 8px 8px 8px;
+       color: #333333;
+       background-color: #eee;
+       text-align: left;
+}
+
+td.DevBottom {
+       border-bottom-right-radius: 5px;
+       -webkit-border-bottom-right-radius: 5px;
+       -moz-border-radius-bottomright: 5px;
+       border-bottom-left-radius: 5px;
+       -webkit-border-bottom-left-radius: 5px;
+       -moz-border-radius-bottomleft: 5px;
+}
+
+td.Alt {
+       background-color: #ddd;
+}
+
+.legend {
+       border-radius: 5px !important;
+       -webkit-border-radius: 5px !important;
+       -moz-border-radius: 5px !important;
+       width: 100px;
+       max-width: 100px;
+       text-align: center;
+       padding: 2px 2px 2px 2px;
+       height: 14px;
+       white-space: nowrap;
+}
+
+.DevStatusBox {
+       text-align: center;
+       height: 20px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.DevStatusBox a {
+       opacity: 0.85;
+       border-width: 1px;
+       border-style: solid;
+       border-radius: 4px;
+       -webkit-border-radius: 4px;
+       -moz-border-radius: 4px;
+       display: block;
+       width: 90%;
+       height: 20px;
+       line-height: 20px;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+.DevStatusBox a.notinbuilder {
+       border-style: none;
+}
+
+.DevSlaveBox {
+       text-align: center;
+       height: 10px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.DevSlaveBox a {
+       opacity: 0.85;
+       border-width: 1px;
+       border-style: solid;
+       border-radius: 4px;
+       -webkit-border-radius: 4px;
+       -moz-border-radius: 4px;
+       display: block;
+       width: 90%;
+       height: 10px;
+       line-height: 20px;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+a.noround {
+       border-radius: 0px;
+       -webkit-border-radius: 0px;
+       -moz-border-radius: 0px;
+       position: relative;
+       margin-top: -8px;
+       margin-bottom: -8px;
+       height: 36px;
+       border-top-width: 0;
+       border-bottom-width: 0;
+}
+
+a.begin {
+       border-top-width: 1px;
+       position: relative;
+       margin-top: 0px;
+       margin-bottom: -7px;
+       height: 27px;
+       border-top-left-radius: 4px;
+       -webkit-border-top-left-radius: 4px;
+       -moz-border-radius-topleft: 4px;
+       border-top-right-radius: 4px;
+       -webkit-border-top-right-radius: 4px;
+       -moz-border-radius-topright: 4px;
+}
+
+a.end {
+       border-bottom-width: 1px;
+       position: relative;
+       margin-top: -7px;
+       margin-bottom: 0px;
+       height: 27px;
+       border-bottom-left-radius: 4px;
+       -webkit-border-bottom-left-radius: 4px;
+       -moz-border-radius-bottomleft: 4px;
+       border-bottom-right-radius: 4px;
+       -webkit-border-bottom-right-radius: 4px;
+       -moz-border-radius-bottomright: 4px;
+}
+
+.center_align {
+       text-align: center;
+}
+
+.right_align {
+       text-align: right;
+}
+
+.left_align {
+       text-align: left;
+}
+
+div.BuildWaterfall {
+       border-radius: 7px;
+       -webkit-border-radius: 7px;
+       -moz-border-radius: 7px;
+       position: absolute;
+       left: 0px;
+       top: 0px;
+       background-color: #FFFFFF;
+       padding: 4px 4px 4px 4px;
+       float: left;
+       display: none;
+       border-width: 1px;
+       border-style: solid;
+}
+
+/* LastBuild, BuildStep states */
+.success {
+       color: #000;
+       background-color: #8d4;
+       border-color: #4F8530;
+}
+
+.failure {
+       color: #000;
+       background-color: #e88;
+       border-color: #A77272;
+}
+
+.failure-again {
+       color: #000;
+       background-color: #eA9;
+       border-color: #A77272;
+}
+
+.warnings {
+       color: #FFFFFF;
+       background-color: #fa3;
+       border-color: #C29D46;
+}
+
+.skipped {
+       color: #000;
+       background: #AADDEE;
+       border-color: #AADDEE;
+}
+
+.exception,.retry {
+       color: #FFFFFF;
+       background-color: #c6c;
+       border-color: #ACA0B3;
+}
+
+.start {
+       color: #000;
+       background-color: #ccc;
+       border-color: #ccc;
+}
+
+.running,.waiting,td.building {
+       color: #000;
+       background-color: #fd3;
+       border-color: #C5C56D;
+}
+
+.paused {
+    color: #FFFFFF;
+    background-color: #8080FF;
+    border-color: #dddddd;
+}
+
+.offline,td.offline {
+    color: #FFFFFF;
+    background-color: #777777;
+    border-color: #dddddd;
+}
+
+
+.start {
+       border-bottom-left-radius: 10px;
+       -webkit-border-bottom-left-radius: 10px;
+       -moz-border-radius-bottomleft: 10px;
+       border-bottom-right-radius: 10px;
+       -webkit-border-bottom-right-radius: 10px;
+       -moz-border-radius-bottomright: 10px;
+}
+
+.notstarted {
+       border-width: 1px;
+       border-style: solid;
+       border-color: #aaa;
+    background-color: #fff;
+}
+
+.closed {
+       background-color: #ff0000;
+}
+
+.closed .large {
+       font-size: 1.5em;
+       font-weight: bolder;
+}
+
+td.Project a:hover,td.start a:hover {
+       color: #000;
+}
+
+.mini-box {
+       text-align: center;
+       height: 20px;
+       padding: 0 2px;
+       line-height: 0;
+       white-space: nowrap;
+}
+
+.mini-box a {
+       border-radius: 0;
+       -webkit-border-radius: 0;
+       -moz-border-radius: 0;
+       display: block;
+       width: 100%;
+       height: 20px;
+       line-height: 20px;
+       margin-top: -30px;
+}
+
+.mini-closed {
+       -box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+       border: 4px solid red;
+}
+
+/* grid styles */
+table.Grid {
+       border-collapse: collapse;
+}
+
+table.Grid tr td {
+       padding: 0.2em;
+       margin: 0px;
+       text-align: center;
+}
+
+table.Grid tr td.title {
+       font-size: 90%;
+       border-right: 1px gray solid;
+       border-bottom: 1px gray solid;
+}
+
+table.Grid tr td.sourcestamp {
+       font-size: 90%;
+}
+
+table.Grid tr td.builder {
+       text-align: right;
+       font-size: 90%;
+}
+
+table.Grid tr td.build {
+       border: 1px gray solid;
+}
+
+/* column container */
+div.column {
+       margin: 0 2em 2em 0;
+       float: left;
+}
+
+/* info tables */
+table.info {
+       border-spacing: 1px;
+}
+
+table.info td {
+       padding: 0.1em 1em 0.1em 1em;
+       text-align: center;
+}
+
+table.info th {
+       padding: 0.2em 1.5em 0.2em 1.5em;
+       text-align: center;
+}
+
+table.info td.left {
+       text-align: left
+}
+
+table.info td .reason {
+    display:block;
+    font-weight: bold;
+}
+
+.alt {
+       background-color: #f6f6f6;
+}
+
+li {
+       padding: 0.1em 1em 0.1em 1em;
+}
+
+.result {
+       padding: 0.3em 1em 0.3em 1em;
+}
+
+/* log view */
+.log * {
+       vlink: #800080;
+       font-family: "Courier New", courier, monotype, monospace;
+}
+
+span.stdout {
+       color: black;
+}
+
+span.stderr {
+       color: red;
+}
+
+span.header {
+       color: blue;
+}
+span.ansi30 {
+       color: black;
+}
+span.ansi31 {
+       color: red;
+}
+span.ansi32 {
+       color: green;
+}
+span.ansi33 {
+       color: orange;
+}
+span.ansi34 {
+       color: yellow;
+}
+span.ansi35 {
+       color: purple;
+}
+span.ansi36 {
+       color: blue;
+}
+span.ansi37 {
+       color: white;
+}
+
+/* revision & email */
+.revision .full {
+       display: none;
+}
+
+.user .email {
+       display: none;
+}
+
+pre {
+       white-space: pre-wrap;
+}
+
+/* change comments (use regular colors here) */
+pre.comments>a:link,pre.comments>a:visited {
+       color: blue;
+}
+
+pre.comments>a:active {
+       color: purple;
+}
+
+form.command_forcebuild {
+    border-top: 1px solid black;
+    padding: .5em;
+    margin: .5em;
+}
+
+form.command_forcebuild > .row {
+    border-top: 1px dotted gray;
+    padding: .5em 0;
+}
+
+form.command_forcebuild .force-textarea > .label {
+    display: block;
+}
+
+form.command_forcebuild .force-nested > .label {
+    font-weight: bold;
+    display: list-item;
+}
+
+form.command_forcebuild .force-any .force-text {
+    display: inline;
+}
diff --git a/public_html/favicon.ico b/public_html/favicon.ico
new file mode 100644 (file)
index 0000000..f125d24
Binary files /dev/null and b/public_html/favicon.ico differ
diff --git a/public_html/lin.png b/public_html/lin.png
new file mode 100644 (file)
index 0000000..c666762
Binary files /dev/null and b/public_html/lin.png differ
diff --git a/public_html/osx.png b/public_html/osx.png
new file mode 100644 (file)
index 0000000..2ffe7e0
Binary files /dev/null and b/public_html/osx.png differ
diff --git a/public_html/robots.txt b/public_html/robots.txt
new file mode 100644 (file)
index 0000000..b139ade
--- /dev/null
@@ -0,0 +1,10 @@
+User-agent: *
+Disallow: /waterfall
+Disallow: /builders
+Disallow: /changes
+Disallow: /buildslaves
+Disallow: /schedulers
+Disallow: /one_line_per_build
+Disallow: /builders
+Disallow: /grid
+Disallow: /tgrid
diff --git a/public_html/win.png b/public_html/win.png
new file mode 100644 (file)
index 0000000..912aebb
Binary files /dev/null and b/public_html/win.png differ
diff --git a/state.sqlite b/state.sqlite
new file mode 100644 (file)
index 0000000..743d57c
Binary files /dev/null and b/state.sqlite differ
diff --git a/templates/build.html b/templates/build.html
new file mode 100644 (file)
index 0000000..684c1ba
--- /dev/null
@@ -0,0 +1,253 @@
+{% extends "layout.html" %}
+{% import 'forms.html' as forms %}
+{% from "change_macros.html" import change with context %}
+
+{% block content %}
+<div class="container">
+
+<h1>
+Builder <a href="{{ path_to_builder }}">{{ b.getBuilder().getName() }}</a>
+Build #{{ b.getNumber() }}
+</h1>
+
+{% if not b.isFinished() %}
+  <h2>Build In Progress:</h2>
+
+  {% if when_time %}
+    <p>ETA: {{ when_time }} [{{ when }}]</p>
+  {% endif %}
+
+  {{ current_step }}
+  
+  {% if authz.advertiseAction('stopBuild', request) %}
+    <h2>Stop Build</h2>
+    {{ forms.stop_build(build_url+"/stop", authz, on_all=False, short=False, label='This Build') }}
+  {% endif %}
+{% else %}
+  <h2>Results:</h2>
+
+  
+  <p><span class="btn-{% if result_css ==  "success" %}{{ result_css }}{% else %}danger{% endif %} btn btn-default btn-block btn-squishy disabled">   
+    {{ b.getText()|join(' ')|capitalize }}
+       </span>
+  </p>
+   
+  {% if b.getTestResults() %}
+    <h3><a href="{{ tests_link }}"/></h3>
+  {% endif %}
+{% endif %}
+
+<h2>
+{% if sourcestamps|count == 1 %}
+SourceStamp:
+{% else %}
+SourceStamps:
+{% endif %}
+</h2>
+
+{% for sourcestamps_row in sourcestamps | batch(3, '&nbsp;') %}
+<div class="row flex">
+{% for ss in sourcestamps_row %}
+<div class="col-md-4">
+<div class="box">
+<h3>{{ ss.codebase }}</h3>
+
+    <table class="table table-striped table-hover box">
+    {% set ss_class = cycler('alt','') %}
+
+    {% if ss.project %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Project</td><td>{{ ss.project|projectlink }}</td></tr>
+    {% endif %}
+
+    {% if ss.repository %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Repository</td><td>{{ ss.repository|repolink }}</td></tr>
+    {% endif %}
+
+    {% if ss.branch %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Branch</td><td>{{ ss.branch|e }}</td></tr>
+    {% endif %}
+
+    {% if ss.revision %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
+    {% endif %}
+
+    {% if got_revisions[ss.codebase] %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
+    {% endif %}
+
+    {% if ss.patch %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Patch</td><td>YES</td></tr>
+    {% endif %}
+
+    {% if ss.changes %}
+      <tr class="{{ ss_class.next() }}"><td class="left">Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
+    {% endif %}
+
+    {% if not ss.branch and not ss.revision and not ss.patch and not ss.changes %}
+      <tr class="{{ ss_class.next() }}"><td class="left" colspan="2">Build of most recent revision</td></tr>
+    {% endif %}
+    </table>
+       </div></div>
+{% endfor %}
+</div>
+{% endfor %}
+
+{#
+ # TODO: turn this into a table, or some other sort of definition-list
+ # that doesn't take up quite so much vertical space
+ #}
+   
+<h2>BuildSlave:</h2>
+  
+{% if slave_url %}  
+  <a href="{{ slave_url|e }}">{{ b.getSlavename()|e }}</a>
+{% else %}
+  {{ b.getSlavename()|e }} 
+{% endif %}
+
+<h2>Reason:</h2>
+<p>
+{{ b.getReason()|e }}
+</p>
+
+<h2>Steps and Logfiles:</h2>
+
+{#
+ # TODO:
+ #       urls = self.original.getURLs()
+ #       ex_url_class = "BuildStep external"
+ #       for name, target in urls.items():
+ #           text.append('[<a href="%s" class="%s">%s</a>]' %
+ #                       (target, ex_url_class, html.escape(name)))
+ #}
+
+<ol>
+{% for s in steps %}
+  <li>
+    <div class="{{ s.css_class }} result">
+      <a href="{{ s.link }}">{{ s.name }}</a> 
+         <span class="pull-right label label-info">{{ s.text }} &nbsp;
+{{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
+    </div>
+
+    <ol>
+      {% set item_class = cycler('alt', '') %}
+      {% for l in s.logs %}
+        <li class="{{ item_class.next() }}"><a class="btn btn-default" href="{{ l.link }}">{{ l.name }}</a></li>
+      {% else %}
+        <li class="{{ item_class.next() }}"><a class="btn btn-default disabled" href="#" >- no logs -</a></li>
+      {% endfor %}
+    
+      {% for u in s.urls %}
+        <li class="{{ item_class.next() }}"><a class="btn btn-default" href="{{ u.url }}">{{ u.logname }}</a></li>
+      {% endfor %}
+    </ol>  
+  </li>
+{% endfor %}
+</ol>
+
+</div>
+<div class="container">
+
+<h2>Build Properties:</h2>
+
+<table class="table">
+<tr><th>Name</th><th>Value</th><th>Source</th></tr>
+
+{% for p in properties %}
+{% if p.source != "Force Build Form" %}
+  <tr class="{{ loop.cycle('alt', '') }}">
+    <td class="left">{{ p.name|e }}</td>
+    {% if p.short_value %}
+        <td>{{ p.short_value|e }} .. [property value too long]</td>
+    {% else %}
+        {% if p.value is not mapping %}
+            <td>{{ p.value|e }}</td>
+        {% else %}
+            <td>
+                <table class="table">
+                    {%- for key, value in p.value.items() recursive %}
+                        <tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
+                    {% endfor %}
+                </table>
+            </td>
+        {% endif %}
+    {% endif %}
+    <td>{{ p.source|e }}</td>
+  </tr>
+{% endif %}
+{% endfor %}
+</table>
+<h2>Forced Build Properties:</h2>
+<table class="table">
+<tr><th>Name</th><th>Label</th><th>Value</th></tr>
+
+{% for p in properties %}
+    {% if p.source == "Force Build Form" %}
+  <tr class="{{ loop.cycle('alt', '') }}">
+    <td class="left">{{ p.name|e }}</td>
+    <td class="left">
+    {% if p.label %}
+    {{ p.label }}
+    {% endif %}    
+    </td>
+    {% if p.text %}
+    <td><textarea readonly cols="{{p.cols}}" rows="{{p.rows}}">{{ p.text|e }}</textarea></td>
+    {% else %}
+    <td>{{ p.value|e }}</td>
+    {% endif %}
+  </tr>
+  {% endif %}    
+{% endfor %}
+</table>
+
+<h2>Responsible Users:</h2>
+
+{% if responsible_users %}
+  <ol>
+  {% for u in responsible_users %}
+     <li class="{{ loop.cycle('alt', '') }}">{{ u|user }}</li>
+  {% endfor %}
+  </ol>
+{% else %}
+  <p>no responsible users</p>
+{% endif %}
+
+
+<h2>Timing:</h2>
+<table class="table">
+  <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
+{% if end %}
+  <tr><td class="left">End</td><td>{{ end }}</td></tr>
+{% endif %}
+  <tr {{ 'class="alt"' if end else '' }}><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
+</table>
+
+  {% if authz.advertiseAction('forceBuild', request) %}
+    <h3>Resubmit Build:</h3>
+    {{ forms.rebuild_build(build_url+"/rebuild", authz, sourcestamps[0]) }}
+  {% endif %}
+
+</div>
+
+<br style="clear:both"/>
+  
+{% if has_changes %}
+    <div class="column">
+      <h2>All Changes:</h2>
+        {% for ss in sourcestamps %}
+            {% if ss.changes %}
+            <h3 id="changes-{{ ss.codebase }}"> {{ ss.codebase }}:</h3>
+            <ol>
+                  {% for c in ss.changes %}
+                    <li><h3>Change #{{ c.number }}</h3>
+                      {{ change(c.asDict()) }}
+                    </li>
+                  {% endfor %}
+            </ol>
+            {% endif %}
+        {% endfor %}
+    </div>
+{% endif %}
+
+{% endblock %}
diff --git a/templates/build_line.html b/templates/build_line.html
new file mode 100644 (file)
index 0000000..71be846
--- /dev/null
@@ -0,0 +1,61 @@
+{% macro build_line(b, include_builder=False) %}
+  <small>({{ b.time }})</small>
+  Rev: {% if b.multiple_revs -%}
+          multiple rev
+       {%- else -%}
+          {{ b.rev_list[0]['rev']|shortrev(b.rev_list[0]['repo']) }}
+       {%- endif %}
+  <span class="{{ b.class }}">{{ b.results }}</span>
+  {% if include_builder %}
+    <a href="{{ b.builderurl }}">{{ b.builder_name }}</a>
+  {% endif %}
+  <a href="{{ b.buildurl }}">#{{ b.buildnum }}</a> - 
+  {{ b.text|capitalize }}
+{% endmacro %}
+
+{% macro build_tr(b, include_builder=False, loop=None) %}
+  <tr class="{{ loop.cycle('alt', '') if loop }}">
+    <td>{{ b.time }}</td>
+    <td>{%- for rev in b.rev_list -%}
+          {%- if not loop.first %}<br/>{% endif -%}
+          {%- if rev.get('codebase', '') %}<span class='codebase'>{{ rev['codebase'] }}</span>:&nbsp;{% endif -%}
+          {{ rev['rev']|shortrev(rev['repo']) }}
+        {%- endfor -%}
+    </td>
+    <td><span class="btn-{% if b.class ==  "success" %}{{ b.class }}{% else %}danger{% endif %} btn  btn-block btn-squishy disabled">{{ b.results }}</span></td>
+  {%- if include_builder %}    
+    <td><a class="btn btn-block btn-squishy" href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
+  {% endif %}
+    <td><a class="btn btn-block btn-squishy" href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td> 
+    <td><span class='reason'>{{ b.reason|e }}</span>
+      {%- for user in (b.interested_users or []) -%}
+        {%- if not loop.first %}, {% endif -%}
+        <span class='interested_user'>{{ user|e }}</span>
+      {%- endfor -%}
+    </td> 
+    <td class="left">{{ b.text|capitalize }}</td>
+  </tr>
+{% endmacro %}
+
+{% macro build_table(builds, include_builder=False) %}
+{% if builds %}
+<table class="table"> 
+  <tr>
+    <th>Time</th>
+    <th>Revision</th>
+    <th>Result</th>
+     {%- if include_builder %}   
+    <th>Builder</th>
+     {% endif %}
+    <th>Build #</th>
+    <th>Reason</th>
+    <th>Info</th>
+  </tr>
+  {% for b in builds %}
+    {{ build_tr(b, include_builder, loop) }}
+  {% endfor %}
+</table>
+{% else %}
+  No matching builds found
+{% endif %}
+{% endmacro %}
diff --git a/templates/buildslave.html b/templates/buildslave.html
new file mode 100644 (file)
index 0000000..b323a77
--- /dev/null
@@ -0,0 +1,94 @@
+{% from 'build_line.html' import build_table, build_line %}
+{% import 'forms.html' as forms %}
+
+{% extends "layout.html" %}
+{% block content %}
+<h1>Buildslave: {{ slavename|e }}</h1>
+
+<div class="col-md-6">
+
+{% if current %}
+  <h2>Currently building:</h2>
+  <ul>
+  {% for b in current %}
+   <li>{{ build_line(b, True) }}
+     <form method="post" action="{{ b.buildurl }}/stop" class="command stopbuild" style="display:inline">
+       <input type="submit" value="Stop Build" />
+       <input type="hidden" name="url" value="{{ this_url }}" />
+     </form>
+   </li>
+  {% endfor %}
+  </ul>
+{% else %}
+  <h2>No current builds</h2>
+{% endif %}
+
+<h2>Recent builds</h2>
+{{ build_table(recent, True) }}
+  
+</div>
+<div class="col-md-6">
+{% if access_uri %}
+  <a href="{{ access_uri|e }}">Click to Access Slave</a>
+{% endif %}
+
+{% if admin %}
+  <h2>Administrator</h2>
+  <p>{{ admin|email }}</p>
+{% endif %}
+
+{% if host or info %}
+  <h2>Slave information</h2>
+
+{% if host %}
+  Buildbot-Slave {{ slave_version }}
+  <div class="box"><p>{{ host|e }}</p></div>
+{% endif %}
+
+{% if info %}
+<table class="table">
+<tr><th>Name</th><th>Value</th></tr>
+
+{% for info_name, info_val in info.iteritems() %}
+  <tr class="{{ loop.cycle('alt', '') }}">
+    <td class="left">{{ info_name|e }}</td>
+      {% if info_val is not mapping %}
+          <td>{{ info_val|e }}</td>
+      {% else %}
+          <td>
+              <table class="table table-striped table-hover box">
+                  {%- for key, value in info_val.items() recursive %}
+                      <tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
+                  {% endfor %}
+              </table>
+          </td>
+      {% endif %}
+  </tr>
+{% endfor %}
+</table>
+{% endif %}
+{% endif %}
+
+<h2>Connection Status</h2>
+<p>
+{{ connect_count }} connection(s) in the last hour
+{% if not slave.isConnected() %}
+(not currently connected)
+{% else %}
+</p>
+  {% if authz.advertiseAction('gracefulShutdown', request) %}
+    <h2>Graceful Shutdown</h2>
+    {% if slave.getGraceful() %}
+      <p>Slave will shut down gracefully when it is idle.</p>
+    {% else %}
+      {{ forms.graceful_shutdown(shutdown_url, authz) }}
+    {% endif %}
+  {% endif %}
+  {% if authz.advertiseAction('pauseSlave', request) %}
+    <h2>Pause Slave</h2>
+    {{ forms.pause_slave(pause_url, authz, slave.isPaused()) }}
+  {% endif %}
+{% endif %}
+</div>
+  
+{% endblock %}
diff --git a/templates/buildslaves.html b/templates/buildslaves.html
new file mode 100644 (file)
index 0000000..167966e
--- /dev/null
@@ -0,0 +1,76 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+<h1>Buildslaves</h1>
+
+<div class="container-fluid">
+
+<table class="table table-striped table-hover box">
+
+<tr>
+  <th>Name</th>
+  {%- if show_builder_column %}
+    <th>Builders</th>
+  {%- endif %}
+  <th>BuildBot</th>
+  <th>Admin</th>
+  <th>Last heard from</th>
+  <th>Connects/Hour</th>
+  <th>Status</th>
+</tr>
+
+{% for s in slaves %}
+  <tr class="{{ loop.cycle('alt','') }}">
+  <td><b><a href="{{ s.link }}">{{ s.name }}</a></b></td>
+  
+  {%- if show_builder_column %}
+    <td>
+    {%- if s.builders %}
+      {%- for b in s.builders %}
+        <a href="{{ b.link }}">{{ b.name }}</a>
+      {%- endfor %}
+    {%- else %}
+      <span class="warning">no builders</span>
+    {%- endif -%}
+    </td>
+  {%- endif %}
+
+
+  <td>{{ (s.version or '-')|e }}</td>
+  {%- if s.admin -%}
+    <td>{{ s.admin|email }}</td>
+  {%- else -%}
+    <td>-</td>
+  {%- endif -%}
+
+    <td>
+    {%- if s.last_heard_from_age -%}
+      {{ s.last_heard_from_age }} <small>({{ s.last_heard_from_time }})</small>
+    {%- endif -%}
+    </td>
+    <td>
+    {{ s.connectCount }}
+    </td>
+        
+  {% if s.connected %}
+    {% if s.running_builds %}
+      <td class="building success">Running {{ s.running_builds }} build(s)</td>
+    {% elif s.paused %}
+      <td class="warning paused">Paused</td>
+    {% else %}
+      <td class="success idle">Idle</td>
+    {% endif %}
+        
+  {% else %}
+    <td class="disabled"><i class="fa fa-frown-o"></i> Not connected</td>
+  {% endif %}
+  
+  </tr>
+{% endfor %}
+</table>
+
+</div>
+  
+{% endblock %}
diff --git a/templates/directory.html b/templates/directory.html
new file mode 100644 (file)
index 0000000..6fb7afc
--- /dev/null
@@ -0,0 +1,185 @@
+{% extends "layout.html" %}
+
+{% block content %}
+
+{% if path == "download/" %}
+<h1>Directory listing for {{ path }}</h1>
+{% else %}
+<h1>Download Latest Builds</h1>
+
+<div class="box alert-warning">
+<p><i class="fa fa-info-circle"></i> These builds are not as stable as releases, use at your own risk.</p>
+</div>
+{% endif %}
+
+{% if path == "/download/experimental/" %}
+<div class="box alert-danger"><p>
+<h1><i class="fa fa-info-circle"></i> These builds are for developer use only!</h1>
+<h2>They contain highly experimental patches, which might ruin your day!</h2>
+<h2>If you're NOT a developer, please leave this page IMMEDIATELY!</h2>
+</p></div>
+{% endif %}
+
+{% set row_class = cycler('alt', '') %}
+
+<table class="table table-striped table-hover box">
+
+<tr>
+<th>Operating System</th>
+<th>Variation</th>
+<th>Name</th>
+<th>Size</th>
+<th>Built On</th>
+</tr>
+
+{% for d in directories %}  
+  {% if not ("experimental" in d,text) %}
+  <tr class="directory {{ row_class.next() }}">
+    <td></td>
+    <td></td>
+    <td><a href="{{ d.href }}"><b>{{ d.text }}</b></a></td>
+    <td><b>{{ d.size }}</b></td>
+    <td>{{ d.lastmodified }}</td>
+  </tr>
+  {% endif %}
+{% endfor %}
+
+{% for f in files|sort %}
+  {% if ("mingw" in f.text) or ('gooseberry' in f.text) or ("experimental" in f.text) or ("vc1" in f.text) or ("vc9" in f.text) or ("multiview" in f.text) %}
+  {% else %}
+  <tr class="file {{ row_class.next() }}">
+    {% if "mingw32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "win32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "mingw64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+    {% elif "win64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+       {% elif "OSX" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-apple"></i> Mac OS X 64 bit
+          {% else %}
+             <td><i class="fa fa-apple"></i> Mac OS X 32 bit
+          {% endif %}
+       {% elif "linux" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-linux"></i> Linux 64 bit
+          {% else %}
+             <td><i class="fa fa-linux"></i> Linux 32 bit
+          {% endif %}
+       {% endif %}
+       </td>
+
+       <td>
+          Official
+       </td>
+
+    <td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
+    <td>{{ f.size }}</td>
+    <td>
+         {{ f.lastmodified }}
+       </td>
+  </tr>
+  {% endif %}
+{% endfor %}
+
+{% for f in files|sort %}
+{% if ("experimental" in f.text) %}
+  <tr class="file {{ row_class.next() }}">
+    {% if "mingw32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "win32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "mingw64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+    {% elif "win64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+       {% elif "OSX" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-apple"></i> Mac OS X 64 bit
+          {% else %}
+             <td><i class="fa fa-apple"></i> Mac OS X 32 bit
+          {% endif %}
+       {% elif "linux" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-linux"></i> Linux 64 bit
+          {% else %}
+             <td><i class="fa fa-linux"></i> Linux 32 bit
+          {% endif %}
+       {% endif %}
+       </td>
+
+       <td>Experimental Build Branch</td>
+       <td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
+       <td>{{ f.size }}</td>
+       <td>{{ f.lastmodified }}</td>
+       </tr>
+{% endif %}
+{% endfor %}
+
+<tr>
+<td>&nbsp;</th>
+<td>&nbsp;</th>
+<td>&nbsp;</th>
+<td>&nbsp;</th>
+<td>&nbsp;</th>
+</tr>
+
+{% for f in files|sort %}
+  {% if (not (("mingw" in f.text) or ("vc1" in f.text) or ("vc9" in f.text) or ("multiview" in f.text) or ("gooseberry" in f.text) )) %}
+  {% else %}
+  <tr class="file {{ row_class.next() }}">
+    {% if "mingw32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "win32" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 32 bit
+    {% elif "mingw64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+    {% elif "win64" in f.text %}
+               <td><i class="fa fa-windows"></i> Windows 64 bit
+       {% elif "OSX" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-apple"></i> Mac OS X 64 bit
+          {% else %}
+             <td><i class="fa fa-apple"></i> Mac OS X 32 bit
+          {% endif %}
+       {% elif "linux" in f.text %}
+          {% if "x86_64" in f.text %}
+             <td><i class="fa fa-linux"></i> Linux 64 bit
+          {% else %}
+             <td><i class="fa fa-linux"></i> Linux 32 bit
+          {% endif %}
+       {% endif %}
+       </td>
+
+       <td>
+    {% if "mingw" in f.text %}
+          Experimental MinGW
+    {% elif "vc11" in f.text %}
+          Experimental VS 2012<br/><span style="font-weight: normal;">(Windows Vista/7/8)</span>
+    {% elif "vc9" in f.text %}
+          Legacy VS 2008<br/><span style="font-weight: normal;">(Windows XP/Vista/7/8)</span>
+    {% elif "win32-vc12" in f.text %}
+          Official Preview VS 2013<br/><span style="font-weight: normal;">(Windows XP/Vista/7/8)</span>
+    {% elif "win64-vc12" in f.text %}
+          Official Preview VS 2013<br/><span style="font-weight: normal;">(Windows Vista/7/8)</span>
+    {% elif "multiview" in f.text %}
+          Multiview Branch<br/><span style="font-weight: normal;">(Stereoscopic 3D)</span>
+       {% elif "gooseberry" in f.text %}
+          Gooseberry Branch
+       {% else %}
+          Official
+       {% endif %}
+       </td>
+
+    <td><a class="info" onclick="ga('send', 'event', 'button', 'download', '{{f.text}}');" href="{{ f.href }}">{{ f.text }}</a></td>
+    <td>{{ f.size }}</td>
+    <td>{{ f.lastmodified }}</td>
+  </tr>
+  {% endif %}
+{% endfor %}
+</table>
+
+
+{% endblock %}
diff --git a/templates/forms.html b/templates/forms.html
new file mode 100644 (file)
index 0000000..44422aa
--- /dev/null
@@ -0,0 +1,274 @@
+
+{% macro cancel_pending_build(cancel_url, authz, short=False, id='all') %}
+  <form method="post" name="cancel" action="{{ cancel_url }}" class='form-horizontal cancelbuild'
+             {{ 'style="display:inline"' if short else '' }}>
+    {% if not short %}
+      {% if id == 'all' %}
+        <p>To cancel all builds, push the 'Cancel' button</p>
+        <p>To cancel individual builds, click the 'Cancel' buttons above.</p>
+      {% else %}
+        <p>To cancel this build, push the 'Cancel' button</p>
+      {% endif %}
+    {% endif %}
+    <input type="hidden" name="id" value="{{ id }}" />
+    <input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel" />
+  </form>
+{% endmacro %}
+
+{% macro stop_change_builds(stopchange_url, changenum, authz) %}
+  {% if not changenum  %}
+    <form method="post" action="{{ stopchange_url }}" class='form-horizontal stopchange'>
+      {% if changenum %}
+        <p>To cancel all builds for this change, push the 'Cancel' button</p>
+      {% else %}
+        <p>To cancel builds for this builder for a given change, fill out the
+          following field and push the 'Cancel' button</p>
+      {% endif %}
+
+      {% if changenum %}
+        <input type="hidden" name="change" value="{{ changenum }}" />
+      {% else %}
+        <div class="row">
+          <span class="label">Change #:</span>
+          <input type="text" name="change"/>
+        </div>
+      {% endif %}
+      <input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel" />
+    </form>
+  {% endif %}
+{% endmacro %}
+
+{% macro stop_build(stop_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
+  {% if not short %}
+    <form method="post" name="stop_build" action="{{ stop_url }}" class='form-horizontal stopbuild'
+               {{ 'style="display:inline"' if short else '' }}>
+      {% if not short %}
+        {% if on_all %}
+          <p>To stop all builds, fill out the following field and
+          push the <i>Stop {{ label }}</i> button</p>
+        {% elif on_selected %}
+          <p>To stop selected builds, select the builders, fill out the
+          following field and push the <i>Stop {{ label }}</i> button</p>
+          <table>
+          {% for b in builders %}
+            <tr>
+              <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
+              <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
+            </tr>
+          {% endfor %}
+          </table>
+
+        {% else %}
+          <p>To stop this build, fill out the following field and
+          push the <i>Stop {{ label }}</i> button</p>
+        {% endif %}
+      {% endif %}
+
+      {% if not short %}
+        <div class="row">
+          <span class="label">Reason:</span>
+          <input type="text" name="comments"/>
+        </div>
+      {% endif %}
+
+      <input class="btn btn-default btn-success btn-squishy" type="submit" value="Stop {{ label }}" />
+    </form>
+  {% endif %}
+{% endmacro %}
+
+{% macro cancel_build(cancel_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
+  {% if not short %}
+    <form method="post" name="cancel_build" action="{{ cancel_url }}" class='form-horizontal cancelbuild'
+               {{ 'style="display:inline"' if short else '' }}>
+      {% if not short %}
+        {% if on_all %}
+          <p>To cancel all pending builds, fill out the following field and
+          push the <i>Cancel {{ label }}</i> button</p>
+        {% elif on_selected %}
+          <p>To cancel selected pending builds, select the builders, fill out the
+          following field and push the <i>Cancel {{ label }}</i> button</p>
+          <table>
+          {% for b in builders %}
+            <tr>
+              <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
+              <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
+            </tr>
+          {% endfor %}
+          </table>
+
+        {% else %}
+          <p>To cancel this pending build, fill out the following field and
+          push the <i>Cancel {{ label }}</i> button</p>
+        {% endif %}
+      {% endif %}
+
+      {% if not short %}
+        <div class="row">
+          <span class="label">Reason:</span>
+          <input type="text" name="comments"/>
+        </div>
+      {% endif %}
+
+      <input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel {{ label }}" />
+    </form>
+  {% endif %}
+{% endmacro %}
+
+{% macro force_build_scheduler_parameter(f, authz, request, sch, default_props) %}
+    {% if f and not f.hide and (f.fullName != "username" or not authz.authenticated(request)) %}
+    <div class="row{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}>
+    {% if 'text' in f.type or 'int' in f.type %}
+       <span class="label">{{f.label}}</span>
+       <input type='text' size='{{f.size}}' name='{{f.fullName}}' value='{{default_props[sch.name+"."+f.fullName]}}' />
+    {% elif 'bool' in f.type%}
+       <input type='checkbox' name='checkbox' value='{{f.fullName}}' {{default_props[sch.name+"."+f.fullName]}} />
+       <span class="label">{{f.label}}</span>
+    {% elif 'textarea' in f.type %}
+       <span class="label">{{f.label}}</span>
+       <textarea name='{{f.fullName}}' rows={{f.rows}} cols={{f.cols}}>{{default_props[sch.name+"."+f.fullName]}}</textarea>
+    {% elif 'list' in f.type %}
+       <span class="label">{{f.label}}</span>
+       <span class="select">
+       <select name='{{f.fullName}}' {{ f.multiple and "multiple" or ""}}>
+         {% for c in default_props[sch.name+"."+f.fullName+".choices"] %}
+           <option {{(c in default_props[sch.name+"."+f.fullName]) and "selected" or ""}}>{{c}}</option>
+         {% endfor %}
+       </select>
+       </span>
+    {% elif 'nested' in f.type %}
+      {% if f.label %}<span class="label">{{f.label}}</span>{% endif %}
+      {% for subfield in f.fields %}
+        {{ force_build_scheduler_parameter(subfield, authz, request, sch, default_props) }}
+      {% endfor %}
+    {% endif %}
+    </div>
+  {% endif %}
+{% endmacro %}
+
+{% macro force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props) %}
+ <form method="post" name="force_build" action="{{ force_url }}" class="command_forcebuild">
+
+  <h3>{{ sch.name|e }}</h3>
+  {% if on_all %}
+     <p>To force a build on <strong>all Builders</strong>, fill out the following fields
+          and push the 'Force Build' button</p>
+  {% elif on_selected %}
+     <p>To force a build on <strong>certain Builders</strong>, select the
+        builders, fill out the following fields and push the
+        'Force Build' button</p>
+
+     <table>
+     {% for b in builders %}
+     {% if b.name in sch.builderNames %}
+       <tr>
+         <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
+         <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
+       </tr>
+       {% endif %}
+     {% endfor %}
+     </table>
+
+  {% else %}
+     <p>To force a build, fill out the following fields and
+        push the 'Force Build' button</p>
+  {% endif %}
+  <input type='hidden' name='forcescheduler' value='{{sch.name}}' />
+  {% for f in sch.all_fields %}
+    {{ force_build_scheduler_parameter(f, authz, request, sch, default_props) }}
+  {% endfor %}
+
+  <input class="btn btn-default btn-success btn-squishy" type="submit" value="{{ sch.buttonName }}" />
+ </form>
+{% endmacro %}
+{% macro force_build(force_url, authz, request, on_all=False, on_selected=False, builders=[], force_schedulers={},default_props={}) %}
+  {% for name, sch in force_schedulers.items() | sort %}
+    {{ force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props=default_props) }}
+  {% endfor %}
+
+{% endmacro %}
+
+{% macro graceful_shutdown(shutdown_url, authz) %}
+  <form method="post" action="{{ shutdown_url }}" class='form-horizontal graceful_shutdown'>
+
+  <p>To cause this slave to shut down gracefully when it is idle,
+    push the 'Graceful Shutdown' button</p>
+  <input class="btn btn-default btn-success btn-squishy" type="submit" value="Graceful Shutdown" />
+ </form>
+{% endmacro %}
+
+{% macro pause_slave(pause_url, authz, paused) %}
+  <form method="post" action="{{ pause_url }}" class='form-horizontal pause_slave'>
+
+  {% if paused %}
+    <p>To cause this slave to start running new builds again,
+      push the 'Unpause Slave' button</p>
+  {% else %}
+    <p>To cause this slave to stop running new builds,
+      push the 'Pause Slave' button</p>
+  {% endif %}
+
+  {% if paused %}
+      <input class="btn btn-default btn-success btn-squishy" type="submit" value="Unpause Slave" />
+  {% else %}
+      <input class="btn btn-default btn-success btn-squishy" type="submit" value="Pause Slave" />
+  {% endif %}
+ </form>
+{% endmacro %}
+
+{% macro clean_shutdown(shutdown_url, authz) %}
+  <form method="post" action="{{ shutdown_url }}" class='form-horizontal clean_shutdown'>
+  <p>To cause this master to shut down cleanly, push the 'Clean Shutdown' button.</p>
+  <p>No other builds will be started on this master, and the master will
+  stop once all current builds are finished.</p>
+
+  <input class="btn btn-default btn-success btn-squishy" type="submit" value="Clean Shutdown" />
+ </form>
+{% endmacro %}
+
+{% macro cancel_clean_shutdown(cancel_shutdown_url, authz) %}
+  <form method="post" action="{{ cancel_shutdown_url }}" class='form-horizontal cancel_clean_shutdown'>
+  <p>To cancel a previously initiated shutdown, push the 'Cancel Shutdown' button.</p>
+
+  <input class="btn btn-default btn-success btn-squishy" type="submit" value="Cancel Shutdown" />
+ </form>
+{% endmacro %}
+
+{% macro ping_builder(ping_url, authz) %}
+  <form method="post" action="{{ ping_url }}" class='form-horizontal ping_builder'>
+    <p>To ping the buildslave(s), push the 'Ping' button</p>
+    <input class="btn btn-default btn-success btn-squishy" type="submit" value="Ping Builder" />
+  </form>
+{% endmacro %}
+
+{% macro rebuild_build(rebuild_url, authz, ss) %}
+ <form method="post" action="{{ rebuild_url }}" class="form-horizontal rebuild">
+
+  {% if on_all %}
+     <p>To force a build on <strong>all Builders</strong>, fill out the following fields
+          and push the 'Force Build' button</p>
+  {% else %}
+     <p>To force a build, fill out the following fields and
+        push the 'Force Build' button</p>
+  {% endif %}
+   <div class="row">
+     <span class="label">Reason for re-running build:</span>
+     <input type='text' name='comments' />
+   </div>
+   <div class="row">
+     Rebuild using:
+     <select name="useSourcestamp">
+        <option value='exact' selected>Exact same revisions</option>
+        <option value='updated'>Same sourcestamps (ignoring 'got revision')</option>
+     </select>
+   </div>
+   <input class="btn btn-default btn-success btn-squishy" type="submit" value="Rebuild" />
+ </form>
+{% endmacro %}
+
+{% macro show_users(users_url, authz) %}
+  <form method="post" action="{{ users_url }}" class='form-horizontal show_users'>
+    <p>To show users, press the 'Show Users' button</p>
+
+    <input class="btn btn-default btn-success btn-squishy" type="submit" value="Show Users" />
+  </form>
+{% endmacro %}
diff --git a/templates/layout.html b/templates/layout.html
new file mode 100644 (file)
index 0000000..085fa38
--- /dev/null
@@ -0,0 +1,105 @@
+{%- block doctype -%}
+<!DOCTYPE html>
+{% endblock %}
+<html lang="en">
+  <head>
+    {% block head %}
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    {% if metatags %}
+      {{ metatags }}
+    {% endif %}
+    {% if refresh %}
+      <meta http-equiv="refresh" content="{{ refresh|e }}"/>
+    {% endif %}
+    <title>{{ title|e }}</title>
+
+       <link href="https://netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
+       <link href="https://netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
+       <link href="{{ path_to_root }}css/main.css" rel="stylesheet">
+
+    <link rel="stylesheet" href="{{ stylesheet }}" type="text/css" />
+    <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_to_root }}rss">
+
+       <link href="{{ path_to_root }}css/font-borg.css" rel="stylesheet">
+       <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
+       <link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
+    {% endblock %}
+  </head>
+  <body class="interface" onload="parent.postMessage(document.body.scrollHeight, 'https://developer.blender.org');">
+
+          {% block header -%}
+        <header class="navbar navbar-default navbar-fixed-top" role="navigation">
+            <div class="container">
+                <div class="navbar-header">
+                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cloud-navbar-collapse-1">
+                        <span class="sr-only">Toggle navigation</span>
+                        <i class="fa fa-bars"></i>
+                    </button>
+                    <a class="logo" href="{{ path_to_root or '.' }}"></a>
+                </div>
+
+                <!-- Collect the nav links, forms, and other content for toggling -->
+                <nav class="collapse navbar-collapse" id="cloud-navbar-collapse-1">
+                    <ul class="nav navbar-nav navbar-right">
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}download">Download</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}waterfall">Waterfall</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}grid">Grid</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}tgrid">T-Grid</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}builders">Builders</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}one_line_per_build">Recent Builds</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}buildslaves">Buildslaves</a></li>
+                        <li class="menu-item menu-item-type-post_type menu-item-object-page"><a href="{{ path_to_root }}about">About</a></li>
+                    </ul>
+                </nav><!-- /.navbar-collapse -->
+
+                </div>
+        </header>
+    {% endblock %}
+
+        <div class="container-fluid featured featured-xs">
+                       <div class="col-md-12 height-full">
+                               <div class="container vertical-align">
+                
+                               </div>
+                       </div>
+               </div> 
+
+    {%- block barecontent -%}
+    <div class="content col-md-12">
+      {%- block content -%}     
+      {%- endblock -%}
+    </div>
+    {%- endblock -%}
+
+    {%- block footer -%} 
+    <footer>
+        <div class="container">
+            <span class="pull-left">
+              <a href="http://buildbot.net/">BuildBot</a> ({{version}})
+              {% if project_name -%}
+                working for the&nbsp;
+                {%- if project_url -%}
+                  <a href="{{ project_url }}">{{ project_name }}</a>
+                {%- else -%}
+                  {{ project_name }}
+                {%- endif -%}
+                &nbsp;project.
+              {%- endif -%}
+            </span>
+        <span class="pull-right"><p>Page built: {{ time }} ({{ tz }})</p></span>
+        </div>
+    </footer>
+    {% endblock -%}
+
+    <script>
+      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+      })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+    
+      ga('create', 'UA-1418081-1', 'auto');
+      ga('send', 'pageview');
+    
+    </script>
+  </body>
+</html>
diff --git a/templates/root.html b/templates/root.html
new file mode 100644 (file)
index 0000000..d352206
--- /dev/null
@@ -0,0 +1,17 @@
+{% extends 'layout.html' %}
+{% import 'forms.html' as forms %}
+
+{% block content %}
+
+<h1>Blender&nbsp;Buildbot</h1>
+
+<div class="column">
+
+<h3><a href="download">Download latest builds</a></h3>
+
+<h3><a href="http://wiki.blender.org/index.php/Dev:Doc/BuildBot">Buildbot setup notes</a></h3>
+
+</div>
+
+{% endblock %}
+