From e55976f35a822e2a369b1341db35307b2cb2dde2 Mon Sep 17 00:00:00 2001 From: Will Stevens Date: Wed, 28 May 2014 12:25:35 -0400 Subject: [PATCH 01/34] fixed the formatting in all the files and added the license to each file: This closes #4 Signed-off-by: Sebastien Goasguen --- rtd/source/administration_guide.rst | 742 ++++++++++++++---- rtd/source/alloc.rst | 123 +-- rtd/source/ansible.rst | 197 +++-- rtd/source/concepts.rst | 358 +++++---- rtd/source/conf.py | 9 + rtd/source/dev.rst | 477 ++++++----- rtd/source/developer_guide.rst | 323 ++++---- rtd/source/index.rst | 80 +- .../autoscale_without_netscaler.rst | 168 +++- rtd/source/networking/ipv6.rst | 173 ++-- rtd/source/networking/midonet.rst | 69 +- rtd/source/networking/nicira-plugin.rst | 102 ++- rtd/source/networking/ovs-plugin.rst | 205 +++-- rtd/source/networking/vxlan.rst | 332 ++++---- rtd/source/plugins.rst | 590 +++++++------- 15 files changed, 2342 insertions(+), 1606 deletions(-) diff --git a/rtd/source/administration_guide.rst b/rtd/source/administration_guide.rst index c79632a..fffcc91 100644 --- a/rtd/source/administration_guide.rst +++ b/rtd/source/administration_guide.rst @@ -1,55 +1,92 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Apache CloudStack Administration Guide ====================================== Backups ------- + Monitoring ---------- + SNMP -____ +---- CloudStack will send alerts for a number of + Syslog -_______ +------ + AMQP -_____ +---- + JMX -____ +--- + API Queries -___________ +----------- Usage ----- + Tuning ------ + Configuration Parameters ------------------------ + System Reliability and Availability ----------------------------------- + HA for Management Server -_________________________ +------------------------ + +The CloudStack Management Server should be deployed in a multi-node +configuration such that it is not susceptible to individual server failures. +The Management Server itself (as distinct from the MySQL database) is +stateless and may be placed behind a load balancer. -The CloudStack Management Server should be deployed in a multi-node configuration such that it is not susceptible to individual server failures. The Management Server itself (as distinct from the MySQL database) is stateless and may be placed behind a load balancer. +Normal operation of Hosts is not impacted by an outage of all Management +Serves. All guest VMs will continue to work. -Normal operation of Hosts is not impacted by an outage of all Management Serves. All guest VMs will continue to work. +When the Management Server is down, no new VMs can be created, and the end +user and admin UI, API, dynamic load distribution, and HA will cease to work. -When the Management Server is down, no new VMs can be created, and the end user and admin UI, API, dynamic load distribution, and HA will cease to work. Management Server Load Balancing -________________________________ +-------------------------------- -CloudStack can use a load balancer to provide a virtual IP for multiple Management Servers. The administrator is responsible for creating the load balancer rules for the Management Servers. The application requires persistence or stickiness across multiple sessions. The following chart lists the ports that should be load balanced and whether or not persistence is required. +CloudStack can use a load balancer to provide a virtual IP for multiple +Management Servers. The administrator is responsible for creating the load +balancer rules for the Management Servers. The application requires +persistence or stickiness across multiple sessions. The following chart lists +the ports that should be load balanced and whether or not persistence is +required. ============ ======================== ============== ====================== Source port Destination port Protocol Persistence Required? @@ -58,304 +95,626 @@ Source port Destination port Protocol Persistence Required? 8250 8250 TCP Yes ============ ======================== ============== ====================== -In addition to above settings, the administrator is responsible for setting the 'host' global config value from the management server IP to load balancer virtual IP address. If the 'host' value is not set to the VIP for Port 8250 and one of your management servers crashes, the UI is still available but the system VMs will not be able to contact the management server. +In addition to above settings, the administrator is responsible for setting +the 'host' global config value from the management server IP to load balancer +virtual IP address. If the 'host' value is not set to the VIP for Port 8250 +and one of your management servers crashes, the UI is still available but the +system VMs will not be able to contact the management server. + Limiting the Rate of API Requests -__________________________________ +--------------------------------- + +You can limit the rate at which API requests can be placed for each account. +This is useful to avoid malicious attacks on the Management Server, prevent +performance degradation, and provide fairness to all accounts. -You can limit the rate at which API requests can be placed for each account. This is useful to avoid malicious attacks on the Management Server, prevent performance degradation, and provide fairness to all accounts. +If the number of API calls exceeds the threshold, an error message is returned +for any additional API calls. The caller will have to retry these API calls at +another time. -If the number of API calls exceeds the threshold, an error message is returned for any additional API calls. The caller will have to retry these API calls at another time. Configuring the API Request Rate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To control the API request rate, use the following global configuration settings: +To control the API request rate, use the following global configuration +settings: + +- api.throttling.enabled - Enable/Disable API throttling. By default, this + setting is false, so API throttling is not enabled. + +- api.throttling.interval (in seconds) - Time interval during which the + number of API requests is to be counted. When the interval has passed, the + API count is reset to 0. + +- api.throttling.max - Maximum number of APIs that can be placed within the + api.throttling.interval period. + +- api.throttling.cachesize - Cache size for storing API counters. Use a value + higher than the total number of accounts managed by the cloud. One cache + entry is needed for each account, to store the running API total for that + account. -* api.throttling.enabled - Enable/Disable API throttling. By default, this setting is false, so API throttling is not enabled. -* api.throttling.interval (in seconds) - Time interval during which the number of API requests is to be counted. When the interval has passed, the API count is reset to 0. -* api.throttling.max - Maximum number of APIs that can be placed within the api.throttling.interval period. -* api.throttling.cachesize - Cache size for storing API counters. Use a value higher than the total number of accounts managed by the cloud. One cache entry is needed for each account, to store the running API total for that account. Limitations on API Throttling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following limitations exist in the current implementation of this feature: -* In a deployment with multiple Management Servers, the cache is not synchronized across them. In this case, CloudStack might not be able to ensure that only the exact desired number of API requests are allowed. In the worst case, the number of API calls that might be allowed is (number of Management Servers) * (api.throttling.max). -* The API commands resetApiLimit and getApiLimit are limited to the Management Server where the API is invoked. +- In a deployment with multiple Management Servers, the cache is not + synchronized across them. In this case, CloudStack might not be able to + ensure that only the exact desired number of API requests are allowed. In + the worst case, the number of API calls that might be allowed is ``(number + of Management Servers) * (api.throttling.max)``. + +- The API commands resetApiLimit and getApiLimit are limited to the + Management Server where the API is invoked. + HA-Enabled Virtual Machines -___________________________ +--------------------------- -The user can specify a virtual machine as HA-enabled. By default, all virtual router VMs and Elastic Load Balancing VMs are automatically configured as HA-enabled. When an HA-enabled VM crashes, CloudStack detects the crash and restarts the VM automatically within the same Availability Zone. HA is never performed across different Availability Zones. CloudStack has a conservative policy towards restarting VMs and ensures that there will never be two instances of the same VM running at the same time. The Management Server attempts to start the VM on another Host in the same cluster. +The user can specify a virtual machine as HA-enabled. By default, all virtual +router VMs and Elastic Load Balancing VMs are automatically configured as +HA-enabled. When an HA-enabled VM crashes, CloudStack detects the crash and +restarts the VM automatically within the same Availability Zone. HA is never +performed across different Availability Zones. CloudStack has a conservative +policy towards restarting VMs and ensures that there will never be two +instances of the same VM running at the same time. The Management Server +attempts to start the VM on another Host in the same cluster. VM HA is not supported when the VM is using local storage. + Dedicated HA Hosts ~~~~~~~~~~~~~~~~~~ -One or more hosts can be designated for use only by HA-enabled VMs that are restarting due to a host failure. Setting up a pool of such dedicated HA hosts as the recovery destination for all HA-enabled VMs is useful to: +One or more hosts can be designated for use only by HA-enabled VMs that are +restarting due to a host failure. Setting up a pool of such dedicated HA hosts +as the recovery destination for all HA-enabled VMs is useful to: + +#. Make it easier to determine which VMs have been restarted as part of the + CloudStack high-availability function. If a VM is running on a dedicated HA + host, then it must be an HA-enabled VM whose original host failed. (With + one exception: It is possible for an administrator to manually migrate any + VM to a dedicated HA host.). + +#. Keep HA-enabled VMs from restarting on hosts which may be reserved for + other purposes. -#. Make it easier to determine which VMs have been restarted as part of the CloudStack high-availability function. If a VM is running on a dedicated HA host, then it must be an HA-enabled VM whose original host failed. (With one exception: It is possible for an administrator to manually migrate any VM to a dedicated HA host.). -#. Keep HA-enabled VMs from restarting on hosts which may be reserved for other purposes. +The dedicated HA option is set through a special host tag when the host is +created. To allow the administrator to dedicate hosts to only HA-enabled VMs, +set the global configuration variable ha.tag to the desired tag (for example, +"ha_host"), and restart the Management Server. Enter the value in the Host +Tags field when adding the host(s) that you want to dedicate to HA-enabled VMs. -The dedicated HA option is set through a special host tag when the host is created. To allow the administrator to dedicate hosts to only HA-enabled VMs, set the global configuration variable ha.tag to the desired tag (for example, "ha_host"), and restart the Management Server. Enter the value in the Host Tags field when adding the host(s) that you want to dedicate to HA-enabled VMs. Primary Storage Outage and Data Loss -____________________________________ +------------------------------------ + +When a primary storage outage occurs the hypervisor immediately stops all VMs +stored on that storage device. Guests that are marked for HA will be restarted +as soon as practical when the primary storage comes back on line. With NFS, +the hypervisor may allow the virtual machines to continue running depending on +the nature of the issue. For example, an NFS hang will cause the guest VMs to +be suspended until storage connectivity is restored.Primary storage is not +designed to be backed up. Individual volumes in primary storage can be backed +up using snapshots. -When a primary storage outage occurs the hypervisor immediately stops all VMs stored on that storage device. Guests that are marked for HA will be restarted as soon as practical when the primary storage comes back on line. With NFS, the hypervisor may allow the virtual machines to continue running depending on the nature of the issue. For example, an NFS hang will cause the guest VMs to be suspended until storage connectivity is restored.Primary storage is not designed to be backed up. Individual volumes in primary storage can be backed up using snapshots. Secondary Storage Outage and Data Loss -______________________________________ +-------------------------------------- + +For a Zone that has only one secondary storage server, a secondary storage +outage will have feature level impact to the system but will not impact +running guest VMs. It may become impossible to create a VM with the selected +template for a user. A user may also not be able to save snapshots or +examine/restore saved snapshots. These features will automatically be +available when the secondary storage comes back online. -For a Zone that has only one secondary storage server, a secondary storage outage will have feature level impact to the system but will not impact running guest VMs. It may become impossible to create a VM with the selected template for a user. A user may also not be able to save snapshots or examine/restore saved snapshots. These features will automatically be available when the secondary storage comes back online. +Secondary storage data loss will impact recently added user data including +templates, snapshots, and ISO images. Secondary storage should be backed up +periodically. Multiple secondary storage servers can be provisioned within +each zone to increase the scalability of the system. -Secondary storage data loss will impact recently added user data including templates, snapshots, and ISO images. Secondary storage should be backed up periodically. Multiple secondary storage servers can be provisioned within each zone to increase the scalability of the system. Managing System VMs ------------------- -CloudStack uses several types of system virtual machines to perform tasks in the cloud. In general CloudStack manages these system VMs and creates, starts, and stops them as needed based on scale and immediate needs. However, the administrator should be aware of them and their roles to assist in debugging issues. +CloudStack uses several types of system virtual machines to perform tasks in +the cloud. In general CloudStack manages these system VMs and creates, starts, +and stops them as needed based on scale and immediate needs. However, the +administrator should be aware of them and their roles to assist in debugging +issues. + +You can configure the system.vm.random.password parameter to create a random +system VM password to ensure higher security. If you reset the value for +system.vm.random.password to true and restart the Management Server, a random +password is generated and stored encrypted in the database. You can view the +decrypted password under the system.vm.password global parameter on the +CloudStack UI or by calling the listConfigurations API. -You can configure the system.vm.random.password parameter to create a random system VM password to ensure higher security. If you reset the value for system.vm.random.password to true and restart the Management Server, a random password is generated and stored encrypted in the database. You can view the decrypted password under the system.vm.password global parameter on the CloudStack UI or by calling the listConfigurations API. The System VM Template -______________________ +---------------------- + +The System VMs come from a single template. The System VM has the following +characteristics: + +- Debian 6.0 ("Squeeze"), 2.6.32 kernel with the latest security patches from + the Debian security APT repository + +- Has a minimal set of packages installed thereby reducing the attack surface + +- 32-bit for enhanced performance on Xen/VMWare -The System VMs come from a single template. The System VM has the following characteristics: +- pvops kernel with Xen PV drivers, KVM virtio drivers, and VMware tools for + optimum performance on all hypervisors + +- Xen tools inclusion allows performance monitoring + +- Latest versions of HAProxy, iptables, IPsec, and Apache from debian + repository ensures improved security and speed + +- Latest version of JRE from Sun/Oracle ensures improved security and speed -* Debian 6.0 ("Squeeze"), 2.6.32 kernel with the latest security patches from the Debian security APT repository -* Has a minimal set of packages installed thereby reducing the attack surface -* 32-bit for enhanced performance on Xen/VMWare -* pvops kernel with Xen PV drivers, KVM virtio drivers, and VMware tools for optimum performance on all hypervisors -* Xen tools inclusion allows performance monitoring -* Latest versions of HAProxy, iptables, IPsec, and Apache from debian repository ensures improved security and speed -* Latest version of JRE from Sun/Oracle ensures improved security and speed Accessing System VMs -____________________ +-------------------- -It may sometimes be necessary to access System VMs for diagnostics of certain issues, for example if you are experiencing SSVM (Secondary Storage VM) connection issues. Use the steps below in order to connect to the SSH console of a running System VM. +It may sometimes be necessary to access System VMs for diagnostics of certain +issues, for example if you are experiencing SSVM (Secondary Storage VM) +connection issues. Use the steps below in order to connect to the SSH console +of a running System VM. + +Accessing System VMs over the network requires the use of private keys and +connecting to System VMs SSH Daemon on port 3922. XenServer/KVM Hypervisors +store this key at /root/.ssh/id_rsa.cloud on each CloudStack agent. To access +System VMs running on ESXi, the key is stored on the management server at +/var/lib/cloudstack/management/.ssh/id_rsa. -Accessing System VMs over the network requires the use of private keys and connecting to System VMs SSH Daemon on port 3922. XenServer/KVM Hypervisors store this key at /root/.ssh/id_rsa.cloud on each CloudStack agent. To access System VMs running on ESXi, the key is stored on the management server at /var/lib/cloudstack/management/.ssh/id_rsa. #. Find the details of the System VM + #. Log in with admin privileges to the CloudStack UI. - #. Click Infrastructure, then System VMs, and then click the name of a running VM. - #. Take a note of the 'Host', 'Private IP Address' and 'Link Local IP Address' of the System VM you wish to access. + + #. Click Infrastructure, then System VMs, and then click the name of a + running VM. + + #. Take a note of the 'Host', 'Private IP Address' and 'Link Local IP + Address' of the System VM you wish to access. + #. XenServer/KVM Hypervisors + #. Connect to the Host of which the System VM is running. - #. SSH to the 'Link Local IP Address' of the System VM from the Host on which the VM is running. + + #. SSH to the 'Link Local IP Address' of the System VM from the Host on + which the VM is running. + Format: ssh -i -p 3922 + Example: root@faith:~# ssh -i /root/.ssh/id_rsa.cloud 169.254.3.93 -p 3922 + #. ESXi Hypervisors + #. Connect to your CloudStack Management Server. + #. ESXi users should SSH to the private IP address of the System VM. + Format: ssh -i -p 3922 + Example: root@management:~# ssh -i /var/lib/cloudstack/management/.ssh/id_rsa 172.16.0.250 -p 3922 + Multiple System VM Support for VMware -______________________________________ +------------------------------------- + +Every CloudStack zone has single System VM for template processing tasks such +as downloading templates, uploading templates, and uploading ISOs. In a zone +where VMware is being used, additional System VMs can be launched to process +VMware-specific tasks such as taking snapshots and creating private templates. +The CloudStack management server launches additional System VMs for +VMware-specific tasks as the load increases. The management server monitors +and weights all commands sent to these System VMs and performs dynamic load +balancing and scaling-up of more System VMs. -Every CloudStack zone has single System VM for template processing tasks such as downloading templates, uploading templates, and uploading ISOs. In a zone where VMware is being used, additional System VMs can be launched to process VMware-specific tasks such as taking snapshots and creating private templates. The CloudStack management server launches additional System VMs for VMware-specific tasks as the load increases. The management server monitors and weights all commands sent to these System VMs and performs dynamic load balancing and scaling-up of more System VMs. Console Proxy -_____________ +------------- -The Console Proxy is a type of System Virtual Machine that has a role in presenting a console view via the web UI. It connects the user’s browser to the VNC port made available via the hypervisor for the console of the guest. Both the administrator and end user web UIs offer a console connection. +The Console Proxy is a type of System Virtual Machine that has a role in +presenting a console view via the web UI. It connects the user’s browser to +the VNC port made available via the hypervisor for the console of the guest. +Both the administrator and end user web UIs offer a console connection. -Clicking a console icon brings up a new window. The AJAX code downloaded into that window refers to the public IP address of a console proxy VM. There is exactly one public IP address allocated per console proxy VM. The AJAX application connects to this IP. The console proxy then proxies the connection to the VNC port for the requested VM on the Host hosting the guest. +Clicking a console icon brings up a new window. The AJAX code downloaded into +that window refers to the public IP address of a console proxy VM. There is +exactly one public IP address allocated per console proxy VM. The AJAX +application connects to this IP. The console proxy then proxies the connection +to the VNC port for the requested VM on the Host hosting the guest. -The console proxy VM will periodically report its active session count to the Management Server. The default reporting interval is five seconds. This can be changed through standard Management Server configuration with the parameter consoleproxy.loadscan.interval. +The console proxy VM will periodically report its active session count to the +Management Server. The default reporting interval is five seconds. This can be +changed through standard Management Server configuration with the parameter +consoleproxy.loadscan.interval. -Assignment of guest VM to console proxy is determined by first determining if the guest VM has a previous session associated with a console proxy. If it does, the Management Server will assign the guest VM to the target Console Proxy VM regardless of the load on the proxy VM. Failing that, the first available running Console Proxy VM that has the capacity to handle new sessions is used. +Assignment of guest VM to console proxy is determined by first determining if +the guest VM has a previous session associated with a console proxy. If it +does, the Management Server will assign the guest VM to the target Console +Proxy VM regardless of the load on the proxy VM. Failing that, the first +available running Console Proxy VM that has the capacity to handle new +sessions is used. + +Console proxies can be restarted by administrators but this will interrupt +existing console sessions for users. -Console proxies can be restarted by administrators but this will interrupt existing console sessions for users. Using a SSL Certificate for the Console Proxy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The console viewing functionality uses a dynamic DNS service under the domain name realhostip.com to assist in providing SSL security to console sessions. The console proxy is assigned a public IP address. In order to avoid browser warnings for mismatched SSL certificates, the URL for the new console window is set to the form of https://aaa-bbb-ccc-ddd.realhostip.com. You will see this URL during console session creation. CloudStack includes the realhostip.com SSL certificate in the console proxy VM. Of course, CloudStack cannot know about the DNS A records for our customers' public IPs prior to shipping the software. CloudStack therefore runs a dynamic DNS server that is authoritative for the realhostip.com domain. It maps the aaa-bbb-ccc-ddd part of the DNS name to the IP address aaa.bbb.ccc.ddd on lookups. This allows the browser to correctly connect to the console proxy's public IP, where it then expects and receives a SSL certificate for realhostip.com, and SSL is set up without browser warnings. +The console viewing functionality uses a dynamic DNS service under the domain +name realhostip.com to assist in providing SSL security to console sessions. +The console proxy is assigned a public IP address. In order to avoid browser +warnings for mismatched SSL certificates, the URL for the new console window +is set to the form of https://aaa-bbb-ccc-ddd.realhostip.com. You will see +this URL during console session creation. CloudStack includes the +realhostip.com SSL certificate in the console proxy VM. Of course, CloudStack +cannot know about the DNS A records for our customers' public IPs prior to +shipping the software. CloudStack therefore runs a dynamic DNS server that is +authoritative for the realhostip.com domain. It maps the aaa-bbb-ccc-ddd part +of the DNS name to the IP address aaa.bbb.ccc.ddd on lookups. This allows the +browser to correctly connect to the console proxy's public IP, where it then +expects and receives a SSL certificate for realhostip.com, and SSL is set up +without browser warnings. + Changing the Console Proxy SSL Certificate and Domain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the administrator prefers, it is possible for the URL of the customer's console session to show a domain other than realhostip.com. The administrator can customize the displayed domain by selecting a different domain and uploading a new SSL certificate and private key. The domain must run a DNS service that is capable of resolving queries for addresses of the form aaa-bbb-ccc-ddd.your.domain to an IPv4 IP address in the form aaa.bbb.ccc.ddd, for example, 202.8.44.1. To change the console proxy domain, SSL certificate, and private key: +If the administrator prefers, it is possible for the URL of the customer's +console session to show a domain other than realhostip.com. The administrator +can customize the displayed domain by selecting a different domain and +uploading a new SSL certificate and private key. The domain must run a DNS +service that is capable of resolving queries for addresses of the form +aaa-bbb-ccc-ddd.your.domain to an IPv4 IP address in the form aaa.bbb.ccc.ddd, +for example, 202.8.44.1. To change the console proxy domain, SSL certificate, +and private key: + +#. Set up dynamic name resolution or populate all possible DNS names in your + public IP range into your existing DNS server with the format + aaa-bbb-ccc-ddd.company.com -> aaa.bbb.ccc.ddd. + +#. Generate the private key and certificate signing request (CSR). When you + are using openssl to generate private/public key pairs and CSRs, for the + private key that you are going to paste into the CloudStack UI, be sure to + convert it into PKCS#8 format. + + #. Generate a new 2048-bit private key + + :: + + openssl genrsa -des3 -out yourprivate.key 2048 + + #. Generate a new certificate CSR -#. Set up dynamic name resolution or populate all possible DNS names in your public IP range into your existing DNS server with the format aaa-bbb-ccc-ddd.company.com -> aaa.bbb.ccc.ddd. -#. Generate the private key and certificate signing request (CSR). When you are using openssl to generate private/public key pairs and CSRs, for the private key that you are going to paste into the CloudStack UI, be sure to convert it into PKCS#8 format. + :: + + openssl req -new -key yourprivate.key -out yourcertificate.csr + + #. Head to the website of your favorite trusted Certificate Authority, + purchase an SSL certificate, and submit the CSR. You should receive a + valid certificate in return - 1. Generate a new 2048-bit private key:: + #. Convert your private key format into PKCS#8 encrypted format. - openssl genrsa -des3 -out yourprivate.key 2048 + :: - 2. Generate a new certificate CSR:: + openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encrypted.key - openssl req -new -key yourprivate.key -out yourcertificate.csr + #. Convert your PKCS#8 encrypted private key into the PKCS#8 format that is + compliant with CloudStack - 3. Head to the website of your favorite trusted Certificate Authority, purchase an SSL certificate, and submit the CSR. You should receive a valid certificate in return - 4. Convert your private key format into PKCS#8 encrypted format.:: + :: - openssl pkcs8 -topk8 -in yourprivate.key -out yourprivate.pkcs8.encrypted.key + openssl pkcs8 -in yourprivate.pkcs8.encrypted.key -out yourprivate.pkcs8.key - 5. Convert your PKCS#8 encrypted private key into the PKCS#8 format that is compliant with CloudStack:: +#. In the Update SSL Certificate screen of the CloudStack UI, paste the following: - openssl pkcs8 -in yourprivate.pkcs8.encrypted.key -out yourprivate.pkcs8.key + - The certificate you've just generated. + + - The private key you've just generated. + + - The desired new domain name; for example, company.com -3. In the Update SSL Certificate screen of the CloudStack UI, paste the following: - *. The certificate you've just generated. - *. The private key you've just generated. - *. The desired new domain name; for example, company.com +#. The desired new domain name; for example, company.com + This stops all currently running console proxy VMs, then restarts them with + the new certificate and key. Users might notice a brief interruption in + console availability. -4. The desired new domain name; for example, company.com -This stops all currently running console proxy VMs, then restarts them with the new certificate and key. Users might notice a brief interruption in console availability. +The Management Server generates URLs of the form "aaa-bbb-ccc-ddd.company.com" +after this change is made. The new console requests will be served with the +new DNS domain name, certificate, and key. -The Management Server generates URLs of the form "aaa-bbb-ccc-ddd.company.com" after this change is made. The new console requests will be served with the new DNS domain name, certificate, and key. Virtual Router -_______________ +-------------- -The virtual router is a type of System Virtual Machine. The virtual router is one of the most frequently used service providers in CloudStack. The end user has no direct access to the virtual router. Users can ping the virtual router and take actions that affect it (such as setting up port forwarding), but users do not have SSH access into the virtual router. +The virtual router is a type of System Virtual Machine. The virtual router is +one of the most frequently used service providers in CloudStack. The end user +has no direct access to the virtual router. Users can ping the virtual router +and take actions that affect it (such as setting up port forwarding), but +users do not have SSH access into the virtual router. + +Virtual routers can be restarted by administrators, but this will interrupt +public network access and other services for end users. A basic test in +debugging networking issues is to attempt to ping the virtual router from a +guest VM. Some of the characteristics of the virtual router are determined by +its associated system service offering.. -Virtual routers can be restarted by administrators, but this will interrupt public network access and other services for end users. A basic test in debugging networking issues is to attempt to ping the virtual router from a guest VM. Some of the characteristics of the virtual router are determined by its associated system service offering.. Configuring the Virtual Router ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can set the following: -*. IP range -*. Supported network services -*. Default domain name for the network serviced by the virtual router -*. Gateway IP address -*. How often CloudStack fetches network usage statistics from CloudStack virtual routers. If you want to collect traffic metering data from the virtual router, set the global configuration parameter router.stats.interval. If you are not using the virtual router to gather network usage statistics, set it to 0. + +- IP range + +- Supported network services + +- Default domain name for the network serviced by the virtual router + +- Gateway IP address + +- How often CloudStack fetches network usage statistics from CloudStack + virtual routers. If you want to collect traffic metering data from the + virtual router, set the global configuration parameter + router.stats.interval. If you are not using the virtual router to gather + network usage statistics, set it to 0. + Upgrading a Virtual Router with System Service Offerings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When CloudStack creates a virtual router, it uses default settings which are defined in a default system service offering. See Section 8.2, “System Service Offerings”. All the virtual routers in a single guest network use the same system service offering. You can upgrade the capabilities of the virtual router by creating and applying a custom system service offering. -Define your custom system service offering. +When CloudStack creates a virtual router, it uses default settings which are +defined in a default system service offering. See Section 8.2, “System Service +Offerings”. All the virtual routers in a single guest network use the same +system service offering. You can upgrade the capabilities of the virtual +router by creating and applying a custom system service offering. +Define your custom system service offering. + Associate the system service offering with a network offering. -Apply the network offering to the network where you want the virtual routers to use the new system service offering. +Apply the network offering to the network where you want the virtual routers +to use the new system service offering. + Best Practices for Virtual Routers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Restarting a virtual router from a hypervisor console deletes all the iptables rules. To work around this issue, stop the virtual router and start it from the CloudStack UI. -* Do not use the destroyRouter API when only one router is available in the network, because restartNetwork API with the cleanup=false parameter can't recreate it later. If you want to destroy and recreate the single router available in the network, use the restartNetwork API with the cleanup=true parameter. +- Restarting a virtual router from a hypervisor console deletes all the + iptables rules. To work around this issue, stop the virtual router and + start it from the CloudStack UI. + +- Do not use the destroyRouter API when only one router is available in the + network, because restartNetwork API with the cleanup=false parameter can't + recreate it later. If you want to destroy and recreate the single router + available in the network, use the restartNetwork API with the cleanup=true + parameter. + Secondary Storage VM -_____________________ +-------------------- -In addition to the hosts, CloudStack’s Secondary Storage VM mounts and writes to secondary storage. -Submissions to secondary storage go through the Secondary Storage VM. The Secondary Storage VM can retrieve templates and ISO images from URLs using a variety of protocols. -The secondary storage VM provides a background task that takes care of a variety of secondary storage activities: downloading a new template to a Zone, copying templates between Zones, and snapshot backups. -The administrator can log in to the secondary storage VM if needed. +In addition to the hosts, CloudStack’s Secondary Storage VM mounts and writes +to secondary storage. Submissions to secondary storage go through the +Secondary Storage VM. The Secondary Storage VM can retrieve templates and ISO +images from URLs using a variety of protocols. The secondary storage VM +provides a background task that takes care of a variety of secondary storage +activities: downloading a new template to a Zone, copying templates between +Zones, and snapshot backups. The administrator can log in to the secondary +storage VM if needed. Storage Administration ---------------------- + Hypervisor Host Management -------------------------- + Maintenance mode -________________ +---------------- + +Maintenance mode makes a host unavailable to have new virtual machines +allocated to it. It also starts a process by which running virtual machines +are live migrated to other available hosts within the same cluster. It should +be noted that the live migration is not universally perfect, and you may end +up with recalcitrant virtual machines which are unable to be live migrated. +This can be due to lack of hypervisor-specific tooling or other problems. -Maintenance mode makes a host unavailable to have new virtual machines allocated to it. It also starts a process by which running virtual machines are live migrated to other available hosts within the same cluster. It should be noted that the live migration is not universally perfect, and you may end up with recalcitrant virtual machines which are unable to be live migrated. This can be due to lack of hypervisor-specific tooling or other problems. vCenter and Maintenance mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To enter maintenance mode on a vCenter host, both vCenter and CloudStack must be used in concert. CloudStack and vCenter have separate maintenance modes that work closely together. +To enter maintenance mode on a vCenter host, both vCenter and CloudStack must +be used in concert. CloudStack and vCenter have separate maintenance modes +that work closely together. + +#. Place the host into CloudStack's "scheduled maintenance" mode. This does + not invoke the vCenter maintenance mode, but only causes VMs to be migrated + off the host When the CloudStack maintenance mode is requested, the host + first moves into the Prepare for Maintenance state. In this state it cannot + be the target of new guest VM starts. Then all VMs will be migrated off the + server. Live migration will be used to move VMs off the host. This allows + the guests to be migrated to other hosts with no disruption to the guests. + After this migration is completed, the host will enter the Ready for + Maintenance mode. -#. Place the host into CloudStack's "scheduled maintenance" mode. This does not invoke the vCenter maintenance mode, but only causes VMs to be migrated off the host When the CloudStack maintenance mode is requested, the host first moves into the Prepare for Maintenance state. In this state it cannot be the target of new guest VM starts. Then all VMs will be migrated off the server. Live migration will be used to move VMs off the host. This allows the guests to be migrated to other hosts with no disruption to the guests. After this migration is completed, the host will enter the Ready for Maintenance mode. #. Wait for the "Ready for Maintenance" indicator to appear in the UI. -#. Now use vCenter to perform whatever actions are necessary to maintain the host. During this time, the host cannot be the target of new VM allocations. -#. When the maintenance tasks are complete, take the host out of maintenance mode as follows: - a. First use vCenter to exit the vCenter maintenance mode. This makes the host ready for CloudStack to reactivate it. - b. Then use CloudStack's administrator UI to cancel the CloudStack maintenance mode When the host comes back online, the VMs that were migrated off of it may be migrated back to it manually and new VMs can be added. + +#. Now use vCenter to perform whatever actions are necessary to maintain the + host. During this time, the host cannot be the target of new VM allocations. + +#. When the maintenance tasks are complete, take the host out of maintenance + mode as follows: + + #. First use vCenter to exit the vCenter maintenance mode. This makes the + host ready for CloudStack to reactivate it. + + #. Then use CloudStack's administrator UI to cancel the CloudStack + maintenance mode When the host comes back online, the VMs that were + migrated off of it may be migrated back to it manually and new VMs can + be added. + XenServer Maintenance Mode ~~~~~~~~~~~~~~~~~~~~~~~~~~ -XenServer, you can take a server offline temporarily by using the Maintenance Mode feature in XenCenter. When you place a server into Maintenance Mode, all running VMs are automatically migrated from it to another host in the same pool. If the server is the pool master, a new master will also be selected for the pool. While a server is Maintenance Mode, you cannot create or start any VMs on it. +XenServer, you can take a server offline temporarily by using the Maintenance +Mode feature in XenCenter. When you place a server into Maintenance Mode, all +running VMs are automatically migrated from it to another host in the same +pool. If the server is the pool master, a new master will also be selected for +the pool. While a server is Maintenance Mode, you cannot create or start any +VMs on it. + To place a XenServer host in Maintenace Mode -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. In the Resources pane, select the server, then do one of the following: - *. Right-click, then click Enter Maintenance Mode on the shortcut menu. - *. On the Server menu, click Enter Maintenance Mode. + + - Right-click, then click Enter Maintenance Mode on the shortcut menu. + + - On the Server menu, click Enter Maintenance Mode. + #. Click Enter Maintenance Mode. -The server's status in the Resources pane shows when all running VMs have been successfully migrated off the server. +The server's status in the Resources pane shows when all running VMs have been +successfully migrated off the server. + To take a Xenserver host out of Maintenance mode -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. In the Resources pane, select the server, then do one of the following: - *Right-click, then click Exit Maintenance Mode on the shortcut menu. - *On the Server menu, click Exit Maintenance Mode. + + - Right-click, then click Exit Maintenance Mode on the shortcut menu. + + - On the Server menu, click Exit Maintenance Mode. + #. Click Exit Maintenance Mode. + Disabling and enabling Zones, Pods, and Clusters -________________________________________________ +------------------------------------------------ + +You can enable or disable a zone, pod, or cluster without permanently removing +it from the cloud. This is useful for maintenance or when there are problems +that make a portion of the cloud infrastructure unreliable. No new allocations +will be made to a disabled zone, pod, or cluster until its state is returned +to Enabled. When a zone, pod, or cluster is first added to the cloud, it is +Disabled by default. -You can enable or disable a zone, pod, or cluster without permanently removing it from the cloud. This is useful for maintenance or when there are problems that make a portion of the cloud infrastructure unreliable. No new allocations will be made to a disabled zone, pod, or cluster until its state is returned to Enabled. When a zone, pod, or cluster is first added to the cloud, it is Disabled by default. To disable and enable a zone, pod, or cluster: #. Log in to the CloudStack UI as administrator + #. In the left navigation bar, click Infrastructure. + #. In Zones, click View More. -#. If you are disabling or enabling a zone, find the name of the zone in the list, and click the Enable/Disable button. -#. If you are disabling or enabling a pod or cluster, click the name of the zone that contains the pod or cluster. + +#. If you are disabling or enabling a zone, find the name of the zone in the + list, and click the Enable/Disable button. + +#. If you are disabling or enabling a pod or cluster, click the name of the + zone that contains the pod or cluster. + #. Click the Compute tab. + #. In the Pods or Clusters node of the diagram, click View All. + #. Click the pod or cluster name in the list. + #. Click the Enable/Disable button. + Removing hypervisor hosts -_________________________ +------------------------- + +Hosts can be removed from the cloud as needed. The procedure to remove a host +depends on the hypervisor type. -Hosts can be removed from the cloud as needed. The procedure to remove a host depends on the hypervisor type. Removing XenServer and KVM Hosts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A node cannot be removed from a cluster until it has been placed in maintenance mode. This will ensure that all of the VMs on it have been migrated to other Hosts. To remove a Host from CloudStack: +A node cannot be removed from a cluster until it has been placed in +maintenance mode. This will ensure that all of the VMs on it have been +migrated to other Hosts. To remove a Host from CloudStack: #. Place the node in maintenance mode. + #. For KVM, stop the cloud-agent service. + #. Use the UI option to remove the node. + #. Then you may power down the Host, re-use its IP address, re-install it, etc + Removing vSphere Hosts ~~~~~~~~~~~~~~~~~~~~~~ -To remove this type of host, first place it in maintenance mode, as described above. Then use CloudStack to remove the host. CloudStack will not direct commands to a host that has been removed using CloudStack. However, the host may still exist in the vCenter cluster. +To remove this type of host, first place it in maintenance mode, as described +above. Then use CloudStack to remove the host. CloudStack will not direct +commands to a host that has been removed using CloudStack. However, the host +may still exist in the vCenter cluster. + Changing hypervisor host password -_________________________________ -The password for a XenServer Node, KVM Node, or vSphere Node may be changed in the database. Note that all Nodes in a Cluster must have the same password. +--------------------------------- +The password for a XenServer Node, KVM Node, or vSphere Node may be changed in +the database. Note that all Nodes in a Cluster must have the same password. + To change a hosts password: #. Identify all hosts in the cluster. -#. Change the password on all hosts in the cluster. Now the password for the host and the password known to CloudStack will not match. Operations on the cluster will fail until the two passwords match. -#. Get the list of host IDs for the host in the cluster where you are changing the password. You will need to access the database to determine these host IDs. For each hostname "h" (or vSphere cluster) that you are changing the password for, execute: :: + +#. Change the password on all hosts in the cluster. Now the password for the + host and the password known to CloudStack will not match. Operations on the + cluster will fail until the two passwords match. + +#. Get the list of host IDs for the host in the cluster where you are changing + the password. You will need to access the database to determine these host + IDs. For each hostname "h" (or vSphere cluster) that you are changing the + password for, execute: + + :: - mysql> select id from cloud.host where name like '%h%'; + mysql> select id from cloud.host where name like '%h%'; + +#. Update the passwords for the host in the database. In this example, we + change the passwords for hosts with IDs 5, 10, and 12 to "password". + + :: -4. Update the passwords for the host in the database. In this example, we change the passwords for hosts with IDs 5, 10, and 12 to "password".:: + mysql> update cloud.host set password='password' where id=5 or id=10 or id=12; - mysql> update cloud.host set password='password' where id=5 or id=10 or id=12; Overprovisioning and Service Offering Limits -____________________________________________ +-------------------------------------------- -CPU and memory (RAM) over-provisioning factors can be set for each cluster to change the number of VMs that can run on each host in the cluster. This helps optimize the use of resources. By increasing the over-provisioning ratio, more resource capacity will be used. If the ratio is set to 1, no over-provisioning is done. +CPU and memory (RAM) over-provisioning factors can be set for each cluster to +change the number of VMs that can run on each host in the cluster. This helps +optimize the use of resources. By increasing the over-provisioning ratio, more +resource capacity will be used. If the ratio is set to 1, no over-provisioning +is done. -The administrator can also set global default over-provisioning ratios in the cpu.overprovisioning.factor and mem.overprovisioning.factor global configuration variables. The default value of these variables is 1: over-provisioning is turned off by default. -Over-provisioning ratios are dynamically substituted in CloudStack's capacity calculations. For example::: +The administrator can also set global default over-provisioning ratios in the +cpu.overprovisioning.factor and mem.overprovisioning.factor global +configuration variables. The default value of these variables is 1: +over-provisioning is turned off by default. +Over-provisioning ratios are dynamically substituted in CloudStack's capacity +calculations. For example: + +:: Capacity = 2 GB Over-provisioning factor = 2 @@ -364,80 +723,147 @@ Over-provisioning ratios are dynamically substituted in CloudStack's capacity ca Used = 3 GB Free = 1 GB -The administrator can specify a memory over-provisioning ratio, and can specify both CPU and memory over-provisioning ratios on a per-cluster basis. -In any given cloud, the optimum number of VMs for each host is affected by such things as the hypervisor, storage, and hardware configuration. These may be different for each cluster in the same cloud. A single global over-provisioning setting can not provide the best utilization for all the different clusters in the cloud. It has to be set for the lowest common denominator. The per-cluster setting provides a finer granularity for better utilization of resources, no matter where the CloudStack placement algorithm decides to place a VM. +The administrator can specify a memory over-provisioning ratio, and can +specify both CPU and memory over-provisioning ratios on a per-cluster basis. + +In any given cloud, the optimum number of VMs for each host is affected by +such things as the hypervisor, storage, and hardware configuration. These may +be different for each cluster in the same cloud. A single global +over-provisioning setting can not provide the best utilization for all the +different clusters in the cloud. It has to be set for the lowest common +denominator. The per-cluster setting provides a finer granularity for better +utilization of resources, no matter where the CloudStack placement algorithm +decides to place a VM. -The overprovisioning settings can be used along with dedicated resources (assigning a specific cluster to an account) to effectively offer different levels of service to different accounts. For example, an account paying for a more expensive level of service could be assigned to a dedicated cluster with an over-provisioning ratio of 1, and a lower-paying account to a cluster with a ratio of 2. +The overprovisioning settings can be used along with dedicated resources +(assigning a specific cluster to an account) to effectively offer different +levels of service to different accounts. For example, an account paying for a +more expensive level of service could be assigned to a dedicated cluster with +an over-provisioning ratio of 1, and a lower-paying account to a cluster with +a ratio of 2. + +When a new host is added to a cluster, CloudStack will assume the host has the +capability to perform the CPU and RAM over-provisioning which is configured +for that cluster. It is up to the administrator to be sure the host is +actually suitable for the level of over-provisioning which has been set. -When a new host is added to a cluster, CloudStack will assume the host has the capability to perform the CPU and RAM over-provisioning which is configured for that cluster. It is up to the administrator to be sure the host is actually suitable for the level of over-provisioning which has been set. Limitations on over-provisioning in KVM and XenServer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In XenServer, due to a constraint of this hypervisor, you can not use an over-provisioning factor greater than 4. +In XenServer, due to a constraint of this hypervisor, you can not use an +over-provisioning factor greater than 4. + +KVM can not manage memory allocation to VMs dynamically. CloudStack sets the +minimum and maximum amount of memory that a VM can use. The hypervisor adjusts +the memory within the set limits based on the memory contention. -KVM can not manage memory allocation to VMs dynamically. CloudStack sets the minimum and maximum amount of memory that a VM can use. The hypervisor adjusts the memory within the set limits based on the memory contention. Requirements for Over-Provisioning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Several prerequisites are required in order for over-provisioning to function properly. The feature is dependent on the OS type, hypervisor capabilities, and certain scripts. It is the administrator's responsibility to ensure that these requirements are met. +Several prerequisites are required in order for over-provisioning to function +properly. The feature is dependent on the OS type, hypervisor capabilities, +and certain scripts. It is the administrator's responsibility to ensure that +these requirements are met. + Balloon Driver -@@@@@@@@@@@@@@ +^^^^^^^^^^^^^^ + +All VMs should have a balloon driver installed in them. The hypervisor +communicates with the balloon driver to free up and make the memory available +to a VM. -All VMs should have a balloon driver installed in them. The hypervisor communicates with the balloon driver to free up and make the memory available to a VM. XenServer -######### +''''''''' + +The balloon driver can be found as a part of xen pv or PVHVM drivers. The xen +pvhvm drivers are included in upstream linux kernels 2.6.36+. -The balloon driver can be found as a part of xen pv or PVHVM drivers. The xen pvhvm drivers are included in upstream linux kernels 2.6.36+. VMware -###### +'''''' + +The balloon driver can be found as a part of the VMware tools. All the VMs +that are deployed in a over-provisioned cluster should have the VMware tools +installed. -The balloon driver can be found as a part of the VMware tools. All the VMs that are deployed in a over-provisioned cluster should have the VMware tools installed. KVM -#### +''' + +All VMs are required to support the virtio drivers. These drivers are +installed in all Linux kernel versions 2.6.25 and greater. The administrator +must set CONFIG_VIRTIO_BALLOON=y in the virtio configuration. -All VMs are required to support the virtio drivers. These drivers are installed in all Linux kernel versions 2.6.25 and greater. The administrator must set CONFIG_VIRTIO_BALLOON=y in the virtio configuration. Hypervisor capabilities -@@@@@@@@@@@@@@@@@@@@@@@ +^^^^^^^^^^^^^^^^^^^^^^^ The hypervisor must be capable of using the memory ballooning. + XenServer -######### +''''''''' + +The DMC (Dynamic Memory Control) capability of the hypervisor should be +enabled. Only XenServer Advanced and above versions have this feature. -The DMC (Dynamic Memory Control) capability of the hypervisor should be enabled. Only XenServer Advanced and above versions have this feature. VMware, KVM -########### +''''''''''' Memory ballooning is supported by default. + Setting Over-Provisioning Rations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are two ways the root admin can set CPU and RAM over-provisioning ratios. First, the global configuration settings cpu.overprovisioning.factor and mem.overprovisioning.factor will be applied when a new cluster is created. Later, the ratios can be modified for an existing cluster. +There are two ways the root admin can set CPU and RAM over-provisioning ratios. +First, the global configuration settings cpu.overprovisioning.factor and +mem.overprovisioning.factor will be applied when a new cluster is created. +Later, the ratios can be modified for an existing cluster. -Only VMs deployed after the change are affected by the new setting. If you want VMs deployed before the change to adopt the new over-provisioning ratio, you must stop and restart the VMs. When this is done, CloudStack recalculates or scales the used and reserved capacities based on the new over-provisioning ratios, to ensure that CloudStack is correctly tracking the amount of free capacity. +Only VMs deployed after the change are affected by the new setting. If you +want VMs deployed before the change to adopt the new over-provisioning ratio, +you must stop and restart the VMs. When this is done, CloudStack recalculates +or scales the used and reserved capacities based on the new over-provisioning +ratios, to ensure that CloudStack is correctly tracking the amount of free +capacity. To change the over-provisioning ratios for an existing cluster: #. Log in as administrator to the CloudStack UI. + #. In the left navigation bar, click Infrastructure. + #. Under Clusters, click View All. -#. Select the cluster you want to work with, and click the Edit button. -#. Fill in your desired over-provisioning multipliers in the fields CPU overcommit ratio and RAM overcommit ratio. The value which is intially shown in these fields is the default value inherited from the global configuration settings. -Service Offering Limits and Over-Provisioning -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#. Select the cluster you want to work with, and click the Edit button. -Service offering limits (e.g. 1 GHz, 1 core) are strictly enforced for core count. For example, a guest with a service offering of one core will have only one core available to it regardless of other activity on the Host. +#. Fill in your desired over-provisioning multipliers in the fields CPU + overcommit ratio and RAM overcommit ratio. The value which is intially + shown in these fields is the default value inherited from the global + configuration settings. -Service offering limits for gigahertz are enforced only in the presence of contention for CPU resources. For example, suppose that a guest was created with a service offering of 1 GHz on a Host that has 2 GHz cores, and that guest is the only guest running on the Host. The guest will have the full 2 GHz available to it. When multiple guests are attempting to use the CPU a weighting factor is used to schedule CPU resources. The weight is based on the clock speed in the service offering. Guests receive a CPU allocation that is proportionate to the GHz in the service offering. For example, a guest created from a 2 GHz service offering will receive twice the CPU allocation as a guest created from a 1 GHz service offering. CloudStack does not perform memory over-provisioning. +Service Offering Limits and Over-Provisioning +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Service offering limits (e.g. 1 GHz, 1 core) are strictly enforced for core +count. For example, a guest with a service offering of one core will have only +one core available to it regardless of other activity on the Host. + +Service offering limits for gigahertz are enforced only in the presence of +contention for CPU resources. For example, suppose that a guest was created +with a service offering of 1 GHz on a Host that has 2 GHz cores, and that +guest is the only guest running on the Host. The guest will have the full +2 GHz available to it. When multiple guests are attempting to use the CPU a +weighting factor is used to schedule CPU resources. The weight is based on the +clock speed in the service offering. Guests receive a CPU allocation that is +proportionate to the GHz in the service offering. For example, a guest created +from a 2 GHz service offering will receive twice the CPU allocation as a guest +created from a 1 GHz service offering. CloudStack does not perform memory +over-provisioning. diff --git a/rtd/source/alloc.rst b/rtd/source/alloc.rst index f5fd1bf..00ce8c9 100644 --- a/rtd/source/alloc.rst +++ b/rtd/source/alloc.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Allocators ========== @@ -14,12 +30,14 @@ These are following categories of allocators currently supported: determine which storage pool to allocate the guest virtual machines on. + Implementing a custom HostAllocator ----------------------------------- HostAllocators are written by extending com.cloud.agent.manager.allocator.HostAllocator interface. + HostAllocator Interface ~~~~~~~~~~~~~~~~~~~~~~~ @@ -27,32 +45,32 @@ The interface defines the following two methods. :: - /** - * Checks if the VM can be upgraded to the specified ServiceOffering - * @param UserVm vm - * @param ServiceOffering offering - * @return boolean true if the VM can be upgraded - **/ - - publicboolean isVirtualMachineUpgradable(final UserVm vm, final ServiceOffering offering); - - /** - * Determines which physical hosts are suitable to allocate the guest virtual machines on - * - * @paramVirtualMachineProfile vmProfile - * @paramDeploymentPlan plan - * @paramType type - * @paramExcludeList avoid - * @paramint returnUpTo - * @returnListList of hosts that are suitable for VM allocation - **/ - - publicList allocateTo( VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, intreturnUpTo); - + /** + * Checks if the VM can be upgraded to the specified ServiceOffering + * @param UserVm vm + * @param ServiceOffering offering + * @return boolean true if the VM can be upgraded + **/ + + publicboolean isVirtualMachineUpgradable(final UserVm vm, final ServiceOffering offering); + + /** + * Determines which physical hosts are suitable to allocate the guest virtual machines on + * + * @paramVirtualMachineProfile vmProfile + * @paramDeploymentPlan plan + * @paramType type + * @paramExcludeList avoid + * @paramint returnUpTo + * @returnListList of hosts that are suitable for VM allocation + **/ + + publicList allocateTo( VirtualMachineProfile vmProfile, DeploymentPlan plan, Type type, ExcludeList avoid, intreturnUpTo); A custom HostAllocator can be written by implementing the ‘allocateTo’ method + Input Parameters for the method ‘HostAllocator :: allocateTo’ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -124,6 +142,7 @@ This specifies return up to that many available hosts for this guest VM. To get all possible hosts, set this value to -1. + Reference HostAllocator implementation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,31 +154,33 @@ given ServiceOffering requirements. If returnUpTo = 1, this allocator would return the first Host that fits the requirements of the guest VM. + Loading a custom HostAllocator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. Write a custom HostAllocator class, implementing the interface +#. Write a custom HostAllocator class, implementing the interface described above. -2. Package the code into a JAR file and make the JAR available in the +#. Package the code into a JAR file and make the JAR available in the classpath of the Management Server/tomcat. -3. Modify the components.xml and components-premium.xml files found in +#. Modify the components.xml and components-premium.xml files found in /client/ tomcatconf as follows. -4. Search for ‘HostAllocator’ in these files. +#. Search for ‘HostAllocator’ in these files. :: - - - + + + -5. Replace the FirstFitAllocator with your class name. Optionally, you +#. Replace the FirstFitAllocator with your class name. Optionally, you can change the name of the adapter as well. -6. Restart the Management Server. +#. Restart the Management Server. + Implementing a custom StoragePoolAllocator ------------------------------------------ @@ -167,6 +188,7 @@ Implementing a custom StoragePoolAllocator StoragePoolAllocators are written by extending com.cloud.storage.allocator. StoragePoolAllocator interface. + StoragePoolAllocator Interface ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -175,17 +197,17 @@ A custom StoragePoolAllocator can be written by implementing the :: - /** - * Determines which storage pools are suitable for the guest virtual machine - * @param DiskProfile dskCh - * @param VirtualMachineProfile vmProfile - * @param DeploymentPlan plan - * @param ExcludeList avoid - * @param int returnUpTo - * @return List List of storage pools that are suitable for the VM - **/ - - public List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); + /** + * Determines which storage pools are suitable for the guest virtual machine + * @param DiskProfile dskCh + * @param VirtualMachineProfile vmProfile + * @param DeploymentPlan plan + * @param ExcludeList avoid + * @param int returnUpTo + * @return List List of storage pools that are suitable for the VM + **/ + + public List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); This interface also contains some other methods to support some legacy @@ -193,6 +215,7 @@ code. However your custom allocator can extend the existing com.cloud.storage.allocator. AbstractStoragePoolAllocator. This class provides default implementation for all the other interface methods. + Input Parameters for the method ‘StoragePoolAllocator :: allocateTo’ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -253,6 +276,7 @@ This specifies return up to that many available pools for this guest VM To get all possible pools, set this value to -1 + Reference StoragePoolAllocator implementation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -264,19 +288,20 @@ considering the given DiskProfile characteristics. If returnUpTo = 1, this allocator would return the first Storage Pool that fits the requirements of the guest VM. + Loading a custom StoragePoolAllocator ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -1. Write a custom StoragePoolAllocator class, implementing the interface +#. Write a custom StoragePoolAllocator class, implementing the interface described above. -2. Package the code into a JAR file and make the JAR available in the +#. Package the code into a JAR file and make the JAR available in the classpath of the Management Server/tomcat. -3. Modify the components.xml and components-premium.xml files found in +#. Modify the components.xml and components-premium.xml files found in /client/ tomcatconf as follows. -4. Search for ‘StoragePoolAllocator’ in these files. +#. Search for ‘StoragePoolAllocator’ in these files. :: @@ -284,9 +309,7 @@ Loading a custom StoragePoolAllocator -5. Replace the FirstFitStoragePoolAllocator with your class name. +#. Replace the FirstFitStoragePoolAllocator with your class name. Optionally, you can change the name of the adapter as well. -6. Restart the Management Server. - - +#. Restart the Management Server. diff --git a/rtd/source/ansible.rst b/rtd/source/ansible.rst index 7f0f9bd..18b19fb 100644 --- a/rtd/source/ansible.rst +++ b/rtd/source/ansible.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Deploying CloudStack with Ansible ================================= @@ -5,6 +21,7 @@ In this article, `Paul Angus `__ Cloud Architect at ShapeBlue takes a look at using Ansible to Deploy an Apache CloudStack cloud.  + What is Ansible --------------- @@ -17,6 +34,7 @@ Like Chef and Puppet, Ansible is designed to be idempotent, these means that you determine the state you want a host to be in and Ansible will decide if it needs to act in order to achieve that state. + There’s already Chef and Puppet, so what’s the fuss about Ansible? ------------------------------------------------------------------ @@ -44,6 +62,7 @@ found it a bit tricky to get the syntax correct for variables in some circumstances, but otherwise I’ve found it one of the easier tools to get my head around. + So let’s see something ---------------------- @@ -51,6 +70,7 @@ For this example we’re going to create an Ansible server which will then deploy a CloudStack server. Both of these servers will be CentOS 6.4 virtual machines. + Installing Ansible ------------------ @@ -60,8 +80,8 @@ server. :: - # rpm -ivh http://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm - # yum install -y ansible + # rpm -ivh http://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm + # yum install -y ansible And that’s it. @@ -82,6 +102,7 @@ Ansible uses playbooks to specify the state in which you wish the target host to be in to be able to accomplish its role. Ansible playbooks are written in YAML format. + Modules ------- @@ -100,11 +121,15 @@ to do exactly that. The pre-requisites to this CloudStack build are: - A CentOS 6.4 host to install CloudStack on + - An IP address already assigned on the ACS management host + - The ACS management host should have a resolvable FQDN (either through DNS or the host file on the ACS management host) + - Internet connectivity on the ACS management host + Planning -------- @@ -113,11 +138,16 @@ group them or split them into logical blocks. So for this deployment of CloudStack I’d start with: - Configure selinux + - (libselinux-python required for Ansible to work with selinux enabled hosts) + - Install and configure MySQL + - (Python MySQL-DB required for Ansible MySQL module) + - Install cloud-client + - Seed secondary storage Ansible is built around the idea of hosts having roles, so generally you @@ -127,6 +157,7 @@ roles for these tasks I’ve created: - cloudstack-manager + - mysql First up we need to tell Ansible where to find our CloudStack management @@ -135,11 +166,12 @@ host. In the root Ansible directory there is a file called ‘hosts’ :: - [acs-manager] - xxx.xxx.xxx.xxx + [acs-manager] + xxx.xxx.xxx.xxx where xxx.xxx.xxx.xxx is the ip address of your ACS management host. + MySQL ----- @@ -150,59 +182,59 @@ the file will look like this: :: - -name: Ensure mysql server is installed + -name: Ensure mysql server is installed - yum: name=mysql-server state=present + yum: name=mysql-server state=present - - name: Ensure mysql python is installed + - name: Ensure mysql python is installed - yum: name=MySQL-python state=present + yum: name=MySQL-python state=present - - name: Ensure selinux python bindings are installed + - name: Ensure selinux python bindings are installed - yum: name=libselinux-python state=present + yum: name=libselinux-python state=present - - name: Ensure cloudstack specfic my.cnf lines are present + - name: Ensure cloudstack specfic my.cnf lines are present - lineinfile: dest=/etc/my.cnf regexp=’$item’ insertafter=”symbolic-links=0″ line=’$item’ + lineinfile: dest=/etc/my.cnf regexp=’$item’ insertafter=”symbolic-links=0″ line=’$item’ - with\_items: + with\_items: - – skip-name-resolve + – skip-name-resolve - – default-time-zone=’+00:00′ + – default-time-zone=’+00:00′ - – innodb\_rollback\_on\_timeout=1 + – innodb\_rollback\_on\_timeout=1 - – innodb\_lock\_wait\_timeout=600 + – innodb\_lock\_wait\_timeout=600 - – max\_connections=350 + – max\_connections=350 - – log-bin=mysql-bin + – log-bin=mysql-bin - – binlog-format = ‘ROW’ + – binlog-format = ‘ROW’ - - name: Ensure MySQL service is started + - name: Ensure MySQL service is started - service: name=mysqld state=started + service: name=mysqld state=started - - name: Ensure MySQL service is enabled at boot + - name: Ensure MySQL service is enabled at boot - service: name=mysqld enabled=yes + service: name=mysqld enabled=yes -   +   - - name: Ensure root password is set + - name: Ensure root password is set - mysql\_user: user=root password=$mysql\_root\_password host=localhost + mysql\_user: user=root password=$mysql\_root\_password host=localhost - ignore\_errors: true + ignore\_errors: true - - name: Ensure root has sufficient privileges + - name: Ensure root has sufficient privileges - mysql\_user: login\_user=root login\_password=$mysql\_root\_password user=root host=% password=$mysql\_root\_password priv=\*.\*:GRANT,ALL state=present + mysql\_user: login\_user=root login\_password=$mysql\_root\_password user=root host=% password=$mysql\_root\_password priv=\*.\*:GRANT,ALL state=present This needs to be saved as `/etc/ansible/roles/mysql/tasks/main.yml` @@ -235,34 +267,34 @@ For the management server role we create a main.yml task like this: :: - - name: Ensure selinux python bindings are installed + - name: Ensure selinux python bindings are installed -   yum: name=libselinux-python state=present +   yum: name=libselinux-python state=present - - name: Ensure the Apache Cloudstack Repo file exists as per template + - name: Ensure the Apache Cloudstack Repo file exists as per template -   template: src=cloudstack.repo.j2 dest=/etc/yum.repos.d/cloudstack.repo +   template: src=cloudstack.repo.j2 dest=/etc/yum.repos.d/cloudstack.repo - - name: Ensure selinux is in permissive mode + - name: Ensure selinux is in permissive mode -   command: setenforce permissive +   command: setenforce permissive - - name: Ensure selinux is set permanently + - name: Ensure selinux is set permanently -   selinux: policy=targeted state=permissive +   selinux: policy=targeted state=permissive - -name: Ensure CloudStack packages are installed + -name: Ensure CloudStack packages are installed - yum: name=cloud-client state=present + yum: name=cloud-client state=present - - name: Ensure vhdutil is in correct location + - name: Ensure vhdutil is in correct location -   get\_url: url=http://download.cloud.com.s3.amazonaws.com/tools/vhd-util dest=/usr/share/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util mode=0755 +   get\_url: url=http://download.cloud.com.s3.amazonaws.com/tools/vhd-util dest=/usr/share/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util mode=0755 Save this as `/etc/ansible/roles/cloudstack-management/tasks/main.yml` @@ -274,24 +306,25 @@ it, so it would simply look like this: :: - [cloudstack] - name=cloudstack - baseurl=http://cloudstack.apt-get.eu/rhel/4.2/ - enabled=1 - gpgcheck=0 + [cloudstack] + name=cloudstack + baseurl=http://cloudstack.apt-get.eu/rhel/4.2/ + enabled=1 + gpgcheck=0 -This is saved in `/etc/ansible/roles/cloudstack-manager/templates/cloudstack.repo.j2` +This is saved in +`/etc/ansible/roles/cloudstack-manager/templates/cloudstack.repo.j2` That gives us the packages installed, we need to set up the database. To do this I’ve created a separate task called setupdb.yml :: - - name: cloudstack-setup-databases - command: /usr/bin/cloudstack-setup-databases cloud:{{mysql\_cloud\_password }}@localhost –deploy-as=root:{{mysql\_root\_password }} + - name: cloudstack-setup-databases + command: /usr/bin/cloudstack-setup-databases cloud:{{mysql\_cloud\_password }}@localhost –deploy-as=root:{{mysql\_root\_password }} - - name: Setup CloudStack manager - command: /usr/bin/cloudstack-setup-management + - name: Setup CloudStack manager + command: /usr/bin/cloudstack-setup-management Save this as: `/etc/ansible/roles/cloudstack-management/tasks/setupdb.yml` @@ -307,34 +340,33 @@ There are some more variables here for us to declare later. System VM Templates: -------------------- - Finally we would want to seed the system VM templates into the secondary storage.  The playbook for this would look as follows: :: - - name: Ensure secondary storage mount exists -   file: path={{ tmp\_nfs\_path }} state=directory + - name: Ensure secondary storage mount exists +   file: path={{ tmp\_nfs\_path }} state=directory - - name: Ensure  NFS storage is mounted -   mount: name={{ tmp\_nfs\_path }} src={{ sec\_nfs\_ip }}:{{sec\_nfs\_path }} fstype=nfs state=mounted opts=nolock + - name: Ensure  NFS storage is mounted +   mount: name={{ tmp\_nfs\_path }} src={{ sec\_nfs\_ip }}:{{sec\_nfs\_path }} fstype=nfs state=mounted opts=nolock - - name: Seed secondary storage -   command: - /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-2013-06-12-master-kvm.qcow2.bz2 -h kvm -F + - name: Seed secondary storage +   command: + /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-2013-06-12-master-kvm.qcow2.bz2 -h kvm -F -   command: - /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-2013-07-12-master-xen.vhd.bz2 -h xenserver -F +   command: + /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-2013-07-12-master-xen.vhd.bz2 -h xenserver -F -   command: - /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-4.2-vh7.ov -h vmware -F +   command: + /usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt -m {{ tmp\_nfs\_path }} -u http://download.cloud.com/templates/4.2/systemvmtemplate-4.2-vh7.ov -h vmware -F Save this as `/etc/ansible/roles/cloudstack-manager/tasks/seedstorage.yml` - Again, there isn’t a CloudStack module so Ansible will always run this +Again, there isn’t a CloudStack module so Ansible will always run this even if the secondary storage already has the templates in it.   @@ -348,46 +380,43 @@ called deploy-cloudstack.yml, which would look like this: :: - -hosts: acs-manager + -hosts: acs-manager -  vars: +  vars: -     mysql\_root\_password: Cl0ud5tack -     mysql\_cloud\_password: Cl0ud5tack -     tmp\_nfs\_path: /mnt/secondary -     sec\_nfs\_ip: IP\_OF\_YOUR\_SECONDARY\_STORAGE -     sec\_nfs\_path: PATH\_TO\_YOUR\_SECONDARY\_STORAGE\_MOUNT +     mysql\_root\_password: Cl0ud5tack +     mysql\_cloud\_password: Cl0ud5tack +     tmp\_nfs\_path: /mnt/secondary +     sec\_nfs\_ip: IP\_OF\_YOUR\_SECONDARY\_STORAGE +     sec\_nfs\_path: PATH\_TO\_YOUR\_SECONDARY\_STORAGE\_MOUNT -  roles: +  roles: -   – mysql -    – cloudstack-manager +   – mysql +    – cloudstack-manager -  tasks: +  tasks: -   – include: /etc/ansible/roles/cloudstack-manager/tasks/setupdb.yml -   – include: /etc/ansible/roles/cloudstack-manager/tasks/seedstorage.yml +   – include: /etc/ansible/roles/cloudstack-manager/tasks/setupdb.yml +   – include: /etc/ansible/roles/cloudstack-manager/tasks/seedstorage.yml Save this as `/etc/ansible/deploy-cloudstack.yml`  inserting the IP address and path for your secondary storage and changing the passwords if you wish to. -  - To run this go to the Ansible directory (cd /etc/ansible ) and run: :: - # ansible-playbook deploy-cloudstack.yml -k + # ansible-playbook deploy-cloudstack.yml -k - ‘-k’ tells Ansible to ask you for the root password to connect to the +‘-k’ tells Ansible to ask you for the root password to connect to the remote host. - Now log in to the CloudStack UI on the new management server. +Now log in to the CloudStack UI on the new management server. -  How is this example different from a production deployment? ----------------------------------------------------------- diff --git a/rtd/source/concepts.rst b/rtd/source/concepts.rst index 5860aa4..93a1fe7 100644 --- a/rtd/source/concepts.rst +++ b/rtd/source/concepts.rst @@ -13,6 +13,7 @@ specific language governing permissions and limitations under the License. + Concepts and Terminology ======================== @@ -25,8 +26,10 @@ build a public or private IaaS compute cloud. With CloudStack you can: -* Set up an on-demand elastic cloud computing service. -* Allow end-users to provision resources +- Set up an on-demand elastic cloud computing service. + +- Allow end-users to provision resources + What can Apache CloudStack do? ------------------------------ @@ -34,117 +37,171 @@ What can Apache CloudStack do? Multiple Hypervisor Support ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CloudStack works with a variety of hypervisors and hypervisor-like technologies. A single -cloud can contain multiple hypervisor implementations. As of the current release CloudStack -supports: +CloudStack works with a variety of hypervisors and hypervisor-like +technologies. A single cloud can contain multiple hypervisor implementations. +As of the current release CloudStack supports: + +- BareMetal (via IPMI) + +- Hyper-V + +- KVM + +- LXC + +- vSphere (via vCenter) + +- Xenserver + +- Xen Project -* BareMetal (via IPMI) -* Hyper-V -* KVM -* LXC -* vSphere (via vCenter) -* Xenserver -* Xen Project Massively Scalable Infrastructure Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CloudStack can manage tens of thousands of physical servers installed in geographically -distributed datacenters. The management server scales near-linearly eliminating the need -for cluster-level management servers. Maintenance or other outages of the management server -can occur without affecting the virtual machines running in the cloud. +CloudStack can manage tens of thousands of physical servers installed in +geographically distributed datacenters. The management server scales +near-linearly eliminating the need for cluster-level management servers. +Maintenance or other outages of the management server can occur without +affecting the virtual machines running in the cloud. + Automatic Cloud Configuration Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -CloudStack automatically configures the network and storage settings for each virtual machine deployment. -Internally, a pool of virtual appliances support the operation of configuration of the cloud itself. These -appliances offer services such as firewalling, routing, DHCP, VPN, console proxy, storage acces, and -storage replication. The extensive use of horizontally scalable virtual machines simplifies the installation -and ongoing operation of a cloud. +CloudStack automatically configures the network and storage settings for each +virtual machine deployment. Internally, a pool of virtual appliances support +the operation of configuration of the cloud itself. These appliances offer +services such as firewalling, routing, DHCP, VPN, console proxy, storage +acces, and storage replication. The extensive use of horizontally scalable +virtual machines simplifies the installation and ongoing operation of a cloud. + Graphical User Interface ~~~~~~~~~~~~~~~~~~~~~~~~ -CloudStack offers an administrators web interface used for provisioning and managing the cloud, as well as -an end-user's Web interface, used for running VMs and managing VM templates. The UI can be customized to -reflect the desired service provider or enterprise look and feel. +CloudStack offers an administrators web interface used for provisioning and +managing the cloud, as well as an end-user's Web interface, used for running +VMs and managing VM templates. The UI can be customized to reflect the desired +service provider or enterprise look and feel. + API ~~~ -CloudStack provides a REST-like API for the operation, management and use of the cloud. +CloudStack provides a REST-like API for the operation, management and use of +the cloud. + AWS EC2 API Support ~~~~~~~~~~~~~~~~~~~ -CloudStack provides an EC2 API translation layer to permit the common EC2 tools to be used in the use of -a CloudStack cloud. +CloudStack provides an EC2 API translation layer to permit the common EC2 +tools to be used in the use of a CloudStack cloud. + High Availability ~~~~~~~~~~~~~~~~~ -CloudStack has a number of features to increase the availability of the system. The Management Server -itself may be deployed in a multi-node installation where the servers are load balanced. MySQL may be -configured to use replication to provide for failover in the event of database loss. For the -hosts, CloudStack supports NIC bonding and the use of separate networks for storage as well as iSCSI Multipath. +CloudStack has a number of features to increase the availability of the +system. The Management Server itself may be deployed in a multi-node +installation where the servers are load balanced. MySQL may be configured to +use replication to provide for failover in the event of database loss. For the +hosts, CloudStack supports NIC bonding and the use of separate networks for +storage as well as iSCSI Multipath. + Deployment Architecture Overview -------------------------------- -Generally speaking, most CloudStack deployments consist of the management server and the resources to be managed. -During deployment you inform the management server of the resources to be managed, such as IP address blocks, storage devices, -hypervisors, and VLANs. +Generally speaking, most CloudStack deployments consist of the management +server and the resources to be managed. During deployment you inform the +management server of the resources to be managed, such as IP address blocks, +storage devices, hypervisors, and VLANs. -The minimum installation consists of one machine running the CloudStack Management Server and another machine -to act as the cloud infrastructure (in this case, a very simple infrastructure consisting of one host running -hypervisor software). In its smallest deployment, a single machine can act as both the Management Server and -the hypervisor host (using the KVM hypervisor). +The minimum installation consists of one machine running the CloudStack +Management Server and another machine to act as the cloud infrastructure (in +this case, a very simple infrastructure consisting of one host running +hypervisor software). In its smallest deployment, a single machine can act as +both the Management Server and the hypervisor host (using the KVM hypervisor). .. image:: _static/images/basic-deployment.png -A more full-featured installation consists of a highly-available multi-node Management Server installation and -up to tens of thousands of hosts using any of severa networking technologies. +A more full-featured installation consists of a highly-available multi-node +Management Server installation and up to tens of thousands of hosts using any +of severa networking technologies. + Management Server Overview ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The management server orchestrates and allocates the resources in your cloud deployment. +The management server orchestrates and allocates the resources in your cloud +deployment. -The management server typically runs on a dedicated machine or as a virtual machine. It controls allocation of -virtual machines to hosts and assigns storage and IP addresses to the virtual machine instances. The Management -Server runs in an Apache Tomcat container and requires a MySQL database for persistence. +The management server typically runs on a dedicated machine or as a virtual +machine. It controls allocation of virtual machines to hosts and assigns +storage and IP addresses to the virtual machine instances. The Management +Server runs in an Apache Tomcat container and requires a MySQL database for +persistence. The management server: -* Provides the web interface for both the adminstrator and end user. -* Provides the API interfaces for both the CloudStack API as well as the EC2 interface. -* Manages the assignment of guest VMs to a specific compute resource -* Manages the assignment of public and private IP addresses. -* Allocates storage during the VM instantiation process. -* Manages snapshots, disk images (templates), and ISO images. -* Provides a single point of configuration for your cloud. +- Provides the web interface for both the adminstrator and end user. + +- Provides the API interfaces for both the CloudStack API as well as the EC2 + interface. + +- Manages the assignment of guest VMs to a specific compute resource + +- Manages the assignment of public and private IP addresses. + +- Allocates storage during the VM instantiation process. + +- Manages snapshots, disk images (templates), and ISO images. + +- Provides a single point of configuration for your cloud. + Cloud Infrastructure Overview ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Resources within the cloud are managed as follows: -* Regions: A collection of one or more geographically proximate zones managed by one or more management servers. -* Zones: Typically, a zone is equivalent to a single datacenter. A zone consists of one or more pods and secondary storage. -* Pods: A pod is usually a rack, or row of racks that includes a layer-2 switch and one or more clusters. -* Clusters: A cluster consists of one or more homogenous hosts and primary storage. -* Host: A single compute node within a cluster; often a hypervisor. -* Primary Storage: A storage resource typically provided to a single cluster for the actual running of instance disk images. (Zone-wide primary storage is an option, though not typically used.) -* Secondary Storage: A zone-wide resource which stores disk templates, ISO images, and snapshots. +- Regions: A collection of one or more geographically proximate zones managed + by one or more management servers. + +- Zones: Typically, a zone is equivalent to a single datacenter. A zone + consists of one or more pods and secondary storage. + +- Pods: A pod is usually a rack, or row of racks that includes a layer-2 + switch and one or more clusters. + +- Clusters: A cluster consists of one or more homogenous hosts and primary + storage. + +- Host: A single compute node within a cluster; often a hypervisor. + +- Primary Storage: A storage resource typically provided to a single cluster + for the actual running of instance disk images. (Zone-wide primary storage + is an option, though not typically used.) + +- Secondary Storage: A zone-wide resource which stores disk templates, ISO + images, and snapshots. + Networking Overview ~~~~~~~~~~~~~~~~~~~ -CloudStack offers many types of networking, but they typically fall into one of two scenarios: +CloudStack offers many types of networking, but they typically fall into one +of two scenarios: + +- Basic: Most analogous to AWS-classic style networking. Provides a single + flat layer-2 network where guest isolation is provided at layer-3 by the + hypervisors bridge device. + +- Advanced: This typically uses layer-2 isolation such as VLANs, though this + category also includes SDN technologies such as Nicira NVP. -* Basic: Most analogous to AWS-classic style networking. Provides a single flat layer-2 network where guest isolation is provided at layer-3 by the hypervisors bridge device. -* Advanced: This typically uses layer-2 isolation such as VLANs, though this category also includes SDN technologies such as Nicira NVP. CloudStack Terminology ---------------------- @@ -181,6 +238,7 @@ selecting that region for their guest. Users might also be required to copy their private templates to additional regions to enable creation of guest VMs using their templates in those regions. + About Zones ~~~~~~~~~~~ @@ -194,19 +252,13 @@ geographically (though this is not required). A zone consists of: -- - - One or more pods. Each pod contains one or more clusters of hosts and +- One or more pods. Each pod contains one or more clusters of hosts and one or more primary storage servers. -- - - A zone may contain one or more primary storage servers, which are +- A zone may contain one or more primary storage servers, which are shared by all the pods in the zone. -- - - Secondary storage, which is shared by all the pods in the zone. +- Secondary storage, which is shared by all the pods in the zone. |zone-overview.png: Nested structure of a simple zone.| @@ -226,31 +278,19 @@ each other through statically configured VPN tunnels. For each zone, the administrator must decide the following. -- - - How many pods to place in each zone. - -- - - How many clusters to place in each pod. - -- +- How many pods to place in each zone. - How many hosts to place in each cluster. +- How many clusters to place in each pod. -- +- How many hosts to place in each cluster. - (Optional) How many primary storage servers to place in each zone and +- (Optional) How many primary storage servers to place in each zone and total capacity for these storage servers. -- - - How many primary storage servers to place in each cluster and total +- How many primary storage servers to place in each cluster and total capacity for these storage servers. -- - - How much secondary storage to deploy in a zone. +- How much secondary storage to deploy in a zone. When you add a new zone using the CloudStack UI, you will be prompted to configure the zone’s physical network and add the first pod, cluster, @@ -266,8 +306,13 @@ the zone. If you are provisioning multiple VMware Datacenters, each one will be set up as a single zone in CloudStack. .. note:: + If you are upgrading from a previous CloudStack version, and your existing + deployment contains a zone with clusters from multiple VMware Datacenters, + that zone will not be forcibly migrated to the new model. It will continue + to function as before. However, any new zone-wide operations, such as + zone-wide primary storage and live storage migration, will not be available + in that zone. - If you are upgrading from a previous CloudStack version, and your existing deployment contains a zone with clusters from multiple VMware Datacenters, that zone will not be forcibly migrated to the new model. It will continue to function as before. However, any new zone-wide operations, such as zone-wide primary storage and live storage migration, will not be available in that zone. About Pods ~~~~~~~~~~ @@ -281,6 +326,7 @@ the end user. |pod-overview.png: Nested structure of a simple pod| + About Clusters ~~~~~~~~~~~~~~ @@ -313,6 +359,7 @@ server. An Administrator must register the vCenter server with CloudStack. There may be multiple vCenter servers per zone. Each vCenter server may manage multiple VMware clusters. + About Hosts ~~~~~~~~~~~ @@ -329,24 +376,16 @@ within regions. Hosts in a CloudStack deployment: -- - - Provide the CPU, memory, storage, and networking resources needed to +- Provide the CPU, memory, storage, and networking resources needed to host the virtual machines -- - - Interconnect using a high bandwidth TCP/IP network and connect to the +- Interconnect using a high bandwidth TCP/IP network and connect to the Internet -- - - May reside in multiple data centers across different geographic +- May reside in multiple data centers across different geographic locations -- - - May have different capacities (different CPU speeds, different +- May have different capacities (different CPU speeds, different amounts of RAM, etc.), although the hosts within a cluster must all be homogeneous @@ -361,17 +400,12 @@ which host their guest has been assigned to. For a host to function in CloudStack, you must do the following: -- - - Install hypervisor software on the host +- Install hypervisor software on the host -- +- Assign an IP address to the host - Assign an IP address to the host +- Ensure the host is connected to the CloudStack Management Server. -- - - Ensure the host is connected to the CloudStack Management Server. About Primary Storage ~~~~~~~~~~~~~~~~~~~~~ @@ -399,43 +433,30 @@ CloudStack is designed to work with all standards-compliant iSCSI and NFS servers that are supported by the underlying hypervisor, including, for example: -- - - SolidFire for iSCSI +- SolidFire for iSCSI -- +- Dell EqualLogic™ for iSCSI - Dell EqualLogic™ for iSCSI +- Network Appliances filers for NFS and iSCSI -- - - Network Appliances filers for NFS and iSCSI - -- - - Scale Computing for NFS +- Scale Computing for NFS If you intend to use only local disk for your installation, you can skip adding separate primary storage. + About Secondary Storage ~~~~~~~~~~~~~~~~~~~~~~~ Secondary storage stores the following: -- - - Templates — OS images that can be used to boot VMs and can include +- Templates — OS images that can be used to boot VMs and can include additional configuration information, such as installed applications -- - - ISO images — disc images containing data or bootable media for +- ISO images — disc images containing data or bootable media for operating systems -- - - Disk volume snapshots — saved copies of VM data which can be used for +- Disk volume snapshots — saved copies of VM data which can be used for data recovery or to create new templates The items in secondary storage are available to all hosts in the scope @@ -462,8 +483,10 @@ resource, making templates and other data available to any zone in the cloud. .. warning:: + Heterogeneous Secondary Storage is not supported in Regions. For example, + you cannot set up multiple zones, one using NFS secondary and the other + using S3 or Swift secondary. - Heterogeneous Secondary Storage is not supported in Regions. For example, you cannot set up multiple zones, one using NFS secondary and the other using S3 or Swift secondary. About Physical Networks ~~~~~~~~~~~~~~~~~~~~~~~ @@ -478,49 +501,34 @@ a zone with basic networking or advanced networking. A physical network is the actual network hardware and wiring in a zone. A zone can have multiple physical networks. An administrator can: -- - - Add/Remove/Update physical networks in a zone - -- - - Configure VLANs on the physical network +- Add/Remove/Update physical networks in a zone -- +- Configure VLANs on the physical network - Configure a name so the network can be recognized by hypervisors +- Configure a name so the network can be recognized by hypervisors -- - - Configure the service providers (firewalls, load balancers, etc.) +- Configure the service providers (firewalls, load balancers, etc.) available on a physical network -- - - Configure the IP addresses trunked to a physical network - -- +- Configure the IP addresses trunked to a physical network - Specify what type of traffic is carried on the physical network, as +- Specify what type of traffic is carried on the physical network, as well as other properties like network speed + Basic Zone Network Traffic Types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When basic networking is used, there can be only one physical network in the zone. That physical network carries the following traffic types: -- - - Guest. When end users run VMs, they generate guest traffic. The guest +- Guest. When end users run VMs, they generate guest traffic. The guest VMs communicate with each other over a network that can be referred to as the guest network. Each pod in a basic zone is a broadcast domain, and therefore each pod has a different IP range for the guest network. The administrator must configure the IP range for each pod. -- - - Management. When CloudStack's internal resources communicate with +- Management. When CloudStack's internal resources communicate with each other, they generate management traffic. This includes communication between hosts, system VMs (VMs used by CloudStack to perform various tasks in the cloud), and any other component that @@ -528,21 +536,16 @@ the zone. That physical network carries the following traffic types: configure the IP range for the system VMs to use. .. note:: - We strongly recommend the use of separate NICs for management traffic and guest traffic. -- - - Public. Public traffic is generated when VMs in the cloud access the +- Public. Public traffic is generated when VMs in the cloud access the Internet. Publicly accessible IPs must be allocated for this purpose. End users can use the CloudStack UI to acquire these IPs to implement NAT between their guest network and the public network, as described in Acquiring a New IP Address. -- - - Storage. While labeled "storage" this is specifically about secondary +- Storage. While labeled "storage" this is specifically about secondary storage, and doesn't affect traffic for primary storage. This includes traffic such as VM templates and snapshots, which is sent between the secondary storage VM and secondary storage servers. @@ -560,6 +563,7 @@ balancing (EIP and ELB) features, you must also configure a network to carry public traffic. CloudStack takes care of presenting the necessary network configuration steps to you in the UI when you add a new zone. + Basic Zone Guest IP Addresses ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -568,6 +572,7 @@ the CIDR of the pod to the guests in that pod. The administrator must add a Direct IP range on the pod for this purpose. These IPs are in the same VLAN as the hosts. + Advanced Zone Network Traffic Types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -577,9 +582,7 @@ traffic types, and you need to let CloudStack know which type of network traffic you want each network to carry. The traffic types in an advanced zone are: -- - - Guest. When end users run VMs, they generate guest traffic. The guest +- Guest. When end users run VMs, they generate guest traffic. The guest VMs communicate with each other over a network that can be referred to as the guest network. This network can be isolated or shared. In an isolated guest network, the administrator needs to reserve VLAN @@ -587,26 +590,20 @@ zone are: (potentially a large number of VLANs). In a shared guest network, all guest VMs share a single network. -- - - Management. When CloudStack’s internal resources communicate with +- Management. When CloudStack’s internal resources communicate with each other, they generate management traffic. This includes communication between hosts, system VMs (VMs used by CloudStack to perform various tasks in the cloud), and any other component that communicates directly with the CloudStack Management Server. You must configure the IP range for the system VMs to use. -- - - Public. Public traffic is generated when VMs in the cloud access the +- Public. Public traffic is generated when VMs in the cloud access the Internet. Publicly accessible IPs must be allocated for this purpose. End users can use the CloudStack UI to acquire these IPs to implement NAT between their guest network and the public network, as described in “Acquiring a New IP Address” in the Administration Guide. -- - - Storage. While labeled "storage" this is specifically about secondary +- Storage. While labeled "storage" this is specifically about secondary storage, and doesn't affect traffic for primary storage. This includes traffic such as VM templates and snapshots, which is sent between the secondary storage VM and secondary storage servers. @@ -621,6 +618,7 @@ can be combined with certain restrictions. When you use the Add Zone wizard in the UI to create a new zone, you are guided into making only valid choices. + Advanced Zone Guest IP Addresses ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -633,6 +631,7 @@ range, and gateway. The administrator may provision thousands of these networks if desired. Additionally, the administrator can reserve a part of the IP address space for non-CloudStack VMs and servers. + Advanced Zone Public IP Addresses ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -644,6 +643,7 @@ attach to these networks. The networks are defined by a VLAN ID, IP range, and gateway. The administrator may provision thousands of these networks if desired. + System Reserved IP Addresses ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -702,14 +702,10 @@ To ensure adequate headroom to scale private IP space in an ESXi pod that uses advanced networking, use one or both of the following techniques: -- - - Specify a larger CIDR block for the subnet. A subnet mask with a /20 +- Specify a larger CIDR block for the subnet. A subnet mask with a /20 suffix will provide more than 4,000 IP addresses. -- - - Create multiple pods, each with its own subnet. For example, if you +- Create multiple pods, each with its own subnet. For example, if you create 10 pods and each pod has 255 IPs, this will provide 2,550 IP addresses. @@ -720,4 +716,4 @@ techniques: .. |region-overview.png: Nested structure of a region.| image:: ./_static/images/region-overview.png .. |zone-overview.png: Nested structure of a simple zone.| image:: ./_static/images/zone-overview.png .. |pod-overview.png: Nested structure of a simple pod| image:: ./_static/images/pod-overview.png -.. |cluster-overview.png: Structure of a simple cluster| image:: ./_static/images/cluster-overview.png \ No newline at end of file +.. |cluster-overview.png: Structure of a simple cluster| image:: ./_static/images/cluster-overview.png diff --git a/rtd/source/conf.py b/rtd/source/conf.py index 751553f..2076d96 100644 --- a/rtd/source/conf.py +++ b/rtd/source/conf.py @@ -31,6 +31,8 @@ import sys import os +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -115,6 +117,13 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' +if not on_rtd: + try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + except ImportError: + pass # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/rtd/source/dev.rst b/rtd/source/dev.rst index 5fca19e..850caf2 100644 --- a/rtd/source/dev.rst +++ b/rtd/source/dev.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Programmer Guide ================ @@ -5,6 +21,7 @@ This guide shows how to develop CloudStack, use the API for operation and integration, access the usage data and use CloudStack specific tools to ease development, testing and integration. + The CloudStack API ------------------ @@ -13,55 +30,42 @@ Getting Started To get started using the CloudStack API, you should have the following: -- - - URL of the CloudStack server you wish to integrate with. +- URL of the CloudStack server you wish to integrate with. -- - - Both the API Key and Secret Key for an account. This should have been +- Both the API Key and Secret Key for an account. This should have been generated by the administrator of the cloud instance and given to you. -- - - Familiarity with HTTP GET/POST and query strings. - -- +- Familiarity with HTTP GET/POST and query strings. - Knowledge of either XML or JSON. +- Knowledge of either XML or JSON. -- - - Knowledge of a programming language that can generate HTTP requests; +- Knowledge of a programming language that can generate HTTP requests; for example, Java or PHP. + Roles ~~~~~ The CloudStack API supports three access roles: -#. - - Root Admin. Access to all features of the cloud, including both +#. Root Admin. Access to all features of the cloud, including both virtual and physical resource management. -#. - - Domain Admin. Access to only the virtual resources of the clouds that +#. Domain Admin. Access to only the virtual resources of the clouds that belong to the administrator’s domain. -#. - - User. Access to only the features that allow management of the user’s +#. User. Access to only the features that allow management of the user’s virtual instances, storage, and network. + API Reference Documentation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can find all the API reference documentation at the below site: -`http://cloudstack.apache.org/docs/api/ `__ +`http://cloudstack.apache.org/docs/api/ +`__ Making API Requests @@ -71,39 +75,33 @@ All CloudStack API requests are submitted in the form of a HTTP GET/POST with an associated command and any parameters. A request is composed of the following whether in HTTP or HTTPS: -- - - CloudStack API URL: This is the web services API entry point(for +- CloudStack API URL: This is the web services API entry point(for example, http://www.example.com:8080/client/api) -- - - Command: The web services command you wish to execute, such as start +- Command: The web services command you wish to execute, such as start a virtual machine or create a disk volume -- - - Parameters: Any additional required or optional parameters for the +- Parameters: Any additional required or optional parameters for the command A sample API GET request looks like the following: .. sourcecode:: bash - http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D Or in a more readable format: .. sourcecode:: bash - 1. http://localhost:8080/client/api - 2. ?command=deployVirtualMachine - 3. &serviceOfferingId=1 - 4. &diskOfferingId=1 - 5. &templateId=2 - 6. &zoneId=4 - 7. &apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXqjB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ - 8. &signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + 1. http://localhost:8080/client/api + 2. ?command=deployVirtualMachine + 3. &serviceOfferingId=1 + 4. &diskOfferingId=1 + 5. &templateId=2 + 6. &zoneId=4 + 7. &apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXqjB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ + 8. &signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D The first line is the CloudStack API URL. This is the Cloud instance you wish to interact with. @@ -123,6 +121,7 @@ Signing API Requests on page 7. Line 8 is the signature hash created to authenticate the user account executing the API command. + Signing API Requests ~~~~~~~~~~~~~~~~~~~~ @@ -137,74 +136,63 @@ To show how to sign a request, we will re-use the previous example. .. sourcecode:: bash - http://http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + http://http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D Breaking this down, we have several distinct parts to this URL. -- - - Base URL: This is the base URL to the CloudStack Management Server. +- Base URL: This is the base URL to the CloudStack Management Server. .. sourcecode:: bash - http://localhost:8080 + http://localhost:8080 -- - - API Path: This is the path to the API Servlet that processes the +- API Path: This is the path to the API Servlet that processes the incoming requests. .. sourcecode:: bash - /client/api? - -- + /client/api? - Command String: This part of the query string comprises of the +- Command String: This part of the query string comprises of the command, its parameters, and the API Key that identifies the account. - .. note:: As with all query string parameters of field-value pairs, the "field" component is case insensitive while all "value" values are case sensitive. + .. note:: + As with all query string parameters of field-value pairs, the "field" + component is case insensitive while all "value" values are case + sensitive. .. sourcecode: bash - command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ - -- + command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ - Signature: This is the signature of the command string that is +- Signature: This is the signature of the command string that is generated using a combination of the user’s Secret Key and the HMAC SHA-1 hashing algorithm. .. sourcecode:: bash - &signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + &signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D Every API request has the format Base URL+API Path+Command String+Signature. To generate the signature. -#. - - For each field-value pair (as separated by a '&') in the Command +#. For each field-value pair (as separated by a '&') in the Command String, URL encode each value so that it can be safely sent via HTTP GET. .. note:: Make sure all spaces are encoded as "%20" rather than "+". -#. - - Lower case the entire Command String and sort it alphabetically via +#. Lower case the entire Command String and sort it alphabetically via the field for each field-value pair. The result of this step would look like the following. .. sourcecode:: bash - apikey=mivr6x7u6bn_sdahobpjnejpgest35exq-jb8cg20yi3yaxxcgpyuairmfi_ejtvwz0nukkjbpmy3y2bcikwfq&command=deployvirtualmachine&diskofferingid=1&serviceofferingid=1&templateid=2&zoneid=4 - -#. + apikey=mivr6x7u6bn_sdahobpjnejpgest35exq-jb8cg20yi3yaxxcgpyuairmfi_ejtvwz0nukkjbpmy3y2bcikwfq&command=deployvirtualmachine&diskofferingid=1&serviceofferingid=1&templateid=2&zoneid=4 - Take the sorted Command String and run it through the HMAC SHA-1 +#. Take the sorted Command String and run it through the HMAC SHA-1 hashing algorithm (most programming languages offer a utility method to do this) with the user’s Secret Key. Base64 encode the resulting byte array in UTF-8 so that it can be safely transmitted via HTTP. @@ -216,7 +204,8 @@ To generate the signature. .. sourcecode:: bash - http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + http://localhost:8080/client/api?command=deployVirtualMachine&serviceOfferingId=1&diskOfferingId=1&templateId=2&zoneId=4&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + How to sign an API call with Python ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -228,15 +217,15 @@ First import the required modules: .. sourcecode:: bash - $python - Python 2.7.3 (default, Nov 17 2012, 19:54:34) - [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin - Type "help", "copyright", "credits" or "license" for more information. - >>> import urllib2 - >>> import urllib - >>> import hashlib - >>> import hmac - >>> import base64 + $python + Python 2.7.3 (default, Nov 17 2012, 19:54:34) + [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin + Type "help", "copyright", "credits" or "license" for more information. + >>> import urllib2 + >>> import urllib + >>> import hashlib + >>> import hmac + >>> import base64 Define the endpoint of the Cloud, the command that you want to execute @@ -244,21 +233,21 @@ and the keys of the user. .. sourcecode:: bash - >>> baseurl='http://localhost:8080/client/api?' - >>> request={} - >>> request['command']='listUsers' - >>> request['response']='json' - >>> request['apikey']='plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg' - >>> secretkey='VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ' + >>> baseurl='http://localhost:8080/client/api?' + >>> request={} + >>> request['command']='listUsers' + >>> request['response']='json' + >>> request['apikey']='plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg' + >>> secretkey='VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ' Build the request string: .. sourcecode:: bash - >>> request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()]) - >>> request_str - 'apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json' + >>> request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()]) + >>> request_str + 'apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json' Compute the signature with hmac, do a 64 bit encoding and a url @@ -266,33 +255,33 @@ encoding: .. sourcecode:: bash - >>> sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())]) - >>> sig_str 'apikey=plgwjfzk4gys3momtvmjuvg-x-jlwlnfauj9gabbbf9edm-kaymmailqzzq1elzlyq_u38zcm0bewzgudp66mg&command=listusers&response=json' - >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1) - >>> sig - - >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest() - >>> sig - 'M:]\x0e\xaf\xfb\x8f\xf2y\xf1p\x91\x1e\x89\x8a\xa1\x05\xc4A\xdb' - >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()) - >>> sig - 'TTpdDq/7j/J58XCRHomKoQXEQds=\n' - >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip() - >>> sig - 'TTpdDq/7j/J58XCRHomKoQXEQds=' - >>> sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()) + >>> sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())]) + >>> sig_str 'apikey=plgwjfzk4gys3momtvmjuvg-x-jlwlnfauj9gabbbf9edm-kaymmailqzzq1elzlyq_u38zcm0bewzgudp66mg&command=listusers&response=json' + >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1) + >>> sig + + >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest() + >>> sig + 'M:]\x0e\xaf\xfb\x8f\xf2y\xf1p\x91\x1e\x89\x8a\xa1\x05\xc4A\xdb' + >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()) + >>> sig + 'TTpdDq/7j/J58XCRHomKoQXEQds=\n' + >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip() + >>> sig + 'TTpdDq/7j/J58XCRHomKoQXEQds=' + >>> sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()) Finally, build the entire string and do an http GET: .. sourcecode:: bash - >>> req=baseurl+request_str+'&signature='+sig - >>> req - 'http://localhost:8080/client/api?apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json&signature=TTpdDq%2F7j%2FJ58XCRHomKoQXEQds%3D' - >>> res=urllib2.urlopen(req) - >>> res.read() - '{ "listusersresponse" : { "count":3 ,"user" : [ {"id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a","username":"admin","firstname":"admin","lastname":"cloud","created":"2012-07-05T12:18:27-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg","secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"1fea6418-5576-4989-a21e-4790787bbee3","username":"runseb","firstname":"foobar","lastname":"goa","email":"joe@smith.com","created":"2013-04-10T16:52:06-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"Xhsb3MewjJQaXXMszRcLvQI9_NPy_UcbDj1QXikkVbDC9MDSPwWdtZ1bUY1H7JBEYTtDDLY3yuchCeW778GkBA","secretkey":"gIsgmi8C5YwxMHjX5o51pSe0kqs6JnKriw0jJBLceY5bgnfzKjL4aM6ctJX-i1ddQIHJLbLJDK9MRzsKk6xZ_w","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"52f65396-183c-4473-883f-a37e7bb93967","username":"toto","firstname":"john","lastname":"smith","email":"john@smith.com","created":"2013-04-23T04:27:22-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"THaA6fFWS_OmvU8od201omxFC8yKNL_Hc5ZCS77LFCJsRzSx48JyZucbUul6XYbEg-ZyXMl_wuEpECzK-wKnow","secretkey":"O5ywpqJorAsEBKR_5jEvrtGHfWL1Y_j1E4Z_iCr8OKCYcsPIOdVcfzjJQ8YqK0a5EzSpoRrjOFiLsG0hQrYnDA","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} ] } }' + >>> req=baseurl+request_str+'&signature='+sig + >>> req + 'http://localhost:8080/client/api?apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json&signature=TTpdDq%2F7j%2FJ58XCRHomKoQXEQds%3D' + >>> res=urllib2.urlopen(req) + >>> res.read() + '{ "listusersresponse" : { "count":3 ,"user" : [ {"id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a","username":"admin","firstname":"admin","lastname":"cloud","created":"2012-07-05T12:18:27-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg","secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"1fea6418-5576-4989-a21e-4790787bbee3","username":"runseb","firstname":"foobar","lastname":"goa","email":"joe@smith.com","created":"2013-04-10T16:52:06-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"Xhsb3MewjJQaXXMszRcLvQI9_NPy_UcbDj1QXikkVbDC9MDSPwWdtZ1bUY1H7JBEYTtDDLY3yuchCeW778GkBA","secretkey":"gIsgmi8C5YwxMHjX5o51pSe0kqs6JnKriw0jJBLceY5bgnfzKjL4aM6ctJX-i1ddQIHJLbLJDK9MRzsKk6xZ_w","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"52f65396-183c-4473-883f-a37e7bb93967","username":"toto","firstname":"john","lastname":"smith","email":"john@smith.com","created":"2013-04-23T04:27:22-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"THaA6fFWS_OmvU8od201omxFC8yKNL_Hc5ZCS77LFCJsRzSx48JyZucbUul6XYbEg-ZyXMl_wuEpECzK-wKnow","secretkey":"O5ywpqJorAsEBKR_5jEvrtGHfWL1Y_j1E4Z_iCr8OKCYcsPIOdVcfzjJQ8YqK0a5EzSpoRrjOFiLsG0hQrYnDA","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} ] } }' Enabling API Call Expiration @@ -305,15 +294,11 @@ that come in after this validity period. To enable this feature, add the following parameters to the API request: -- - - signatureVersion=3: If the signatureVersion parameter is missing or +- signatureVersion=3: If the signatureVersion parameter is missing or is not equal to 3, the expires parameter is ignored in the API request. -- - - expires=YYYY-MM-DDThh:mm:ssZ: Specifies the date and time at which +- expires=YYYY-MM-DDThh:mm:ssZ: Specifies the date and time at which the signature included in the request is expired. The timestamp is expressed in the YYYY-MM-DDThh:mm:ssZ format, as specified in the ISO 8601 standard. @@ -322,13 +307,13 @@ For example: .. sourcecode:: bash - expires=2011-10-10T12:00:00+0530 + expires=2011-10-10T12:00:00+0530 A sample API request with expiration is given below: .. sourcecode:: bash - http://:8080/client/api?command=listZones&signatureVersion=3&expires=2011-10-10T12:00:00+0530&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D + http://:8080/client/api?command=listZones&signatureVersion=3&expires=2011-10-10T12:00:00+0530&apiKey=miVr6X7u6bN_sdahOBpjNejPgEsT35eXq-jB8CG20YI3yaxXcgpyuaIRmFI_EJTVwZ0nUkkJbPmY3y2bciKwFQ&signature=Lxx1DM40AjcXU%2FcaiK8RAP0O1hU%3D Limiting the Rate of API Requests @@ -343,58 +328,49 @@ If the number of API calls exceeds the threshold, an error message is returned for any additional API calls. The caller will have to retry these API calls at another time. + Configuring the API Request Rate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To control the API request rate, use the following global configuration settings: -- - - `api.throttling.enabled` - Enable/Disable API throttling. By default, +- `api.throttling.enabled` - Enable/Disable API throttling. By default, this setting is false, so API throttling is not enabled. -- - - `api.throttling.interval` (in seconds) - Time interval during which the +- `api.throttling.interval` (in seconds) - Time interval during which the number of API requests is to be counted. When the interval has passed, the API count is reset to 0. -- - - `api.throttling.max` - Maximum number of APIs that can be placed within +- `api.throttling.max` - Maximum number of APIs that can be placed within the `api.throttling.interval` period. -- - - `api.throttling.cachesize` - Cache size for storing API counters. Use a +- `api.throttling.cachesize` - Cache size for storing API counters. Use a value higher than the total number of accounts managed by the cloud. One cache entry is needed for each account, to store the running API total for that account. + Limitations on API Throttling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The following limitations exist in the current implementation of this feature. -.. note:: Even with these limitations, CloudStack is still able to effectively use -API throttling to avoid malicious attacks causing denial of service. - +.. note:: + Even with these limitations, CloudStack is still able to effectively use + API throttling to avoid malicious attacks causing denial of service. -- - - In a deployment with multiple Management Servers, the cache is not +- In a deployment with multiple Management Servers, the cache is not synchronized across them. In this case, CloudStack might not be able to ensure that only the exact desired number of API requests are allowed. In the worst case, the number of API calls that might be allowed is (number of Management Servers) \* (api.throttling.max). -- - - The API commands resetApiLimit and getApiLimit are limited to the +- The API commands resetApiLimit and getApiLimit are limited to the Management Server where the API is invoked. + API Responses ~~~~~~~~~~~~~ @@ -415,33 +391,34 @@ Sample XML Response: .. sourcecode:: bash - - - 192.168.10.141 - 2009-09-18T13:16:10-0700 - 4 - WC - true - - + + + 192.168.10.141 + 2009-09-18T13:16:10-0700 + 4 + WC + true + + Sample JSON Response: .. sourcecode:: bash - { "listipaddressesresponse" : - { "allocatedipaddress" : - [ - { - "ipaddress" : "192.168.10.141", - "allocated" : "2009-09-18T13:16:10-0700", - "zoneid" : "4", - "zonename" : "WC", - "issourcenat" : "true" - } - ] - } - } + { "listipaddressesresponse" : + { "allocatedipaddress" : + [ + { + "ipaddress" : "192.168.10.141", + "allocated" : "2009-09-18T13:16:10-0700", + "zoneid" : "4", + "zonename" : "WC", + "issourcenat" : "true" + } + ] + } + } + Maximum Result Pages Returned ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -465,18 +442,15 @@ the global setting with the page and pagesize parameters, which are available in any list\* command (listCapabilities, listDiskOfferings, etc.). -- +- Both parameters must be specified together. - Both parameters must be specified together. - -- - - The value of the pagesize parameter must be smaller than the value of +- The value of the pagesize parameter must be smaller than the value of default.page.size. That is, you can not increase the number of possible items in a result page, only decrease it. For syntax information on the list\* commands, see the API Reference. + Error Handling ~~~~~~~~~~~~~~ @@ -611,6 +585,7 @@ An HTTP error code of 401 is always returned if API request was rejected due to bad signatures, missing API Keys, or the user simply did not have the permissions to execute the command. + Asynchronous Commands ~~~~~~~~~~~~~~~~~~~~~ @@ -619,24 +594,19 @@ designated as asynchronous when they can potentially take a long period of time to complete such as creating a snapshot or disk volume. They differ from synchronous commands by the following: -- - - They are identified in the API Reference by an (A). +- They are identified in the API Reference by an (A). -- - - They will immediately return a job ID to refer to the job that will +- They will immediately return a job ID to refer to the job that will be responsible in processing the command. -- - - If executed as a "create" resource command, it will return the +- If executed as a "create" resource command, it will return the resource ID as well as the job ID. You can periodically check the status of the job by making a simple API call to the command, `queryAsyncJobResult` and passing in the job ID. + Job Status ~~~~~~~~~~ @@ -646,22 +616,17 @@ periodically check the job status by making calls to queryAsyncJobResult command. The command will return three possible job status integer values: -- - - 0 - Job is still in progress. Continue to periodically poll for any +- 0 - Job is still in progress. Continue to periodically poll for any status changes. -- - - 1 - Job has successfully completed. The job will return any +- 1 - Job has successfully completed. The job will return any successful response values associated with command that was originally executed. -- - - 2 - Job has failed to complete. Please check the "jobresultcode" tag +- 2 - Job has failed to complete. Please check the "jobresultcode" tag for failure reason code and "jobresult" for the failure reason. + Example ~~~~~~~ @@ -670,24 +635,24 @@ the API command: .. sourcecode:: bash - command=deployVirtualMachine&zoneId=1&serviceOfferingId=1&diskOfferingId=1&templateId=1 + command=deployVirtualMachine&zoneId=1&serviceOfferingId=1&diskOfferingId=1&templateId=1 CloudStack will immediately return a job ID and any other additional data. .. sourcecode:: bash - - 1 - 100 - + + 1 + 100 + Using the job ID, you can periodically poll for the results by using the queryAsyncJobResult command. .. sourcecode:: bash - command=queryAsyncJobResult&jobId=1 + command=queryAsyncJobResult&jobId=1 Three possible results could come from this query. @@ -695,78 +660,78 @@ Job is still pending: .. sourcecode:: bash - - 1 - 0 - 1 - + + 1 + 0 + 1 + Job has succeeded: .. sourcecode:: bash - - 1 - 1 - 0 - 0 - object - - - 450 - i-2-450-VM - i-2-450-VM - admin - 1 - ROOT - 2011-03-10T18:20:25-0800 - Running - false - 1 - San Jose 1 - 2 - 905-13.sjc.lab.vmops.com - 1 - CentOS 5.3 64bit LAMP - CentOS 5.3 64bit LAMP - false - 1 - Small Instance - 1 - 500 - 512 - 12 - 0 - NetworkFilesystem - - 561 - 205 - 255.255.255.0 - 10.1.1.1 - 10.1.1.225 - vlan://295 - vlan://295 - Guest - Virtual - true - - XenServer - - - + + 1 + 1 + 0 + 0 + object + + + 450 + i-2-450-VM + i-2-450-VM + admin + 1 + ROOT + 2011-03-10T18:20:25-0800 + Running + false + 1 + San Jose 1 + 2 + 905-13.sjc.lab.vmops.com + 1 + CentOS 5.3 64bit LAMP + CentOS 5.3 64bit LAMP + false + 1 + Small Instance + 1 + 500 + 512 + 12 + 0 + NetworkFilesystem + + 561 + 205 + 255.255.255.0 + 10.1.1.1 + 10.1.1.225 + vlan://295 + vlan://295 + Guest + Virtual + true + + XenServer + + + Job has failed: .. sourcecode:: bash - - 1 - 2 - 0 - 551 - text - Unable to deploy virtual machine id = 100 due to not enough capacity - + + 1 + 2 + 0 + 551 + text + Unable to deploy virtual machine id = 100 due to not enough capacity + Event Types @@ -1318,6 +1283,7 @@ Event Types | | UCS.DISASSOCIATEPROFILE | +-------------------+--------------------------------------------------------+ + Time Zones ---------- @@ -1367,6 +1333,3 @@ user, and specifying the usage time zone in the Configuration table. +-----------------------------------+-----------------------+------------------------+ | Pacific/Guam | Pacific/Auckland | | +-----------------------------------+-----------------------+------------------------+ - - - diff --git a/rtd/source/developer_guide.rst b/rtd/source/developer_guide.rst index e859a59..0e49688 100644 --- a/rtd/source/developer_guide.rst +++ b/rtd/source/developer_guide.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + CloudStack Installation from Source for Developers ================================================== @@ -7,13 +23,19 @@ and were tested with the 4.2 release of Apache CloudStack, please adapt them if you are on a different operating system or using a newer/older version of CloudStack. This book is composed of the following sections: -1. Installation of the prerequisites -2. Compiling and installation from source -3. Using the CloudStack simulator -4. Installation with DevCloud the CloudStack sandbox -5. Building your own packages -6. The CloudStack API -7. Testing the AWS API interface +#. Installation of the prerequisites + +#. Compiling and installation from source + +#. Using the CloudStack simulator + +#. Installation with DevCloud the CloudStack sandbox + +#. Building your own packages + +#. The CloudStack API + +#. Testing the AWS API interface Prerequisites @@ -22,6 +44,7 @@ Prerequisites In this section we'll look at installing the dependencies you'll need for Apache CloudStack development. + On Ubuntu 12.04 ~~~~~~~~~~~~~~~ @@ -29,21 +52,21 @@ First update and upgrade your system: :: - apt-get update - apt-get upgrade + apt-get update + apt-get upgrade NTP might already be installed, check it with ``service ntp status``. If it's not then install NTP to synchronize the clocks: :: - apt-get install openntpd + apt-get install openntpd Install ``openjdk``. As we're using Linux, OpenJDK is our first choice. :: - apt-get install openjdk-6-jdk + apt-get install openjdk-6-jdk Install ``tomcat6``, note that the new version of tomcat on `Ubuntu `__ is the @@ -51,13 +74,13 @@ Install ``tomcat6``, note that the new version of tomcat on :: - apt-get install tomcat6 + apt-get install tomcat6 Next, we'll install MySQL if it's not already present on the system. :: - apt-get install mysql-server + apt-get install mysql-server Remember to set the correct ``mysql`` password in the CloudStack properties file. Mysql should be running but you can check it's status @@ -65,7 +88,7 @@ with: :: - service mysql status + service mysql status Developers wanting to build CloudStack from source will want to install the following additional packages. If you dont' want to build from @@ -75,13 +98,13 @@ Install ``git`` to later clone the CloudStack source code: :: - apt-get install git + apt-get install git Install ``Maven`` to later build CloudStack :: - apt-get install maven + apt-get install maven This should have installed Maven 3.0, check the version number with ``mvn --version`` @@ -91,35 +114,36 @@ package management tools: :: - apt-get install python-pip python-setuptools + apt-get install python-pip python-setuptools Finally install ``mkisofs`` with: :: - apt-get install genisoimage + apt-get install genisoimage -On centOS 6.4 + +On CentOS 6.4 ~~~~~~~~~~~~~ First update and upgrade your system: :: - yum -y update - yum -y upgrade + yum -y update + yum -y upgrade If not already installed, install NTP for clock synchornization :: - yum -y install ntp + yum -y install ntp Install ``openjdk``. As we're using Linux, OpenJDK is our first choice. :: - yum -y install java-1.6.0-openjdk + yum -y install java-1.6.0-openjdk Install ``tomcat6``, note that the version of tomcat6 in the default CentOS 6.4 repo is 6.0.24, so we will grab the 6.0.35 version. The @@ -127,22 +151,22 @@ CentOS 6.4 repo is 6.0.24, so we will grab the 6.0.35 version. The :: - wget https://archive.apache.org/dist/tomcat/tomcat-6/v6.0.35/bin/apache-tomcat-6.0.35.tar.gz - tar xzvf apache-tomcat-6.0.35.tar.gz -C /usr/local + wget https://archive.apache.org/dist/tomcat/tomcat-6/v6.0.35/bin/apache-tomcat-6.0.35.tar.gz + tar xzvf apache-tomcat-6.0.35.tar.gz -C /usr/local Setup tomcat6 system wide by creating a file ``/etc/profile.d/tomcat.sh`` with the following content: :: - export CATALINA_BASE=/usr/local/apache-tomcat-6.0.35 - export CATALINA_HOME=/usr/local/apache-tomcat-6.0.35 + export CATALINA_BASE=/usr/local/apache-tomcat-6.0.35 + export CATALINA_HOME=/usr/local/apache-tomcat-6.0.35 Next, we'll install MySQL if it's not already present on the system. :: - yum -y install mysql mysql-server + yum -y install mysql mysql-server Remember to set the correct ``mysql`` password in the CloudStack properties file. Mysql should be running but you can check it's status @@ -150,37 +174,37 @@ with: :: - service mysqld status + service mysqld status Install ``git`` to later clone the CloudStack source code: :: - yum -y install git + yum -y install git Install ``Maven`` to later build CloudStack. Grab the 3.0.5 release from the Maven `website `__ :: - wget http://mirror.cc.columbia.edu/pub/software/apache/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.tar.gz - tar xzf apache-maven-3.0.5-bin.tar.gz -C /usr/local - cd /usr/local - ln -s apache-maven-3.0.5 maven + wget http://mirror.cc.columbia.edu/pub/software/apache/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.tar.gz + tar xzf apache-maven-3.0.5-bin.tar.gz -C /usr/local + cd /usr/local + ln -s apache-maven-3.0.5 maven Setup Maven system wide by creating a ``/etc/profile.d/maven.sh`` file with the following content: :: - export M2_HOME=/usr/local/maven - export PATH=${M2_HOME}/bin:${PATH} + export M2_HOME=/usr/local/maven + export PATH=${M2_HOME}/bin:${PATH} Log out and log in again and you will have maven in your PATH: :: - mvn --version + mvn --version This should have installed Maven 3.0, check the version number with ``mvn --version`` @@ -190,16 +214,16 @@ package management tools: :: - yum -y install python-setuptools + yum -y install python-setuptools To install python-pip you might want to setup the Extra Packages for Enterprise Linux (EPEL) repo :: - cd /tmp - wget http://mirror-fpt-telecom.fpt.net/fedora/epel/6/i386/epel-release-6-8.noarch.rpm - rpm -ivh epel-release-6-8.noarch.rpm + cd /tmp + wget http://mirror-fpt-telecom.fpt.net/fedora/epel/6/i386/epel-release-6-8.noarch.rpm + rpm -ivh epel-release-6-8.noarch.rpm Then update you repository cache ``yum update`` and install pip ``yum -y install python-pip`` @@ -208,7 +232,7 @@ Finally install ``mkisofs`` with: :: - yum -y install genisoimage + yum -y install genisoimage Installing from Source @@ -220,20 +244,20 @@ setup on your machine, pull the source with: :: - git clone https://git-wip-us.apache.org/repos/asf/cloudstack.git + git clone https://git-wip-us.apache.org/repos/asf/cloudstack.git To build the latest stable release: :: - git checkout 4.2 + git checkout 4.2 To compile Apache CloudStack, go to the cloudstack source folder and run: :: - mvn -Pdeveloper,systemvm clean install + mvn -Pdeveloper,systemvm clean install If you want to skip the tests add ``-DskipTests`` to the command above. Do NOT use ``-Dmaven.test.skip=true`` because that will break the build. @@ -245,14 +269,14 @@ Deploy the database next: :: - mvn -P developer -pl developer -Ddeploydb + mvn -P developer -pl developer -Ddeploydb Run Apache CloudStack with jetty for testing. Note that ``tomcat`` maybe be running on port 8080, stop it before you use ``jetty`` :: - mvn -pl :cloud-client-ui jetty:run + mvn -pl :cloud-client-ui jetty:run Log Into Apache CloudStack: @@ -260,11 +284,13 @@ Open your Web browser and use this URL to connect to CloudStack: :: - http://localhost:8080/client/ + http://localhost:8080/client/ Replace ``localhost`` with the IP of your management server if need be. -.. note:: If you have iptables enabled, you may have to open the ports used by CloudStack. Specifically, ports 8080, 8250, and 9090. +.. note:: + If you have iptables enabled, you may have to open the ports used by + CloudStack. Specifically, ports 8080, 8250, and 9090. You can now start configuring a Zone, playing with the API. Of course we did not setup any infrastructure, there is no storage, no @@ -272,6 +298,7 @@ hypervisors...etc. However you can run tests using the simulator. The following section shows you how to use the simulator so that you don't have to setup a physical infrastructure. + Using the Simulator ------------------- @@ -287,39 +314,39 @@ Do a clean build: :: - mvn -Pdeveloper -Dsimulator -DskipTests clean install + mvn -Pdeveloper -Dsimulator -DskipTests clean install Deploy the database: :: - mvn -Pdeveloper -pl developer -Ddeploydb - mvn -Pdeveloper -pl developer -Ddeploydb-simulator + mvn -Pdeveloper -pl developer -Ddeploydb + mvn -Pdeveloper -pl developer -Ddeploydb-simulator Install marvin. Note that you will need to have installed ``pip`` properly in the prerequisites step. :: - pip install tools/marvin/dist/Marvin-0.1.0.tar.gz + pip install tools/marvin/dist/Marvin-0.1.0.tar.gz Stop jetty (from any previous runs) :: - mvn -pl :cloud-client-ui jetty:stop + mvn -pl :cloud-client-ui jetty:stop Start jetty :: - mvn -pl client jetty:run + mvn -pl client jetty:run Setup a basic zone with Marvin. In a separate shell:// :: - mvn -Pdeveloper,marvin.setup -Dmarvin.config=setup/dev/basic.cfg -pl :cloud-marvin integration-test + mvn -Pdeveloper,marvin.setup -Dmarvin.config=setup/dev/basic.cfg -pl :cloud-marvin integration-test At this stage log in the CloudStack management server at http://localhost:8080/client with the credentials admin/password, you @@ -328,6 +355,7 @@ advanced zone replace ``basic.cfg`` with ``advanced.cfg``. You can now run integration tests, use the API etc... + Using DevCloud -------------- @@ -345,25 +373,26 @@ with the VirtualBox image. For KVM see the \*\* DevCloud Pre-requisites -1. Install `VirtualBox `__ on your machine +#. Install `VirtualBox `__ on your machine -2. Run VirtualBox and under >Preferences create a *host-only interface* +#. Run VirtualBox and under >Preferences create a *host-only interface* on which you disable the DHCP server -3. Download the DevCloud - `image `__ +#. Download the DevCloud `image + `__ -4. In VirtualBox, under File > Import Appliance import the DevCloud +#. In VirtualBox, under File > Import Appliance import the DevCloud image. -5. Verify the settings under > Settings and check the ``enable PAE`` +#. Verify the settings under > Settings and check the ``enable PAE`` option in the processor menu -6. Once the VM has booted try to ``ssh`` to it with credentials: +#. Once the VM has booted try to ``ssh`` to it with credentials: ``root/password`` ssh root@192.168.56.10 + Adding DevCloud as an Hypervisor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -371,28 +400,28 @@ Picking up from a clean build: :: - mvn -Pdeveloper,systemvm clean install - mvn -P developer -pl developer,tools/devcloud -Ddeploydb + mvn -Pdeveloper,systemvm clean install + mvn -P developer -pl developer,tools/devcloud -Ddeploydb At this stage install marvin similarly than with the simulator: :: - pip install tools/marvin/dist/Marvin-0.1.0.tar.gz + pip install tools/marvin/dist/Marvin-0.1.0.tar.gz Start the management server :: - mvn -pl client jetty:run + mvn -pl client jetty:run Then you are going to configure CloudStack to use the running DevCloud instance: :: - cd tools/devcloud - python ../marvin/marvin/deployDataCenter.py -i devcloud.cfg + cd tools/devcloud + python ../marvin/marvin/deployDataCenter.py -i devcloud.cfg If you are curious, check the ``devcloud.cfg`` file and see how the data center is defined: 1 Zone, 1 Pod, 1 Cluster, 1 Host, 1 primary Storage, @@ -407,6 +436,7 @@ that DevCloud is used only as a n Hypervisor. You could potentially run the management server within DevCloud as well, or memory granted, run multiple DevClouds. + Building Packages ----------------- @@ -425,35 +455,36 @@ not need to install for source compilation: :: - apt-get install python-mysqldb - apt-get install debhelper + apt-get install python-mysqldb + apt-get install debhelper Then build the packages with: :: - dpkg-buildpackage -uc -us + dpkg-buildpackage -uc -us One directory up from the CloudStack root dir you will find: :: - cloudstack_4.2.0_amd64.changes - cloudstack_4.2.0.dsc - cloudstack_4.2.0.tar.gz - cloudstack-agent_4.2.0_all.deb - cloudstack-awsapi_4.2.0_all.deb - cloudstack-cli_4.2.0_all.deb - cloudstack-common_4.2.0_all.deb - cloudstack-docs_4.2.0_all.deb - cloudstack-management_4.2.0_all.deb - cloudstack-usage_4.2.0_all.deb + cloudstack_4.2.0_amd64.changes + cloudstack_4.2.0.dsc + cloudstack_4.2.0.tar.gz + cloudstack-agent_4.2.0_all.deb + cloudstack-awsapi_4.2.0_all.deb + cloudstack-cli_4.2.0_all.deb + cloudstack-common_4.2.0_all.deb + cloudstack-docs_4.2.0_all.deb + cloudstack-management_4.2.0_all.deb + cloudstack-usage_4.2.0_all.deb Of course the community provides a repository for these packages and you can use it instead of building your own packages and putting them in your own repo. Instructions on how to use this community repository are available in the installation book. + The CloudStack API ------------------ @@ -498,8 +529,8 @@ using the ``Generate Keys`` icon. You will see an ``API Key`` and :: - API Key : XzAz0uC0t888gOzPs3HchY72qwDc7pUPIO8LxC-VkIHo4C3fvbEBY_Ccj8fo3mBapN5qRDg_0_EbGdbxi8oy1A - Secret Key: zmBOXAXPlfb-LIygOxUVblAbz7E47eukDS_0JYUxP3JAmknOYo56T0R-AcM7rK7SMyo11Y6XW22gyuXzOdiybQ + API Key : XzAz0uC0t888gOzPs3HchY72qwDc7pUPIO8LxC-VkIHo4C3fvbEBY_Ccj8fo3mBapN5qRDg_0_EbGdbxi8oy1A + Secret Key: zmBOXAXPlfb-LIygOxUVblAbz7E47eukDS_0JYUxP3JAmknOYo56T0R-AcM7rK7SMyo11Y6XW22gyuXzOdiybQ Open a Python shell and import the basic modules necessary to make the request. Do note that this request could be made many different ways, @@ -511,15 +542,15 @@ encoded using the ``base64`` module. :: - $python - Python 2.7.3 (default, Nov 17 2012, 19:54:34) - [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin - Type "help", "copyright", "credits" or "license" for more information. - >>> import urllib2 - >>> import urllib - >>> import hashlib - >>> import hmac - >>> import base64 + $python + Python 2.7.3 (default, Nov 17 2012, 19:54:34) + [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin + Type "help", "copyright", "credits" or "license" for more information. + >>> import urllib2 + >>> import urllib + >>> import hashlib + >>> import hmac + >>> import base64 Define the endpoint of the Cloud, the command that you want to execute, the type of the response (i.e XML or JSON) and the keys of the user. @@ -528,21 +559,21 @@ it is only used to compute the hmac. :: - >>> baseurl='http://localhost:8080/client/api?' - >>> request={} - >>> request['command']='listUsers' - >>> request['response']='json' - >>> request['apikey']='plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg' - >>> secretkey='VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ' + >>> baseurl='http://localhost:8080/client/api?' + >>> request={} + >>> request['command']='listUsers' + >>> request['response']='json' + >>> request['apikey']='plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg' + >>> secretkey='VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ' Build the base request string, the combination of all the key/pairs of the request, url encoded and joined with ampersand. :: - >>> request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()]) - >>> request_str - 'apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json' + >>> request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()]) + >>> request_str + 'apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json' Compute the signature with hmac, do a 64 bit encoding and a url encoding, the string used for the signature is similar to the base @@ -551,37 +582,53 @@ joined in a sorted order :: - >>> sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())]) - >>> sig_str - 'apikey=plgwjfzk4gys3momtvmjuvg-x-jlwlnfauj9gabbbf9edm-kaymmailqzzq1elzlyq_u38zcm0bewzgudp66mg&command=listusers&response=json' - >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest() - >>> sig - 'M:]\x0e\xaf\xfb\x8f\xf2y\xf1p\x91\x1e\x89\x8a\xa1\x05\xc4A\xdb' - >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()) - >>> sig - 'TTpdDq/7j/J58XCRHomKoQXEQds=\n' - >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip() - >>> sig - 'TTpdDq/7j/J58XCRHomKoQXEQds=' - >>> sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()) + >>> sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())]) + >>> sig_str + 'apikey=plgwjfzk4gys3momtvmjuvg-x-jlwlnfauj9gabbbf9edm-kaymmailqzzq1elzlyq_u38zcm0bewzgudp66mg&command=listusers&response=json' + >>> sig=hmac.new(secretkey,sig_str,hashlib.sha1).digest() + >>> sig + 'M:]\x0e\xaf\xfb\x8f\xf2y\xf1p\x91\x1e\x89\x8a\xa1\x05\xc4A\xdb' + >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()) + >>> sig + 'TTpdDq/7j/J58XCRHomKoQXEQds=\n' + >>> sig=base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip() + >>> sig + 'TTpdDq/7j/J58XCRHomKoQXEQds=' + >>> sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip()) Finally, build the entire string by joining the baseurl, the request str and the signature. Then do an http GET: :: - >>> req=baseurl+request_str+'&signature='+sig - >>> req - 'http://localhost:8080/client/api?apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json&signature=TTpdDq%2F7j%2FJ58XCRHomKoQXEQds%3D' - >>> res=urllib2.urlopen(req) - >>> res.read() - '{ "listusersresponse" : { "count":1 ,"user" : [ {"id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a","username":"admin","firstname":"admin", - "lastname":"cloud","created":"2012-07-05T12:18:27-0700","state":"enabled","account":"admin", - "accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT", - "apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg", - "secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ", - "accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}]}} - + >>> req=baseurl+request_str+'&signature='+sig + >>> req + 'http://localhost:8080/client/api?apikey=plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg&command=listUsers&response=json&signature=TTpdDq%2F7j%2FJ58XCRHomKoQXEQds%3D' + >>> res=urllib2.urlopen(req) + >>> res.read() + { + "listusersresponse" : { + "count":1 , + "user" : [ + { + "id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a", + "username":"admin", + "firstname":"admin", + "lastname":"cloud", + "created":"2012-07-05T12:18:27-0700", + "state":"enabled", + "account":"admin", + "accounttype":1, + "domainid":"8a111e58-e155-4482-93ce-84efff3c7c77", + "domain":"ROOT", + "apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg", + "secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ", + "accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d" + } + ] + } + } + All the clients that you will find on github will implement this signature technique, you should not have to do it by hand. Now that you @@ -592,6 +639,7 @@ is a sub-project of Apache CloudStack and gives operators/developers the ability to use any of the API methods. It has nice auto-completion and help feature as well as an API discovery mechanism since 4.2. + Testing the AWS API interface ----------------------------- @@ -608,7 +656,7 @@ start the AWS API interface in a separate shell with: :: - mvn -Pawsapi -pl :cloud-awsapi jetty:run + mvn -Pawsapi -pl :cloud-awsapi jetty:run Log into the CloudStack UI ``http://localhost:8080/client``, go to *Service Offerings* and edit one of the compute offerings to have the @@ -619,24 +667,25 @@ to use Python `Boto `__ module: :: - import boto - import boto.ec2 + import boto + import boto.ec2 - accesskey="2IUSA5xylbsPSnBQFoWXKg3RvjHgsufcKhC1SeiCbeEc0obKwUlwJamB_gFmMJkFHYHTIafpUx0pHcfLvt-dzw" - secretkey="oxV5Dhhk5ufNowey7OVHgWxCBVS4deTl9qL0EqMthfPBuy3ScHPo2fifDxw1aXeL5cyH10hnLOKjyKphcXGeDA" + accesskey="2IUSA5xylbsPSnBQFoWXKg3RvjHgsufcKhC1SeiCbeEc0obKwUlwJamB_gFmMJkFHYHTIafpUx0pHcfLvt-dzw" + secretkey="oxV5Dhhk5ufNowey7OVHgWxCBVS4deTl9qL0EqMthfPBuy3ScHPo2fifDxw1aXeL5cyH10hnLOKjyKphcXGeDA" - region = boto.ec2.regioninfo.RegionInfo(name="ROOT", endpoint="localhost") - conn = boto.connect_ec2(aws_access_key_id=accesskey, aws_secret_access_key=secretkey, is_secure=False, region=region, port=7080, path="/awsapi", api_version="2012-08-15") + region = boto.ec2.regioninfo.RegionInfo(name="ROOT", endpoint="localhost") + conn = boto.connect_ec2(aws_access_key_id=accesskey, aws_secret_access_key=secretkey, is_secure=False, region=region, port=7080, path="/awsapi", api_version="2012-08-15") - images=conn.get_all_images() - print images + images=conn.get_all_images() + print images - res = images[0].run(instance_type='m1.small',security_groups=['default']) + res = images[0].run(instance_type='m1.small',security_groups=['default']) Note the new ``api_version`` number in the connection object and also note that there was no user registration to make like in previous CloudStack releases. + Conclusions ----------- diff --git a/rtd/source/index.rst b/rtd/source/index.rst index 3972486..398a1f6 100644 --- a/rtd/source/index.rst +++ b/rtd/source/index.rst @@ -1,69 +1,97 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + .. CloudStack Documentation documentation master file, created by sphinx-quickstart on Sat Nov 2 11:17:30 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. + Welcome to CloudStack Documentation ! ===================================== .. figure:: /_static/images/acslogo.png - :align: center + :align: center -.. warning:: We are in the process of changing documentation format as well as hosting mechanism. - Please be patient with us as we migrate our entire documentation to this new setup. +.. warning:: + We are in the process of changing documentation format as well as hosting + mechanism. Please be patient with us as we migrate our entire documentation + to this new setup. .. toctree:: + Introduction ------------ -If you are new to CloudStack you should go through this short introduction on concepts and terminology before proceeding to the installation or administration guides. +If you are new to CloudStack you should go through this short introduction on +concepts and terminology before proceeding to the installation or +administration guides. .. toctree:: - :maxdepth: 2 + :maxdepth: 2 + + concepts - concepts Navigating the docs ------------------- -Now that you have gone over the basic concepts of CloudStack you are ready to dive into installation and operation documentation. +Now that you have gone over the basic concepts of CloudStack you are ready to +dive into installation and operation documentation. -- `Installation Guide `_ +- `Installation Guide + `_ -- `Administration Guide `_ +- `Administration Guide + `_ -- `Release Notes `_ +- `Release Notes + `_ -Below you will find very specific documentation on advanced networking_ which you can skip if you are just getting started. -Developers will also find below a short developers_ guide. +Below you will find very specific documentation on advanced networking_ which +you can skip if you are just getting started. Developers will also find below +a short developers_ guide. .. _networking: + Advanced Networking Guides -------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 2 - networking/nicira-plugin - networking/midonet - networking/vxlan.rst - networking/ovs-plugin - networking/ipv6 - networking/autoscale_without_netscaler.rst + networking/nicira-plugin + networking/midonet + networking/vxlan.rst + networking/ovs-plugin + networking/ipv6 + networking/autoscale_without_netscaler.rst .. _developers: + Developers Guide ---------------- .. toctree:: - :maxdepth: 2 - - developer_guide - dev - plugins - alloc.rst - ansible + :maxdepth: 2 + developer_guide + dev + plugins + alloc.rst + ansible diff --git a/rtd/source/networking/autoscale_without_netscaler.rst b/rtd/source/networking/autoscale_without_netscaler.rst index 9dbac42..b35eaaf 100644 --- a/rtd/source/networking/autoscale_without_netscaler.rst +++ b/rtd/source/networking/autoscale_without_netscaler.rst @@ -1,87 +1,177 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Configuring AutoScale without using NetScaler ============================================= -.. warning:: This feature is currently only available on the master branch and will be released in the 4.4 release. +.. warning:: + This feature is currently only available on the master branch and will be + released in the 4.4 release. + What is AutoScaling? -~~~~~~~~~~~~~~~~~~~~ +-------------------- + +AutoScaling allows you to scale your back-end services or application VMs up +or down seamlessly and automatically according to the conditions you define. +With AutoScaling enabled, you can ensure that the number of VMs you are using +seamlessly scale up when demand increases, and automatically decreases when +demand subsides. Thus it helps you save compute costs by terminating underused +VMs automatically and launching new VMs when you need them, without the need +for manual intervention. -AutoScaling allows you to scale your back-end services or application VMs up or down seamlessly and automatically according to the conditions you define. With AutoScaling enabled, you can ensure that the number of VMs you are using seamlessly scale up when demand increases, and automatically decreases when demand subsides. Thus it helps you save compute costs by terminating underused VMs automatically and launching new VMs when you need them, without the need for manual intervention. Hypervisor support -~~~~~~~~~~~~~~~~~~ +------------------ + +At that time, AutoScaling without NetScaler only supports for Xenserver. We +are working to support KVM also. -At that time, AutoScaling without NetScaler only supports for Xenserver. We are working to support KVM also. Prerequisites -~~~~~~~~~~~~~ +------------- Before you configure an AutoScale rule, consider the following: -* Ensure that the necessary template is prepared before configuring AutoScale. Firstly you must install the PV-driver, which helps Xenserver collect performance parameters (CPU and memory) into VMs. Beside, When a VM is deployed by using a template and when it comes up, the application should be up and running. +- Ensure that the necessary template is prepared before configuring AutoScale. + Firstly you must install the PV-driver, which helps Xenserver collect + performance parameters (CPU and memory) into VMs. Beside, When a VM is + deployed by using a template and when it comes up, the application should be + up and running. + Configuration -~~~~~~~~~~~~~ +------------- Specify the following: .. image:: ../_static/images/autoscale-config.png -* Template: A template consists of a base OS image and application. A template is used to provision the new instance of an application on a scaleup action. When a VM is deployed from a template, the VM can start taking the traffic from the load balancer without any admin intervention. For example, if the VM is deployed for a Web service, it should have the Web server running, the database connected, and so on. +- Template: A template consists of a base OS image and application. A + template is used to provision the new instance of an application on a + scaleup action. When a VM is deployed from a template, the VM can start + taking the traffic from the load balancer without any admin intervention. + For example, if the VM is deployed for a Web service, it should have the + Web server running, the database connected, and so on. + +- Compute offering: A predefined set of virtual hardware attributes, + including CPU speed, number of CPUs, and RAM size, that the user can select + when creating a new virtual machine instance. Choose one of the compute + offerings to be used while provisioning a VM instance as part of scaleup + action. + +- Min Instance: The minimum number of active VM instances that is assigned to + a load balancing rule. The active VM instances are the application + instances that are up and serving the traffic, and are being load balanced. + This parameter ensures that a load balancing rule has at least the + configured number of active VM instances are available to serve the traffic. + +- Max Instance: Maximum number of active VM instances that should be assigned + to a load balancing rule. This parameter defines the upper limit of active + VM instances that can be assigned to a load balancing rule. + + Specifying a large value for the maximum instance parameter might result in + provisioning large number of VM instances, which in turn leads to a single + load balancing rule exhausting the VM instances limit specified at the + account or domain level. -* Compute offering: A predefined set of virtual hardware attributes, including CPU speed, number of CPUs, and RAM size, that the user can select when creating a new virtual machine instance. Choose one of the compute offerings to be used while provisioning a VM instance as part of scaleup action. +Specify the following scale-up and scale-down policies: -* Min Instance: The minimum number of active VM instances that is assigned to a load balancing rule. The active VM instances are the application instances that are up and serving the traffic, and are being load balanced. This parameter ensures that a load balancing rule has at least the configured number of active VM instances are available to serve the traffic. +- Duration: The duration, in seconds, for which the conditions you specify + must be true to trigger a scaleup action. The conditions defined should + hold true for the entire duration you specify for an AutoScale action to be + invoked. -* Max Instance: Maximum number of active VM instances that should be assigned to a load balancing rule. This parameter defines the upper limit of active VM instances that can be assigned to a load balancing rule. +- Counter: The performance counters expose the state of the monitored + instances. We added two new counter to work with that feature: -Specifying a large value for the maximum instance parameter might result in provisioning large number of VM instances, which in turn leads to a single load balancing rule exhausting the VM instances limit specified at the account or domain level. + - Linux User CPU [native] - percentage + - Linux User RAM [native] - percentage -Specify the following scale-up and scale-down policies: + Remember to choose one of them. If you choose anything else, the + autoscaling will not work. -* Duration: The duration, in seconds, for which the conditions you specify must be true to trigger a scaleup action. The conditions defined should hold true for the entire duration you specify for an AutoScale action to be invoked. +- Operator: The following five relational operators are supported in + AutoScale feature: Greater than, Less than, Less than or equal to, Greater + than or equal to, and Equal to. -* Counter: The performance counters expose the state of the monitored instances. We added two new counter to work with that feature: +- Threshold: Threshold value to be used for the counter. Once the counter + defined above breaches the threshold value, the AutoScale feature initiates + a scaleup or scaledown action. -- Linux User CPU [native] - percentage -- Linux User RAM [native] - percentage +- Add: Click Add to add the condition. -Remember to choose one of them. If you choose anything else, the autoscaling will not work. + Additionally, if you want to configure the advanced settings, click Show + advanced settings, and specify the following: -* Operator: The following five relational operators are supported in AutoScale feature: Greater than, Less than, Less than or equal to, Greater than or equal to, and Equal to. +- Polling interval: Frequency in which the conditions, combination of counter, + operator and threshold, are to be evaluated before taking a scale up or + down action. The default polling interval is 30 seconds. -* Threshold: Threshold value to be used for the counter. Once the counter defined above breaches the threshold value, the AutoScale feature initiates a scaleup or scaledown action. +- Quiet Time: This is the cool down period after an AutoScale action is + initiated. The time includes the time taken to complete provisioning a VM + instance from its template and the time taken by an application to be ready + to serve traffic. This quiet time allows the fleet to come up to a stable + state before any action can take place. The default is 300 seconds. -* Add: Click Add to add the condition. +- Destroy VM Grace Period: The duration in seconds, after a scaledown action + is initiated, to wait before the VM is destroyed as part of scaledown + action. This is to ensure graceful close of any pending sessions or + transactions being served by the VM marked for destroy. The default is 120 + seconds. -Additionally, if you want to configure the advanced settings, click Show advanced settings, and specify the following: +- Apply: Click Apply to create the AutoScale configuration. -* Polling interval: Frequency in which the conditions, combination of counter, operator and threshold, are to be evaluated before taking a scale up or down action. The default polling interval is 30 seconds. -* Quiet Time: This is the cool down period after an AutoScale action is initiated. The time includes the time taken to complete provisioning a VM instance from its template and the time taken by an application to be ready to serve traffic. This quiet time allows the fleet to come up to a stable state before any action can take place. The default is 300 seconds. +Disabling and Enabling an AutoScale Configuration +------------------------------------------------- -* Destroy VM Grace Period: The duration in seconds, after a scaledown action is initiated, to wait before the VM is destroyed as part of scaledown action. This is to ensure graceful close of any pending sessions or transactions being served by the VM marked for destroy. The default is 120 seconds. +If you want to perform any maintenance operation on the AutoScale VM instances, +disable the AutoScale configuration. When the AutoScale configuration is +disabled, no scaleup or scaledown action is performed. You can use this +downtime for the maintenance activities. To disable the AutoScale +configuration, click the Disable AutoScale button. -* Apply: Click Apply to create the AutoScale configuration. +The button toggles between enable and disable, depending on whether AutoScale +is currently enabled or not. After the maintenance operations are done, you +can enable the AutoScale configuration back. To enable, open the AutoScale +configuration page again, then click the Enable AutoScale button. -Disabling and Enabling an AutoScale Configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you want to perform any maintenance operation on the AutoScale VM instances, disable the AutoScale configuration. When the AutoScale configuration is disabled, no scaleup or scaledown action is performed. You can use this downtime for the maintenance activities. To disable the AutoScale configuration, click the Disable AutoScale button. +Updating an AutoScale Configuration +----------------------------------- -The button toggles between enable and disable, depending on whether AutoScale is currently enabled or not. After the maintenance operations are done, you can enable the AutoScale configuration back. To enable, open the AutoScale configuration page again, then click the Enable AutoScale button. +You can update the various parameters and add or delete the conditions in a +scaleup or scaledown rule. Before you update an AutoScale configuration, +ensure that you disable the AutoScale load balancer rule by clicking the +Disable AutoScale button. -Updating an AutoScale Configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +After you modify the required AutoScale parameters, click Apply. To apply the +new AutoScale policies, open the AutoScale configuration page again, then +click the Enable AutoScale button. -You can update the various parameters and add or delete the conditions in a scaleup or scaledown rule. Before you update an AutoScale configuration, ensure that you disable the AutoScale load balancer rule by clicking the Disable AutoScale button. -After you modify the required AutoScale parameters, click Apply. To apply the new AutoScale policies, open the AutoScale configuration page again, then click the Enable AutoScale button. Runtime Considerations -~~~~~~~~~~~~~~~~~~~~~~ - -An administrator should not assign a VM to a load balancing rule which is configured for AutoScale. +---------------------- -Making API calls outside the context of AutoScale, such as destroyVM, on an autoscaled VM leaves the load balancing configuration in an inconsistent state. Though VM is destroyed from the load balancer rule, it continues be showed as a service assigned to a rule inside the context of AutoScale. +An administrator should not assign a VM to a load balancing rule which is +configured for AutoScale. +Making API calls outside the context of AutoScale, such as destroyVM, on an +autoscaled VM leaves the load balancing configuration in an inconsistent state. +Though VM is destroyed from the load balancer rule, it continues be showed as +a service assigned to a rule inside the context of AutoScale. diff --git a/rtd/source/networking/ipv6.rst b/rtd/source/networking/ipv6.rst index 2e5a1b6..117fdc2 100644 --- a/rtd/source/networking/ipv6.rst +++ b/rtd/source/networking/ipv6.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + IPv6 Support in CloudStack =========================== @@ -19,17 +35,11 @@ support is only an experimental feature. Here's the sequence of events when IPv6 is used: -#. - - The administrator creates an IPv6 shared network in an advanced zone. - -#. +#. The administrator creates an IPv6 shared network in an advanced zone. - The user deploys a VM in an IPv6 shared network. +#. The user deploys a VM in an IPv6 shared network. -#. - - The user VM generates an IPv6 link local address by itself, and gets +#. The user VM generates an IPv6 link local address by itself, and gets an IPv6 global or site local address through DHCPv6. @@ -38,48 +48,38 @@ Prerequisites and Guidelines Consider the following: -- - - CIDR size must be 64 for IPv6 networks. - -- +- CIDR size must be 64 for IPv6 networks. - The DHCP client of the guest VMs should support generating DUID based +- The DHCP client of the guest VMs should support generating DUID based on Link-layer Address (DUID- LL). DUID-LL derives from the MAC address of guest VMs, and therefore the user VM can be identified by using DUID. See `Dynamic Host Configuration Protocol for IPv6 `__\ for more information. -- - - The gateway of the guest network generates Router Advisement and +- The gateway of the guest network generates Router Advisement and Response messages to Router Solicitation. The M (Managed Address Configuration) flag of Router Advisement should enable stateful IP address configuration. Set the M flag to where the end nodes receive their IPv6 addresses from the DHCPv6 server as opposed to the router or switch. - .. note:: The M flag is the 1-bit Managed Address Configuration flag for Router - Advisement. When set, Dynamic Host Configuration Protocol (DHCPv6) is - available for address configuration in addition to any IPs set by - using stateless address auto-configuration. - -- + .. note:: + The M flag is the 1-bit Managed Address Configuration flag for Router + Advisement. When set, Dynamic Host Configuration Protocol (DHCPv6) is + available for address configuration in addition to any IPs set by + using stateless address auto-configuration. - Use the System VM template exclusively designed to support IPv6. +- Use the System VM template exclusively designed to support IPv6. Download the System VM template from - `http://cloudstack.apt-get.eu/systemvm/ `__. - -- + `http://cloudstack.apt-get.eu/systemvm/ + `__. - The concept of Default Network applies to IPv6 networks. However, +- The concept of Default Network applies to IPv6 networks. However, unlike IPv4 CloudStack does not control the routing information of IPv6 in shared network; the choice of Default Network will not affect the routing in the user VM. -- - - In a multiple shared network, the default route is set by the rack +- In a multiple shared network, the default route is set by the rack router, rather than the DHCP server, which is out of CloudStack control. Therefore, in order for the user VM to get only the default route from the default NIC, modify the configuration of the user VM, @@ -88,22 +88,18 @@ Consider the following: auto-configure ``/proc/sys/net/ipv6/conf/interface`` with received data. + Limitations of IPv6 in CloudStack --------------------------------- The following are not yet supported: -#. - - Security groups +#. Security groups -#. +#. Userdata and metadata - Userdata and metadata +#. Passwords -#. - - Passwords Guest VM Configuration for DHCPv6 --------------------------------- @@ -111,114 +107,93 @@ Guest VM Configuration for DHCPv6 For the guest VMs to get IPv6 address, run dhclient command manually on each of the VMs. Use DUID-LL to set up dhclient. -.. note:: The IPv6 address is lost when a VM is stopped and started. Therefore, -use the same procedure to get an IPv6 address when a VM is stopped and -started. - -#. +.. note:: + The IPv6 address is lost when a VM is stopped and started. Therefore, + use the same procedure to get an IPv6 address when a VM is stopped and + started. - Set up dhclient by using DUID-LL. +#. Set up dhclient by using DUID-LL. Perform the following for DHCP Client 4.2 and above: - #. - - Run the following command on the selected VM to get the dhcpv6 + #. Run the following command on the selected VM to get the dhcpv6 offer from VR: .. sourcecode:: bash - dhclient -6 -D LL + dhclient -6 -D LL Perform the following for DHCP Client 4.1: - #. - - Open the following to the dhclient configuration file: + #. Open the following to the dhclient configuration file: .. sourcecode:: bash - vi /etc/dhcp/dhclient.conf - - #. + vi /etc/dhcp/dhclient.conf - Add the following to the dhclient configuration file: + #. Add the following to the dhclient configuration file: .. sourcecode:: bash - send dhcp6.client-id = concat(00:03:00, hardware); - -#. + send dhcp6.client-id = concat(00:03:00, hardware); - Get IPv6 address from DHCP server as part of the system or network +#. Get IPv6 address from DHCP server as part of the system or network restart. Based on the operating systems, perform the following: On CentOS 6.2: - #. - - Open the Ethernet interface configuration file: + #. Open the Ethernet interface configuration file: .. sourcecode:: bash - vi /etc/sysconfig/network-scripts/ifcfg-eth0 + vi /etc/sysconfig/network-scripts/ifcfg-eth0 The ``ifcfg-eth0`` file controls the first NIC in a system. - #. - - Make the necessary configuration changes, as given below: + #. Make the necessary configuration changes, as given below: .. sourcecode:: bash - DEVICE=eth0 - HWADDR=06:A0:F0:00:00:38 - NM_CONTROLLED=no - ONBOOT=yes - BOOTPROTO=dhcp6 - TYPE=Ethernet - USERCTL=no - PEERDNS=yes - IPV6INIT=yes - DHCPV6C=yes - - #. + DEVICE=eth0 + HWADDR=06:A0:F0:00:00:38 + NM_CONTROLLED=no + ONBOOT=yes + BOOTPROTO=dhcp6 + TYPE=Ethernet + USERCTL=no + PEERDNS=yes + IPV6INIT=yes + DHCPV6C=yes - Open the following: + #. Open the following: .. sourcecode:: bash - vi /etc/sysconfig/network + vi /etc/sysconfig/network - #. - - Make the necessary configuration changes, as given below: + #. Make the necessary configuration changes, as given below: .. sourcecode:: bash - NETWORKING=yes - HOSTNAME=centos62mgmt.lab.vmops.com - NETWORKING_IPV6=yes - IPV6_AUTOCONF=no + NETWORKING=yes + HOSTNAME=centos62mgmt.lab.vmops.com + NETWORKING_IPV6=yes + IPV6_AUTOCONF=no On Ubuntu 12.10 - #. - - Open the following: + #. Open the following: .. sourcecode:: bash - etc/network/interfaces: - - #. + etc/network/interfaces: - Make the necessary configuration changes, as given below: + #. Make the necessary configuration changes, as given below: .. sourcecode:: bash - iface eth0 inet6 dhcp - autoconf 0 - accept_ra 1 + iface eth0 inet6 dhcp + autoconf 0 + accept_ra 1 diff --git a/rtd/source/networking/midonet.rst b/rtd/source/networking/midonet.rst index 73d7ab2..a82fa44 100644 --- a/rtd/source/networking/midonet.rst +++ b/rtd/source/networking/midonet.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + The MidoNet Plugin ================== @@ -9,11 +25,13 @@ networking solution as a provider for CloudStack networks and services. For more information on MidoNet and how it works, see http://www.midokura.com/midonet/. + Features of the MidoNet Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. note:: In CloudStack 4.2.0 only the KVM hypervisor is supported for use in - combination with MidoNet. +.. note:: + In CloudStack 4.2.0 only the KVM hypervisor is supported for use in + combination with MidoNet. In CloudStack release 4.2.0 this plugin supports several services in the Advanced Isolated network mode. @@ -39,6 +57,7 @@ supported in the 4.2.0 release: The plugin has been tested with MidoNet version 12.12. (Caddo). + Using the MidoNet Plugin ------------------------ @@ -50,11 +69,11 @@ the MidoNet Agent, and the MidoNet API server must be available. Please consult the MidoNet User Guide for more information. The following section describes the CloudStack side setup. -1. CloudStack needs to have at least one physical network with the +#. CloudStack needs to have at least one physical network with the isolation method set to "MIDO". This network should be enabled for the Guest and Public traffic types. -2. Next, we need to set the following CloudStack settings under "Global +#. Next, we need to set the following CloudStack settings under "Global Settings" in the UI: +-----------------------------+------------------------------------------------------------------------+--------------------------------------------+ @@ -67,33 +86,35 @@ section describes the CloudStack side setup. Table: CloudStack settings -3. We also want MidoNet to take care of public traffic, so in +#. We also want MidoNet to take care of public traffic, so in *componentContext.xml* we need to replace this line: :: - + With this: :: - + -.. note:: On the compute host, MidoNet takes advantage of per-traffic type VIF - driver support in CloudStack KVM. +.. note:: + On the compute host, MidoNet takes advantage of per-traffic type VIF + driver support in CloudStack KVM. - In agent.properties, we set the following to make MidoNet take care - of Guest and Public traffic: + In agent.properties, we set the following to make MidoNet take care + of Guest and Public traffic: - :: + :: + + libvirt.vif.driver.Guest=com.cloud.network.resource.MidoNetVifDriver + libvirt.vif.driver.Public=com.cloud.network.resource.MidoNetVifDriver - libvirt.vif.driver.Guest=com.cloud.network.resource.MidoNetVifDriver - libvirt.vif.driver.Public=com.cloud.network.resource.MidoNetVifDriver + This is explained further in MidoNet User Guide. - This is explained further in MidoNet User Guide. Enabling the MidoNet service provider via the UI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -103,21 +124,22 @@ needs to be enabled on the physical network. The steps to enable via the UI are as follows: -1. In the left navbar, click Infrastructure +#. In the left navbar, click Infrastructure -2. In Zones, click View All +#. In Zones, click View All -3. Click the name of the Zone on which you are setting up MidoNet +#. Click the name of the Zone on which you are setting up MidoNet -4. Click the Physical Network tab +#. Click the Physical Network tab -5. Click the Name of the Network on which you are setting up MidoNet +#. Click the Name of the Network on which you are setting up MidoNet -6. Click Configure on the Network Service Providers box +#. Click Configure on the Network Service Providers box -7. Click on the name MidoNet +#. Click on the name MidoNet + +#. Click the Enable Provider button in the Network tab -8. Click the Enable Provider button in the Network tab Enabling the MidoNet service provider via the API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -136,6 +158,7 @@ To enable via the API, use the following API calls: - state = "Enabled" + Revision History ---------------- diff --git a/rtd/source/networking/nicira-plugin.rst b/rtd/source/networking/nicira-plugin.rst index b644f16..cbff59c 100644 --- a/rtd/source/networking/nicira-plugin.rst +++ b/rtd/source/networking/nicira-plugin.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + The Nicira NVP Plugin ===================== @@ -9,6 +25,7 @@ implementations in CloudStack. With the plugin an exisiting Nicira NVP setup can be used by CloudStack to implement isolated guest networks and to provide additional services like routing and NAT. + Features of the Nicira NVP Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -29,8 +46,9 @@ the Nicira NVP Plugin. Table: Supported Services -.. note:: The Virtual Networking service was originally called 'Connectivity' - in CloudStack 4.0 +.. note:: + The Virtual Networking service was originally called 'Connectivity' + in CloudStack 4.0 The following hypervisors are supported by the Nicira NVP Plugin. @@ -44,8 +62,10 @@ The following hypervisors are supported by the Nicira NVP Plugin. Table: Supported Hypervisors -.. note:: Please refer to the Nicira NVP configuration guide on how to prepare - the hypervisors for Nicira NVP integration. +.. note:: + Please refer to the Nicira NVP configuration guide on how to prepare + the hypervisors for Nicira NVP integration. + Configuring the Nicira NVP Plugin --------------------------------- @@ -71,8 +91,10 @@ Make sure you have the following information ready: services. -.. note:: The gateway service uuid is optional and is used for Layer 3 - services only (SourceNat, StaticNat and PortForwarding) +.. note:: + The gateway service uuid is optional and is used for Layer 3 + services only (SourceNat, StaticNat and PortForwarding) + Zone Configuration ~~~~~~~~~~~~~~~~~~ @@ -81,14 +103,16 @@ CloudStack needs to have at least one physical network with the isolation method set to "STT". This network should be enabled for the Guest traffic type. -.. note:: The Guest traffic type should be configured with the traffic label - that matches the name of the Integration Bridge on the hypervisor. - See the Nicira NVP User Guide for more details on how to set this up - in XenServer or KVM. +.. note:: + The Guest traffic type should be configured with the traffic label + that matches the name of the Integration Bridge on the hypervisor. + See the Nicira NVP User Guide for more details on how to set this up + in XenServer or KVM. .. figure:: /_static/images/nvp-physical-network-stt.png - :align: center - :alt: a screenshot of a physical network with the STT isolation type + :align: center + :alt: a screenshot of a physical network with the STT isolation type + Enabling the service provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -98,13 +122,15 @@ Service Providers" configuration of the physical network with the STT isolation type. Navigate to the Nicira NVP provider and press the "Enable Provider" button. -.. note:: CloudStack 4.0 does not have the UI interface to configure the - Nicira NVP plugin. Configuration needs to be done using the API - directly. +.. note:: + CloudStack 4.0 does not have the UI interface to configure the + Nicira NVP plugin. Configuration needs to be done using the API + directly. .. figure:: /_static/images/nvp-physical-network-stt.png - :align: center - :alt: a screenshot of an enabled Nicira NVP provider + :align: center + :alt: a screenshot of an enabled Nicira NVP provider + Device Management ~~~~~~~~~~~~~~~~~ @@ -116,8 +142,9 @@ network. Press the "Add NVP Controller" button on the provider panel and enter the configuration details. .. figure:: /_static/images/nvp-physical-network-stt.png - :align: center - :alt: a screenshot of the device configuration popup. + :align: center + :alt: a screenshot of the device configuration popup. + Network Offerings ~~~~~~~~~~~~~~~~~ @@ -155,12 +182,13 @@ Table: Isolated network offering with regular services from the Virtual Router. .. figure:: /_static/images/nvp-physical-network-stt.png - :align: center - :alt: a screenshot of a network offering. + :align: center + :alt: a screenshot of a network offering. -.. note:: The tag in the network offering should be set to the name of the - physical network with the NVP provider. +.. note:: + The tag in the network offering should be set to the name of the + physical network with the NVP provider. Isolated network with network services. The virtual router is still required to provide network services like dns and dhcp. @@ -185,6 +213,7 @@ required to provide network services like dns and dhcp. Table: Isolated network offering with network services + Using the Nicira NVP plugin with VPC ------------------------------------ @@ -201,6 +230,7 @@ Router It is not possible to connect a private gateway using a Nicira NVP Logical Switch + VPC Offering with Nicira NVP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -221,13 +251,15 @@ to the 'vpc\_offering\_service\_map' with service 'Connectivity' and provider 'NiciraNvp' .. figure:: /_static/images/nvp-physical-network-stt.png - :align: center - :alt: a screenshot of the mysql table. + :align: center + :alt: a screenshot of the mysql table. -.. note:: When creating a new VPC offering please note that the UI does not - allow you to select a VPC offering yet. The VPC needs to be created - using the API with the offering UUID. +.. note:: + When creating a new VPC offering please note that the UI does not + allow you to select a VPC offering yet. The VPC needs to be created + using the API with the offering UUID. + VPC Network Offerings ~~~~~~~~~~~~~~~~~~~~~ @@ -267,6 +299,7 @@ with the loadbalancing service enabled and one without loadbalancing. Table: VPC Network Offering with Loadbalancing + Troubleshooting the Nicira NVP Plugin ------------------------------------- @@ -284,9 +317,11 @@ network on the NVP Controller. The Nics that are connected to one of the Logical Switches will have their Logical Switch Port UUID listed in the nicira\_nvp\_nic\_map table -.. note:: All devices created on the NVP Controller will have a tag set to - domain-account of the owner of the network, this string can be used - to search for items in the NVP Controller. +.. note:: + All devices created on the NVP Controller will have a tag set to + domain-account of the owner of the network, this string can be used + to search for items in the NVP Controller. + Database tables ~~~~~~~~~~~~~~~ @@ -332,7 +367,9 @@ Table: external\_nicira\_nvp\_devices Table: nicira\_nvp\_router\_map -.. note:: nicira\_nvp\_router\_map is only available in CloudStack 4.1 and above +.. note:: + nicira\_nvp\_router\_map is only available in CloudStack 4.1 and above + Revision History ---------------- @@ -341,6 +378,7 @@ Revision History for 4.0.0-incubating version of the NVP Plugin 1-0 Wed May 22 2013 Hugo Trippaers hugo@apache.org Documentation updated for CloudStack 4.1.0 + .. | nvp-physical-network-stt.png: a screenshot of a physical network with the STT isolation type | image:: ./images/nvp-physical-network-stt.png .. | nvp-physical-network-stt.png: a screenshot of an enabled Nicira NVP provider | image:: ./images/nvp-enable-provider.png .. | nvp-physical-network-stt.png: a screenshot of the device configuration popup. | image:: ./images/nvp-add-controller.png diff --git a/rtd/source/networking/ovs-plugin.rst b/rtd/source/networking/ovs-plugin.rst index 495b304..90892b5 100644 --- a/rtd/source/networking/ovs-plugin.rst +++ b/rtd/source/networking/ovs-plugin.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + The OVS Plugin ============== @@ -5,8 +21,10 @@ Introduction to the OVS Plugin ------------------------------ The OVS plugin is the native SDN -implementations in CloudStack, using GRE isolation method. The plugin can be used by CloudStack to implement isolated guest networks and -to provide additional services like NAT, port forwarding and load balancing. +implementations in CloudStack, using GRE isolation method. The plugin can be +used by CloudStack to implement isolated guest networks and to provide +additional services like NAT, port forwarding and load balancing. + Features of the OVS Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,8 +46,9 @@ the OVS Plugin. Table: Supported Services -.. note:: The Virtual Networking service was originally called 'Connectivity' - in CloudStack 4.0 +.. note:: + The Virtual Networking service was originally called 'Connectivity' + in CloudStack 4.0 The following hypervisors are supported by the OVS Plugin. @@ -50,12 +69,20 @@ Configuring the OVS Plugin Prerequisites ~~~~~~~~~~~~~ -Before enabling the OVS plugin the hypervisor needs to be install OpenvSwitch. Default, XenServer has already installed OpenvSwitch. However, you must install OpenvSwitch manually on KVM. CentOS 6.4 and OpenvSwitch 1.10 are recommended. +Before enabling the OVS plugin the hypervisor needs to be install OpenvSwitch. +Default, XenServer has already installed OpenvSwitch. However, you must +install OpenvSwitch manually on KVM. CentOS 6.4 and OpenvSwitch 1.10 are +recommended. KVM hypervisor: -- CentOS 6.4 is recommended. -- To make sure that the native bridge module will not interfere with openvSwitch the bridge module should be added to the blacklist. See the modprobe documentation for your distribution on where to find the blacklist. Make sure the module is not loaded either by rebooting or executing rmmod bridge before executing next steps. +- CentOS 6.4 is recommended. + +- To make sure that the native bridge module will not interfere with + openvSwitch the bridge module should be added to the blacklist. See the + modprobe documentation for your distribution on where to find the blacklist. + Make sure the module is not loaded either by rebooting or executing rmmod + bridge before executing next steps. Zone Configuration @@ -66,76 +93,82 @@ method set to “GRE”. This network should be enabled for the Guest traffic type. .. note:: - With KVM, the traffic type should be configured with the traffic label - that matches the name of the Integration Bridge on the hypervisor. For example, you should set the traffic label as following: - - Management & Storage traffic: cloudbr0 - - Guest & Public traffic: cloudbr1 - See KVM networking configuration guide for more detail. + With KVM, the traffic type should be configured with the traffic label + that matches the name of the Integration Bridge on the hypervisor. For + example, you should set the traffic label as following: + + - Management & Storage traffic: cloudbr0 + + - Guest & Public traffic: cloudbr1 + See KVM networking configuration guide for more detail. .. figure:: /_static/images/ovs-physical-network-gre.png - :align: center - :alt: a screenshot of a physical network with the GRE isolation type + :align: center + :alt: a screenshot of a physical network with the GRE isolation type + Agent Configuration ~~~~~~~~~~~~~~~~~~~ -.. note:: Only for KVM hypervisor - -* Configure network interfaces: - -:: - - /etc/sysconfig/network-scripts/ifcfg-eth0 - DEVICE=eth0 - BOOTPROTO=none - IPV6INIT=no - NM_CONTROLLED=no - ONBOOT=yes - TYPE=OVSPort - DEVICETYPE=ovs - OVS_BRIDGE=cloudbr0 - - /etc/sysconfig/network-scripts/ifcfg-eth1 - DEVICE=eth1 - BOOTPROTO=none - IPV6INIT=no - NM_CONTROLLED=no - ONBOOT=yes - TYPE=OVSPort - DEVICETYPE=ovs - OVS_BRIDGE=cloudbr1 - - /etc/sysconfig/network-scripts/ifcfg-cloudbr0 - DEVICE=cloudbr0 - ONBOOT=yes - DEVICETYPE=ovs - TYPE=OVSBridge - BOOTPROTO=static - IPADDR=172.16.10.10 - GATEWAY=172.16.10.1 - NETMASK=255.255.255.0 - HOTPLUG=no - - /etc/sysconfig/network-scripts/ifcfg-cloudbr1 - DEVICE=cloudbr1 - ONBOOT=yes - DEVICETYPE=ovs - TYPE=OVSBridge - BOOTPROTO=none - HOTPLUG=no - - /etc/sysconfig/network - NETWORKING=yes - HOSTNAME=testkvm1 - GATEWAY=172.10.10.1 - -* Edit /etc/cloudstack/agent/agent.properties - -:: - - network.bridge.type=openvswitch - libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.OvsVifDriver +.. note:: + Only for KVM hypervisor + +- Configure network interfaces: + + :: + + /etc/sysconfig/network-scripts/ifcfg-eth0 + DEVICE=eth0 + BOOTPROTO=none + IPV6INIT=no + NM_CONTROLLED=no + ONBOOT=yes + TYPE=OVSPort + DEVICETYPE=ovs + OVS_BRIDGE=cloudbr0 + + /etc/sysconfig/network-scripts/ifcfg-eth1 + DEVICE=eth1 + BOOTPROTO=none + IPV6INIT=no + NM_CONTROLLED=no + ONBOOT=yes + TYPE=OVSPort + DEVICETYPE=ovs + OVS_BRIDGE=cloudbr1 + + /etc/sysconfig/network-scripts/ifcfg-cloudbr0 + DEVICE=cloudbr0 + ONBOOT=yes + DEVICETYPE=ovs + TYPE=OVSBridge + BOOTPROTO=static + IPADDR=172.16.10.10 + GATEWAY=172.16.10.1 + NETMASK=255.255.255.0 + HOTPLUG=no + + /etc/sysconfig/network-scripts/ifcfg-cloudbr1 + DEVICE=cloudbr1 + ONBOOT=yes + DEVICETYPE=ovs + TYPE=OVSBridge + BOOTPROTO=none + HOTPLUG=no + + /etc/sysconfig/network + NETWORKING=yes + HOSTNAME=testkvm1 + GATEWAY=172.10.10.1 + +- Edit /etc/cloudstack/agent/agent.properties + + :: + + network.bridge.type=openvswitch + libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.OvsVifDriver + Enabling the service provider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -146,8 +179,9 @@ isolation type. Navigate to the OVS provider and press the "Enable Provider" button. .. figure:: /_static/images/ovs-physical-network-gre-enable.png - :align: center - :alt: a screenshot of an enabled OVS provider + :align: center + :alt: a screenshot of an enabled OVS provider + Network Offerings ~~~~~~~~~~~~~~~~~ @@ -168,29 +202,30 @@ OVS plugin. +----------------------+-----------------+ | Firewall | VirtualRouter | +----------------------+-----------------+ -| Load Balancer | OVS | +| Load Balancer | OVS | +----------------------+-----------------+ | User Data | VirtualRouter | +----------------------+-----------------+ | Source NAT | VirtualRouter | +----------------------+-----------------+ -| Static NAT | OVS | +| Static NAT | OVS | +----------------------+-----------------+ -| Post Forwarding | OVS | +| Post Forwarding | OVS | +----------------------+-----------------+ -| Virtual Networking | OVS | +| Virtual Networking | OVS | +----------------------+-----------------+ Table: Isolated network offering with regular services from the Virtual Router. .. figure:: /_static/images/ovs-network-offering.png - :align: center - :alt: a screenshot of a network offering. + :align: center + :alt: a screenshot of a network offering. -.. note:: The tag in the network offering should be set to the name of the - physical network with the OVS provider. +.. note:: + The tag in the network offering should be set to the name of the + physical network with the OVS provider. Isolated network with network services. The virtual router is still required to provide network services like dns and dhcp. @@ -206,22 +241,24 @@ required to provide network services like dns and dhcp. +----------------------+-----------------+ | Source NAT | VirtualRouter | +----------------------+-----------------+ -| Static NAT | OVS | +| Static NAT | OVS | +----------------------+-----------------+ -| Post Forwarding | OVS | +| Post Forwarding | OVS | +----------------------+-----------------+ -| Load Balancing | OVS | +| Load Balancing | OVS | +----------------------+-----------------+ -| Virtual Networking | OVS | +| Virtual Networking | OVS | +----------------------+-----------------+ Table: Isolated network offering with network services + Using the OVS plugin with VPC ----------------------------- OVS plugin does not work with VPC at that time + Revision History ---------------- diff --git a/rtd/source/networking/vxlan.rst b/rtd/source/networking/vxlan.rst index 24520a3..d3b54a8 100644 --- a/rtd/source/networking/vxlan.rst +++ b/rtd/source/networking/vxlan.rst @@ -1,3 +1,19 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + The VXLAN Plugin ================ @@ -21,6 +37,7 @@ The following table lists the requirements for the hypervisor. Table: Hypervisor Requirement for VXLAN + Linux Distributions that meet the requirements ---------------------------------------------- @@ -39,6 +56,7 @@ The following table lists distributions which meet requirements. Table: List of Linux distributions which meet the hypervisor requirements + Check the capability of your system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -46,13 +64,13 @@ To check the capability of your system, execute the following commands. :: - $ sudo modprobe vxlan && echo $? - # Confirm the output is "0". - # If it's non-0 value or error message, your kernel doesn't have VXLAN kernel module. + $ sudo modprobe vxlan && echo $? + # Confirm the output is "0". + # If it's non-0 value or error message, your kernel doesn't have VXLAN kernel module. - $ ip link add type vxlan help - # Confirm the output is usage of the command and that it's for VXLAN. - # If it's not, your iproute2 utility doesn't support VXLAN. + $ ip link add type vxlan help + # Confirm the output is usage of the command and that it's for VXLAN. + # If it's not, your iproute2 utility doesn't support VXLAN. Advanced: Build kernel and iproute2 @@ -62,54 +80,55 @@ Even if your system doesn't support VXLAN, you can compile the kernel and iproute2 by yourself. The following procedure is an example for CentOS 6.4. + Build kernel ^^^^^^^^^^^^ :: - $ sudo yum groupinstall "Development Tools" - $ sudo yum install ncurses-devel hmaccalc zlib-devel binutils-devel elfutils-libelf-devel bc - - $ KERNEL_VERSION=3.10.4 - # Declare the kernel version you want to build. - - $ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-${KERNEL_VERSION}.tar.xz - $ tar xvf linux-${KERNEL_VERSION}.tar.xz - $ cd linux-${KERNEL_VERSION} - $ cp /boot/config-`uname -r` .config - $ make oldconfig - # You may keep hitting enter and choose the default. - - $ make menuconfig - # Dig into "Device Drivers" -> "Network device support", - # then select "Virtual eXtensible Local Area Network (VXLAN)" and hit space. - # Make sure it indicates "" (build as module), then Save and Exit. - - # You may also want to check "IPv4 NAT" and its child nodes in "IP: Netfilter Configuration" - # and "IPv6 NAT" and its child nodes in "IPv6: Netfilter Configuration". - # In 3.10.4, you can find the options in - # "Networking support" -> "Networking options" - # -> "Network packet filtering framework (Netfilter)". - - $ make # -j N - # You may use -j N option to make the build process parallel and faster, - # generally N = 1 + (cores your machine have). - - $ sudo make modules_install - $ sudo make install - # You would get an error like "ERROR: modinfo: could not find module XXXX" here. - # This happens mainly due to config structure changes between kernel versions. - # You can ignore this error, until you find you need the kernel module. - # If you feel uneasy, you can go back to make menuconfig, - # find module XXXX by using '/' key, enable the module, build and install the kernel again. - - $ sudo vi /etc/grub.conf - # Make sure the new kernel isn't set as the default and the timeout is long enough, - # so you can select the new kernel during boot process. - # It's not a good idea to set the new kernel as the default until you confirm the kernel works fine. - - $ sudo reboot - # Select the new kernel during the boot process. + $ sudo yum groupinstall "Development Tools" + $ sudo yum install ncurses-devel hmaccalc zlib-devel binutils-devel elfutils-libelf-devel bc + + $ KERNEL_VERSION=3.10.4 + # Declare the kernel version you want to build. + + $ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-${KERNEL_VERSION}.tar.xz + $ tar xvf linux-${KERNEL_VERSION}.tar.xz + $ cd linux-${KERNEL_VERSION} + $ cp /boot/config-`uname -r` .config + $ make oldconfig + # You may keep hitting enter and choose the default. + + $ make menuconfig + # Dig into "Device Drivers" -> "Network device support", + # then select "Virtual eXtensible Local Area Network (VXLAN)" and hit space. + # Make sure it indicates "" (build as module), then Save and Exit. + + # You may also want to check "IPv4 NAT" and its child nodes in "IP: Netfilter Configuration" + # and "IPv6 NAT" and its child nodes in "IPv6: Netfilter Configuration". + # In 3.10.4, you can find the options in + # "Networking support" -> "Networking options" + # -> "Network packet filtering framework (Netfilter)". + + $ make # -j N + # You may use -j N option to make the build process parallel and faster, + # generally N = 1 + (cores your machine have). + + $ sudo make modules_install + $ sudo make install + # You would get an error like "ERROR: modinfo: could not find module XXXX" here. + # This happens mainly due to config structure changes between kernel versions. + # You can ignore this error, until you find you need the kernel module. + # If you feel uneasy, you can go back to make menuconfig, + # find module XXXX by using '/' key, enable the module, build and install the kernel again. + + $ sudo vi /etc/grub.conf + # Make sure the new kernel isn't set as the default and the timeout is long enough, + # so you can select the new kernel during boot process. + # It's not a good idea to set the new kernel as the default until you confirm the kernel works fine. + + $ sudo reboot + # Select the new kernel during the boot process. Build iproute2 @@ -117,22 +136,23 @@ Build iproute2 :: - $ sudo yum install db4-devel + $ sudo yum install db4-devel - $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git - $ cd iproute2 - $ git tag - # Find the version that matches the kernel. - # If you built kernel 3.10.4 as above, it would be v3.10.0. + $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git + $ cd iproute2 + $ git tag + # Find the version that matches the kernel. + # If you built kernel 3.10.4 as above, it would be v3.10.0. - $ git checkout v3.10.0 - $ ./configure - $ make # -j N - $ sudo make install + $ git checkout v3.10.0 + $ ./configure + $ make # -j N + $ sudo make install .. note:: Please use rebuild kernel and tools at your own risk. + Configure PRODUCT to use VXLAN Plugin ------------------------------------- @@ -146,6 +166,7 @@ In addition to "KVM Hypervisor Host Installation" in "PRODUCT Installation Guide", you have to configure the following item on the host. + Create bridge interface with IPv4 address ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -165,6 +186,7 @@ this way. Let ``cloudbr1`` be the bridge interface for the instances' private network. + Configure in RHEL or CentOS ''''''''''''''''''''''''''' @@ -172,35 +194,33 @@ When you configured the ``cloudbr1`` interface as below, :: - $ sudo vi /etc/sysconfig/network-scripts/ifcfg-cloudbr1 - + $ sudo vi /etc/sysconfig/network-scripts/ifcfg-cloudbr1 :: - DEVICE=cloudbr1 - TYPE=Bridge - ONBOOT=yes - BOOTPROTO=none - IPV6INIT=no - IPV6_AUTOCONF=no - DELAY=5 - STP=yes - + DEVICE=cloudbr1 + TYPE=Bridge + ONBOOT=yes + BOOTPROTO=none + IPV6INIT=no + IPV6_AUTOCONF=no + DELAY=5 + STP=yes you would change the configuration similar to below. :: - DEVICE=cloudbr1 - TYPE=Bridge - ONBOOT=yes - BOOTPROTO=static - IPADDR=192.0.2.X - NETMASK=255.255.255.0 - IPV6INIT=no - IPV6_AUTOCONF=no - DELAY=5 - STP=yes + DEVICE=cloudbr1 + TYPE=Bridge + ONBOOT=yes + BOOTPROTO=static + IPADDR=192.0.2.X + NETMASK=255.255.255.0 + IPV6INIT=no + IPV6_AUTOCONF=no + DELAY=5 + STP=yes Configure in Ubuntu @@ -210,72 +230,71 @@ When you configured ``cloudbr1`` as below, :: - $ sudo vi /etc/network/interfaces + $ sudo vi /etc/network/interfaces :: - auto lo - iface lo inet loopback - - # The primary network interface - auto eth0.100 - iface eth0.100 inet static - address 192.168.42.11 - netmask 255.255.255.240 - gateway 192.168.42.1 - dns-nameservers 8.8.8.8 8.8.4.4 - dns-domain lab.example.org - - # Public network - auto cloudbr0 - iface cloudbr0 inet manual - bridge_ports eth0.200 - bridge_fd 5 - bridge_stp off - bridge_maxwait 1 - - # Private network - auto cloudbr1 - iface cloudbr1 inet manual - bridge_ports eth0.300 - bridge_fd 5 - bridge_stp off - bridge_maxwait 1 - + auto lo + iface lo inet loopback + + # The primary network interface + auto eth0.100 + iface eth0.100 inet static + address 192.168.42.11 + netmask 255.255.255.240 + gateway 192.168.42.1 + dns-nameservers 8.8.8.8 8.8.4.4 + dns-domain lab.example.org + + # Public network + auto cloudbr0 + iface cloudbr0 inet manual + bridge_ports eth0.200 + bridge_fd 5 + bridge_stp off + bridge_maxwait 1 + + # Private network + auto cloudbr1 + iface cloudbr1 inet manual + bridge_ports eth0.300 + bridge_fd 5 + bridge_stp off + bridge_maxwait 1 you would change the configuration similar to below. :: - auto lo - iface lo inet loopback - - # The primary network interface - auto eth0.100 - iface eth0.100 inet static - address 192.168.42.11 - netmask 255.255.255.240 - gateway 192.168.42.1 - dns-nameservers 8.8.8.8 8.8.4.4 - dns-domain lab.example.org - - # Public network - auto cloudbr0 - iface cloudbr0 inet manual - bridge_ports eth0.200 - bridge_fd 5 - bridge_stp off - bridge_maxwait 1 - - # Private network - auto cloudbr1 - iface cloudbr1 inet static - addres 192.0.2.X - netmask 255.255.255.0 - bridge_ports eth0.300 - bridge_fd 5 - bridge_stp off - bridge_maxwait 1 + auto lo + iface lo inet loopback + + # The primary network interface + auto eth0.100 + iface eth0.100 inet static + address 192.168.42.11 + netmask 255.255.255.240 + gateway 192.168.42.1 + dns-nameservers 8.8.8.8 8.8.4.4 + dns-domain lab.example.org + + # Public network + auto cloudbr0 + iface cloudbr0 inet manual + bridge_ports eth0.200 + bridge_fd 5 + bridge_stp off + bridge_maxwait 1 + + # Private network + auto cloudbr1 + iface cloudbr1 inet static + addres 192.0.2.X + netmask 255.255.255.0 + bridge_ports eth0.300 + bridge_fd 5 + bridge_stp off + bridge_maxwait 1 Configure iptables to pass XVLAN packets @@ -284,6 +303,7 @@ Configure iptables to pass XVLAN packets Since VXLAN uses UDP packet to forward encapsulated the L2 frames, UDP/8472 port must be opened. + Configure in RHEL or CentOS ''''''''''''''''''''''''''' @@ -292,7 +312,7 @@ extra ports by executing the following iptable commands: :: - $ sudo iptables -I INPUT -p udp -m udp --dport 8472 -j ACCEPT + $ sudo iptables -I INPUT -p udp -m udp --dport 8472 -j ACCEPT These iptable settings are not persistent accross reboots, we have to @@ -300,7 +320,7 @@ save them first. :: - $ sudo iptables-save > /etc/sysconfig/iptables + $ sudo iptables-save > /etc/sysconfig/iptables With this configuration you should be able to restart the network, @@ -308,11 +328,14 @@ although a reboot is recommended to see if everything works properly. :: - $ sudo service network restart - $ sudo reboot + $ sudo service network restart + $ sudo reboot -.. warning:: Make sure you have an alternative way like IPMI or ILO to reach the machine in case you made a configuration error and the network stops functioning! +.. warning:: + Make sure you have an alternative way like IPMI or ILO to reach the machine + in case you made a configuration error and the network stops functioning! + Configure in Ubuntu ''''''''''''''''''' @@ -324,21 +347,24 @@ To open the required ports, execute the following commands: :: - $ sudo ufw allow proto udp from any to any port 8472 + $ sudo ufw allow proto udp from any to any port 8472 - -.. note:: By default UFW is not enabled on Ubuntu. Executing these commands with the firewall disabled does not enable the firewall. +.. note:: + By default UFW is not enabled on Ubuntu. Executing these commands with the + firewall disabled does not enable the firewall. With this configuration you should be able to restart the network, although a reboot is recommended to see if everything works properly. :: - $ sudo service networking restart - $ sudo reboot + $ sudo service networking restart + $ sudo reboot +.. warning:: + Make sure you have an alternative way like IPMI or ILO to reach the machine + in case you made a configuration error and the network stops functioning! -.. warning:: Make sure you have an alternative way like IPMI or ILO to reach the machine in case you made a configuration error and the network stops functioning! Setup zone using VXLAN ~~~~~~~~~~~~~~~~~~~~~~ @@ -349,6 +375,7 @@ is not required to add a network element nor to reconfigure the network offering. The only thing you have to do is configure the physical network to use VXLAN as the isolation method for Guest Network. + Configure the physical network ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -363,6 +390,7 @@ Guest Network traffic label should be the name of the physical interface or the name of the bridge interface and the bridge interface and they should have an IPv4 address. See ? for details. + Configure the guest traffic ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -371,6 +399,6 @@ Configure the guest traffic Specify a range of VNIs you would like to use for carrying guest network traffic. -.. warning:: VNI must be unique per zone and no duplicate VNIs can exist in the zone. Exercise care when designing your VNI allocation policy. - - +.. warning:: + VNI must be unique per zone and no duplicate VNIs can exist in the zone. + Exercise care when designing your VNI allocation policy. diff --git a/rtd/source/plugins.rst b/rtd/source/plugins.rst index 6e365a1..56f0259 100644 --- a/rtd/source/plugins.rst +++ b/rtd/source/plugins.rst @@ -1,7 +1,22 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + Plugins ======= - Storage Plugins --------------- @@ -40,13 +55,14 @@ provider is selected, additional input fields may appear so that the user can provide the additional details required by that provider, such as a user name and password for a third-party storage account. + Overview of How to Write a Storage Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To add a third-party storage option to CloudStack, follow these general steps (explained in more detail later in this section): -1. Implement the following interfaces in Java: +#. Implement the following interfaces in Java: - DataStoreDriver @@ -57,14 +73,16 @@ steps (explained in more detail later in this section): - VMSnapshotStrategy (if you want to customize the VM snapshot functionality) -2. Hardcode your plugin's required additional input fields into the code +#. Hardcode your plugin's required additional input fields into the code for the Add Secondary Storage or Add Primary Storage dialog box. -3. Place your .jar file in `plugins/storage/volume/` or `plugins/storage/image/`. +#. Place your .jar file in `plugins/storage/volume/` or + `plugins/storage/image/`. -4. Edit `/client/tomcatconf/componentContext.xml.in`. +#. Edit `/client/tomcatconf/componentContext.xml.in`. + +#. Edit `client/pom.xml`. -5. Edit `client/pom.xml`. Implementing DataStoreDriver ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,6 +107,7 @@ The following methods are optional: - canCopy() is optional. If you set it to true, then you must implement copyAsync(). + Implementing DataStoreLifecycle ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -107,8 +126,8 @@ You must implement the following methods: - deleteDataStore() - Implement one of the attach\*() methods depending on what scope you - want the storage to have: attachHost(), attachCluster(), or - attachZone(). + want the storage to have: attachHost(), attachCluster(), or attachZone(). + Implementing DataStoreProvider ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -134,8 +153,8 @@ You must implement the following methods: The following methods are optional: -- getHostListener() is optional; it's for monitoring the status of the - host. +- getHostListener() is optional; it's for monitoring the status of the host. + Implementing VMSnapshotStrategy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -151,6 +170,7 @@ VMSnapshotStrategy has the following methods: - canHandle(). For a given VM snapshot, tells whether this implementation of VMSnapshotStrategy can handle it. + Place the .jar File in the Right Directory ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -158,13 +178,14 @@ For a secondary storage plugin, place your .jar file here: :: - plugins/storage/image/ + plugins/storage/image/ For a primary storage plugin, place your .jar file here: :: - plugins/storage/volume/ + plugins/storage/volume/ + Edit Configuration Files ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -175,29 +196,30 @@ now has a dependency on your code: :: - client/pom.xml + client/pom.xml Place some facts about your code in the following file so CloudStack can run it: :: - /client/tomcatconf/componentContext.xml.in + /client/tomcatconf/componentContext.xml.in In the section “Deployment configurations of various adapters,” add this: :: - id=”some unique ID” class=”package name of your implementation of DataStoreProvider” + id=”some unique ID” class=”package name of your implementation of DataStoreProvider” In the section “Storage Providers,” add this: :: - - - + + + + Minimum Required Interfaces ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -207,6 +229,7 @@ Services (AWS) Java SDK are listed in this section. An object storage that supports the S3 interface is minimally required to support the below in order to be compatible with CloudStack. + Interface AmazonS3 ^^^^^^^^^^^^^^^^^^ @@ -322,18 +345,19 @@ time after CloudStack installation. The new plugin appears only when it is enabled by the cloud administrator. .. figure:: /_static/images/plugin_intro.jpg - :align: center - :alt: New plugin button in CloudStack navbar + :align: center + :alt: New plugin button in CloudStack navbar The left navigation bar of the CloudStack UI has a new Plugins button to help you work with UI plugins. + How to Write a Plugin: Overview ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The basic procedure for writing a plugin is: -1. Write the code and create the other files needed. You will need the +#. Write the code and create the other files needed. You will need the plugin code itself (in Javascript), a thumbnail image, the plugin listing, and a CSS file. @@ -345,40 +369,41 @@ The basic procedure for writing a plugin is: :: - +-- cloudstack/ - +-- ui/ - +-- plugins/ - +-- csMyFirstPlugin/ - +-- config.js --> Plugin metadata (title, author, vendor URL, etc.) - +-- icon.png --> Icon, shown on side nav bar and plugin listing - (should be square, and ~50x50px) - +-- csMyFirstPlugin.css --> CSS file, loaded automatically when plugin loads - +-- csMyFirstPlugin.js --> Main JS file, containing plugin code + +-- cloudstack/ + +-- ui/ + +-- plugins/ + +-- csMyFirstPlugin/ + +-- config.js --> Plugin metadata (title, author, vendor URL, etc.) + +-- icon.png --> Icon, shown on side nav bar and plugin listing + (should be square, and ~50x50px) + +-- csMyFirstPlugin.css --> CSS file, loaded automatically when plugin loads + +-- csMyFirstPlugin.js --> Main JS file, containing plugin code The same files must also be present at `/tomcat/webapps/client/plugins`. -2. The CloudStack administrator adds the folder containing your plugin code +#. The CloudStack administrator adds the folder containing your plugin code under the CloudStack PLUGINS folder. .. figure:: /_static/images/plugin2.jpg - :align: center - :alt: The plugin code is placed in the PLUGINS folder + :align: center + :alt: The plugin code is placed in the PLUGINS folder -3. The administrator also adds the name of your plugin to the plugin.js +#. The administrator also adds the name of your plugin to the plugin.js file in the PLUGINS folder. .. figure:: /_static/images/plugin3.jpg - :align: center - :alt: The plugin name is added to `plugin.js` in the PLUGINS folder + :align: center + :alt: The plugin name is added to `plugin.js` in the PLUGINS folder -4. The next time the user refreshes the UI in the browser, your plugin +#. The next time the user refreshes the UI in the browser, your plugin will appear in the left navigation bar. .. figure:: /_static/images/plugin4.jpg - :align: center - :alt: The plugin appears in the UI + :align: center + :alt: The plugin appears in the UI + How to Write a Plugin: Implementation Details ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -394,302 +419,299 @@ countless options and variations. The best reference right now is to read the existing code for the main UI, which is in the /ui folder. Plugins are written in a very similar way to the main UI. -1. **Create the directory to hold your plugin.** +#. **Create the directory to hold your plugin.** - All plugins are composed of set of required files in the directory - /ui/plugins/pluginID, where pluginID is a short name for your - plugin. It's recommended that you prefix your folder name (for - example, bfMyPlugin) to avoid naming conflicts with other people's - plugins. + All plugins are composed of set of required files in the directory + /ui/plugins/pluginID, where pluginID is a short name for your + plugin. It's recommended that you prefix your folder name (for + example, bfMyPlugin) to avoid naming conflicts with other people's + plugins. - In this example, the plugin is named csMyFirstPlugin. + In this example, the plugin is named csMyFirstPlugin. - :: + :: - $ cd cloudstack/ui/plugins - $ mkdir csMyFirstPlugin - $ ls -l + $ cd cloudstack/ui/plugins + $ mkdir csMyFirstPlugin + $ ls -l - total 8 - drwxr-xr-x 2 bgregory staff 68 Feb 11 14:44 csMyFirstPlugin - -rw-r--r-- 1 bgregory staff 101 Feb 11 14:26 plugins.js + total 8 + drwxr-xr-x 2 bgregory staff 68 Feb 11 14:44 csMyFirstPlugin + -rw-r--r-- 1 bgregory staff 101 Feb 11 14:26 plugins.js +#. **Change to your new plugin directory.** -2. **Change to your new plugin directory.** + :: - :: + $ cd csMyFirstPlugin + +#. **Set up the listing.** - $ cd csMyFirstPlugin - + Add the file `config.js`, using your favorite editor. -3. **Set up the listing.** + :: - Add the file `config.js`, using your favorite editor. + $ vi config.js - :: + Add the following content to config.js. This information will be + displayed on the plugin listing page in the UI: - $ vi config.js + :: - Add the following content to config.js. This information will be - displayed on the plugin listing page in the UI: + (function (cloudStack) { + cloudStack.plugins.csMyFirstPlugin.config = { + title: 'My first plugin', + desc: 'Tutorial plugin', + externalLink: 'http://www.cloudstack.org/', + authorName: 'Test Plugin Developer', + authorEmail: 'plugin.developer@example.com' + }; + }(cloudStack)); + - :: +#. **Add a new main section.** - (function (cloudStack) { - cloudStack.plugins.csMyFirstPlugin.config = { - title: 'My first plugin', - desc: 'Tutorial plugin', - externalLink: 'http://www.cloudstack.org/', - authorName: 'Test Plugin Developer', - authorEmail: 'plugin.developer@example.com' - }; - }(cloudStack)); - + Add the file csMyFirstPlugin.js, using your favorite editor. -4. **Add a new main section.** + :: - Add the file csMyFirstPlugin.js, using your favorite editor. + $ vi csMyFirstPlugin.js - :: + Add the following content to csMyFirstPlugin.js: - $ vi csMyFirstPlugin.js + :: - Add the following content to csMyFirstPlugin.js: + (function (cloudStack) { + cloudStack.plugins.csMyFirstPlugin = function(plugin) { + plugin.ui.addSection({ + id: 'csMyFirstPlugin', + title: 'My Plugin', + preFilter: function(args) { + return isAdmin(); + }, + show: function() { + return $('
').html('Content will go here'); + } + }); + }; + }(cloudStack)); + + +#. **Register the plugin.** + + You now have the minimal content needed to run the plugin, so you + can activate the plugin in the UI by adding it to plugins.js. First, + edit the file: - :: + :: - (function (cloudStack) { - cloudStack.plugins.csMyFirstPlugin = function(plugin) { - plugin.ui.addSection({ - id: 'csMyFirstPlugin', - title: 'My Plugin', - preFilter: function(args) { - return isAdmin(); - }, - show: function() { - return $('
').html('Content will go here'); - } - }); - }; - }(cloudStack)); - + $ cd cloudstack/ui/plugins + $ vi plugins.js + -5. **Register the plugin.** + Now add the following to plugins.js: - You now have the minimal content needed to run the plugin, so you - can activate the plugin in the UI by adding it to plugins.js. First, - edit the file: + :: - :: + (function($, cloudStack) { + cloudStack.plugins = [ + 'csMyFirstPlugin' + ]; + }(jQuery, cloudStack)); + - $ cd cloudstack/ui/plugins - $ vi plugins.js - +#. **Check the plugin in the UI.** - Now add the following to plugins.js: + First, copy all the plugin code that you have created so far to + `/tomcat/webapps/client/plugins`. Then refresh the browser and click + Plugins in the side navigation bar. You should see your new plugin. - :: +#. **Make the plugin do something.** - (function($, cloudStack) { - cloudStack.plugins = [ - 'csMyFirstPlugin' - ]; - }(jQuery, cloudStack)); - + Right now, you just have placeholder content in the new plugin. It's + time to add real code. In this example, you will write a basic list + view, which renders data from an API call. You will list all virtual + machines owned by the logged-in user. To do this, replace the 'show' + function in the plugin code with a 'listView' block, containing the + required syntax for a list view. To get the data, use the + listVirtualMachines API call. Without any parameters, it will return + VMs only for your active user. Use the provided 'apiCall' helper + method to handle the server call. Of course, you are free to use any + other method for making the AJAX call (for example, jQuery's $.ajax + method). -6. **Check the plugin in the UI.** + First, open your plugin's JavaScript source file in your favorite + editor: - First, copy all the plugin code that you have created so far to - `/tomcat/webapps/client/plugins`. Then refresh the browser and click - Plugins in the side navigation bar. You should see your new plugin. + :: -7. **Make the plugin do something.** + $ cd csMyFirstPlugin + $ vi csMyFirstPlugin.js + - Right now, you just have placeholder content in the new plugin. It's - time to add real code. In this example, you will write a basic list - view, which renders data from an API call. You will list all virtual - machines owned by the logged-in user. To do this, replace the 'show' - function in the plugin code with a 'listView' block, containing the - required syntax for a list view. To get the data, use the - listVirtualMachines API call. Without any parameters, it will return - VMs only for your active user. Use the provided 'apiCall' helper - method to handle the server call. Of course, you are free to use any - other method for making the AJAX call (for example, jQuery's $.ajax - method). + Add the following code in csMyFirstPlugin.js: - First, open your plugin's JavaScript source file in your favorite - editor: + :: - :: + (function (cloudStack) { + cloudStack.plugins.csMyFirstPlugin = function(plugin) { + plugin.ui.addSection({ + id: 'csMyFirstPlugin', + title: 'My Plugin', + preFilter: function(args) { + return isAdmin(); + }, + + // Render page as a list view + listView: { + id: 'testPluginInstances', + fields: { + name: { label: 'label.name' }, + instancename: { label: 'label.internal.name' }, + displayname: { label: 'label.display.name' }, + zonename: { label: 'label.zone.name' } + }, + dataProvider: function(args) { + // API calls go here, to retrive the data asynchronously + // + // On successful retrieval, call + // args.response.success({ data: [data array] }); + plugin.ui.apiCall('listVirtualMachines', { + success: function(json) { + var vms = json.listvirtualmachinesresponse.virtualmachine; + + args.response.success({ data: vms }); + }, + error: function(errorMessage) { + args.response.error(errorMessage) + } + }); + } + } + }); + }; + }(cloudStack)); + - $ cd csMyFirstPlugin - $ vi csMyFirstPlugin.js - +#. **Test the plugin.** - Add the following code in csMyFirstPlugin.js: + First, copy all the plugin code that you have created so far to + `/tomcat/webapps/client/plugins`. Then refresh the browser. You can + see that your placeholder content was replaced with a list table, + containing 4 columns of virtual machine data. - :: +#. **Add an action button.** - (function (cloudStack) { - cloudStack.plugins.csMyFirstPlugin = function(plugin) { - plugin.ui.addSection({ - id: 'csMyFirstPlugin', - title: 'My Plugin', - preFilter: function(args) { - return isAdmin(); - }, + Let's add an action button to the list view, which will reboot the + VM. To do this, add an actions block under listView. After + specifying the correct format, the actions will appear automatically + to the right of each row of data. - // Render page as a list view - listView: { - id: 'testPluginInstances', - fields: { - name: { label: 'label.name' }, - instancename: { label: 'label.internal.name' }, - displayname: { label: 'label.display.name' }, - zonename: { label: 'label.zone.name' } - }, - dataProvider: function(args) { - // API calls go here, to retrive the data asynchronously - // - // On successful retrieval, call - // args.response.success({ data: [data array] }); - plugin.ui.apiCall('listVirtualMachines', { - success: function(json) { - var vms = json.listvirtualmachinesresponse.virtualmachine; - - args.response.success({ data: vms }); - }, - error: function(errorMessage) { - args.response.error(errorMessage) - } - }); - } - } - }); - }; - }(cloudStack)); - + :: -8. **Test the plugin.** - - First, copy all the plugin code that you have created so far to - `/tomcat/webapps/client/plugins`. Then refresh the browser. You can - see that your placeholder content was replaced with a list table, - containing 4 columns of virtual machine data. - -9. **Add an action button.** - - Let's add an action button to the list view, which will reboot the - VM. To do this, add an actions block under listView. After - specifying the correct format, the actions will appear automatically - to the right of each row of data. - - :: - - $ vi csMyFirstPlugin.js - - - Now add the following new code in csMyFirstPlugin.js. (The dots ... - show where we have omitted some existing code for the sake of space. - Don't actually cut and paste that part): - - :: - - ... - listView: { - id: 'testPluginInstances', - ... - - actions: { - // The key/ID you specify here will determine what icon is - // shown in the UI for this action, - // and will be added as a CSS class to the action's element - // (i.e., '.action.restart') - // - // -- here, 'restart' is a predefined name in CloudStack that will - // automatically show a 'reboot' arrow as an icon; - // this can be changed in csMyFirstPlugin.css - restart: { - label: 'Restart VM', - messages: { - confirm: function() { return 'Are you sure you want to restart this VM?' }, - notification: function() { return 'Rebooted VM' } - }, - action: function(args) { - // Get the instance object of the selected row from context - // - // -- all currently loaded state is stored in 'context' as objects, - // such as the selected list view row, - // the selected section, and active user - // - // -- for list view actions, the object's key will be the same as - // listView.id, specified above; - // always make sure you specify an 'id' for the listView, - // or else it will be 'undefined!' - var instance = args.context.testPluginInstances[0]; - - plugin.ui.apiCall('rebootVirtualMachine', { - // These will be appended to the API request - // - // i.e., rebootVirtualMachine&id=... - data: { - id: instance.id - }, - success: function(json) { - args.response.success({ - // This is an async job, so success here only indicates - // that the job was initiated. - // - // To pass the job ID to the notification UI - // (for checking to see when action is completed), - // '_custom: { jobID: ... }' needs to always be passed on success, - // in the same format as below - _custom: { jobId: json.rebootvirtualmachineresponse.jobid } - }); - }, - - - error: function(errorMessage) { - args.response.error(errorMessage); // Cancel action, show error message returned - } - }); - }, - - // Because rebootVirtualMachine is an async job, we need to add - // a poll function, which will perodically check - // the management server to see if the job is ready - // (via pollAsyncJobResult API call) - // - // The plugin API provides a helper function, 'plugin.ui.pollAsyncJob', - / which will work for most jobs - // in CloudStack - notification: { - poll: plugin.ui.pollAsyncJob - } - } - }, + $ vi csMyFirstPlugin.js + + + Now add the following new code in csMyFirstPlugin.js. (The dots ... + show where we have omitted some existing code for the sake of space. + Don't actually cut and paste that part): - dataProvider: function(args) { - ... - ... + :: + + ... + listView: { + id: 'testPluginInstances', + ... + + actions: { + // The key/ID you specify here will determine what icon is + // shown in the UI for this action, + // and will be added as a CSS class to the action's element + // (i.e., '.action.restart') + // + // -- here, 'restart' is a predefined name in CloudStack that will + // automatically show a 'reboot' arrow as an icon; + // this can be changed in csMyFirstPlugin.css + restart: { + label: 'Restart VM', + messages: { + confirm: function() { return 'Are you sure you want to restart this VM?' }, + notification: function() { return 'Rebooted VM' } + }, + action: function(args) { + // Get the instance object of the selected row from context + // + // -- all currently loaded state is stored in 'context' as objects, + // such as the selected list view row, + // the selected section, and active user + // + // -- for list view actions, the object's key will be the same as + // listView.id, specified above; + // always make sure you specify an 'id' for the listView, + // or else it will be 'undefined!' + var instance = args.context.testPluginInstances[0]; + + plugin.ui.apiCall('rebootVirtualMachine', { + // These will be appended to the API request + // + // i.e., rebootVirtualMachine&id=... + data: { + id: instance.id + }, + success: function(json) { + args.response.success({ + // This is an async job, so success here only indicates + // that the job was initiated. + // + // To pass the job ID to the notification UI + // (for checking to see when action is completed), + // '_custom: { jobID: ... }' needs to always be passed on success, + // in the same format as below + _custom: { jobId: json.rebootvirtualmachineresponse.jobid } + }); + }, + + + error: function(errorMessage) { + args.response.error(errorMessage); // Cancel action, show error message returned + } + }); + }, + + // Because rebootVirtualMachine is an async job, we need to add + // a poll function, which will perodically check + // the management server to see if the job is ready + // (via pollAsyncJobResult API call) + // + // The plugin API provides a helper function, 'plugin.ui.pollAsyncJob', + / which will work for most jobs + // in CloudStack + notification: { + poll: plugin.ui.pollAsyncJob + } + } + }, + + dataProvider: function(args) { + ... + ... -10. **Add the thumbnail icon.** +#. **Add the thumbnail icon.** - Create an icon file; it should be square, about 50x50 pixels, and - named `icon.png`. Copy it into the same directory with your plugin - code: `cloudstack/ui/plugins/csMyFirstPlugin/icon.png`. + Create an icon file; it should be square, about 50x50 pixels, and + named `icon.png`. Copy it into the same directory with your plugin + code: `cloudstack/ui/plugins/csMyFirstPlugin/icon.png`. -11. **Add the stylesheet.** +#. **Add the stylesheet.** + + Create a CSS file, with the same name as your `.js` file. Copy it into + the same directory with your plugin code: + `cloudstack/ui/plugins/csMyFirstPlugin/csMyFirstPlugin.css`. - Create a CSS file, with the same name as your `.js` file. Copy it into - the same directory with your plugin code: - `cloudstack/ui/plugins/csMyFirstPlugin/csMyFirstPlugin.css`. .. | plugin_intro.jpg: New plugin button in CloudStack navbar | image:: _static/images/plugin_intro.jpg .. | plugin1.jpg: Write the plugin code | image:: _static/images/plugin1.jpg .. | plugin2.jpg: The plugin code is placed in the PLUGINS folder | image:: _static/images/plugin2.jpg .. | plugin3.jpg: The plugin name is added to plugin.js in the PLUGINS folder | image:: _static/images/plugin3.jpg .. | plugin4.jpg: The plugin appears in the UI | image:: _static/images/plugin4.jpg - - From 0414fddcd509411767f543ae34e285e8a64b86bb Mon Sep 17 00:00:00 2001 From: roryerickson Date: Tue, 15 Jul 2014 20:05:53 -0700 Subject: [PATCH 02/34] Fix typos in concepts.rst Closes #5 Signed-off-by: Sebastien Goasguen --- rtd/source/concepts.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtd/source/concepts.rst b/rtd/source/concepts.rst index 93a1fe7..c8aa36f 100644 --- a/rtd/source/concepts.rst +++ b/rtd/source/concepts.rst @@ -73,7 +73,7 @@ CloudStack automatically configures the network and storage settings for each virtual machine deployment. Internally, a pool of virtual appliances support the operation of configuration of the cloud itself. These appliances offer services such as firewalling, routing, DHCP, VPN, console proxy, storage -acces, and storage replication. The extensive use of horizontally scalable +access, and storage replication. The extensive use of horizontally scalable virtual machines simplifies the installation and ongoing operation of a cloud. @@ -129,7 +129,7 @@ both the Management Server and the hypervisor host (using the KVM hypervisor). A more full-featured installation consists of a highly-available multi-node Management Server installation and up to tens of thousands of hosts using any -of severa networking technologies. +of several networking technologies. Management Server Overview From 8f17a2fecd70341dad7dd585d318d7cbbc526cce Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Tue, 19 Aug 2014 15:26:51 +0530 Subject: [PATCH 03/34] updated instructions to install jdk1.7 for apt-get and yum corrected the java install commands to install jdk1.7 --- rtd/source/developer_guide.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtd/source/developer_guide.rst b/rtd/source/developer_guide.rst index 0e49688..661cd11 100644 --- a/rtd/source/developer_guide.rst +++ b/rtd/source/developer_guide.rst @@ -66,7 +66,7 @@ Install ``openjdk``. As we're using Linux, OpenJDK is our first choice. :: - apt-get install openjdk-6-jdk + apt-get install openjdk-7-jdk Install ``tomcat6``, note that the new version of tomcat on `Ubuntu `__ is the @@ -143,7 +143,7 @@ Install ``openjdk``. As we're using Linux, OpenJDK is our first choice. :: - yum -y install java-1.6.0-openjdk + yum -y install java-1.7.0-openjdk-devel Install ``tomcat6``, note that the version of tomcat6 in the default CentOS 6.4 repo is 6.0.24, so we will grab the 6.0.35 version. The From 73add914343177a1c297d5f68f51667b35ac9e7b Mon Sep 17 00:00:00 2001 From: Mary Brennan Date: Fri, 14 Nov 2014 16:17:01 -0800 Subject: [PATCH 04/34] Fixed some typos. This closes #7 --- rtd/source/ansible.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtd/source/ansible.rst b/rtd/source/ansible.rst index 7f0f9bd..a410e93 100644 --- a/rtd/source/ansible.rst +++ b/rtd/source/ansible.rst @@ -13,7 +13,7 @@ intent to Chef and Puppet. It allows (usually) DevOps teams to orchestrate the deployment and configuration of their environments without having to re-write custom scripts to make changes. -Like Chef and Puppet, Ansible is designed to be idempotent, these means +Like Chef and Puppet, Ansible is designed to be idempotent. This means that you determine the state you want a host to be in and Ansible will decide if it needs to act in order to achieve that state. @@ -23,7 +23,7 @@ There’s already Chef and Puppet, so what’s the fuss about Ansible? Let’s take it as a given that configuration management makes life much easier (and is quite cool), Ansible only needs an SSH connection to the hosts that you’re going to manage to get started. While Ansible requires -Python 2.4 or greater to on the host you’re going to manage in order to +Python 2.4 or greater on the host you’re going to manage in order to leverage the vast majority of its functionality, it is able to connect to hosts which don’t have Python installed in order to then install Python, so it’s not really a problem. This greatly simplifies the From cbd7a13622780142127f06bf2f0d2888afea3c68 Mon Sep 17 00:00:00 2001 From: andrijapanic Date: Wed, 26 Nov 2014 13:10:32 +0100 Subject: [PATCH 05/34] Update vxlan.rst Added section about MTU sizes and examples. --- rtd/source/networking/vxlan.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rtd/source/networking/vxlan.rst b/rtd/source/networking/vxlan.rst index d3b54a8..85da616 100644 --- a/rtd/source/networking/vxlan.rst +++ b/rtd/source/networking/vxlan.rst @@ -73,6 +73,16 @@ To check the capability of your system, execute the following commands. # If it's not, your iproute2 utility doesn't support VXLAN. +Important note on MTU size +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When new vxlan interfaces are created, kernel will obtain current MTU size of the physical interface (ethX or the bridge) +and then create vxlan interface/bridge that are exactly 50 bytes smaller than the MTU on physical interface/bridge. +This means that in order to support default MTU size of 1500 bytes inside VM, your vxlan interface/bridge must also +have MTU of 1500 bytes, meaning that your physical interface/bridge must have MTU of at least 1550 bytes. +In order to configure "jumbo frames" you can i.e. make physical interface/bridge with 9000 bytes MTU, then all the vxlan +interfaces will be created with MTU of 8950 bytes, and then MTU size inside VM can be set to 8950 bytes. + Advanced: Build kernel and iproute2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 0a0606d97a0163105507d1278263a665d48ac01f Mon Sep 17 00:00:00 2001 From: Satoru Nakaya Date: Tue, 3 Mar 2015 15:10:28 +0900 Subject: [PATCH 06/34] Fixed the description of the attaching data disks upper limit of the VMware hypervisor Signed-off-by: Rajani Karuturi This closes #9 --- en-US/working-with-volumes.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/en-US/working-with-volumes.xml b/en-US/working-with-volumes.xml index 5de5e6c..9b970a2 100644 --- a/en-US/working-with-volumes.xml +++ b/en-US/working-with-volumes.xml @@ -39,7 +39,8 @@ used on a guest of another hypervisor type. &PRODUCT; supports attaching up to 13 data disks to a VM on XenServer hypervisor versions - 6.0 and above. For the VMs on other hypervisor types, the data disk limit is 6. + 6.0 and above, And VMware hypervisor versions 5.0 and above. + For the VMs on other hypervisor types, the data disk limit is 6. From af7d1e3a9a53d54d42d92e0e67df9408aaf25516 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Dion Date: Sun, 8 Mar 2015 17:23:11 -0400 Subject: [PATCH 07/34] add basic doc tools --- rtd/make.sh | 3 +++ rtd/source/_global.rst | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100755 rtd/make.sh create mode 100644 rtd/source/_global.rst diff --git a/rtd/make.sh b/rtd/make.sh new file mode 100755 index 0000000..d4e96fd --- /dev/null +++ b/rtd/make.sh @@ -0,0 +1,3 @@ +rm -fr build +mkdir build +sphinx-build -b html source build diff --git a/rtd/source/_global.rst b/rtd/source/_global.rst new file mode 100644 index 0000000..e726975 --- /dev/null +++ b/rtd/source/_global.rst @@ -0,0 +1,22 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + +.. This file contain Variables shared across .rst files in this project + +.. _CloudStack Installation Guide: http://docs.cloudstack.apache.org/projects/cloudstack-installation +.. _CloudStack Administrator's Guide: http://docs.cloudstack.apache.org/projects/cloudstack-administration +.. _CloudStack Apidocs: http://cloudstack.apache.org/docs/api/ +.. _Release Notes: http://docs.cloudstack.apache.org/projects/cloudstack-release-notes \ No newline at end of file From be8e7eddb100d8070ec1939ce28fccdb4c023c24 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Dion Date: Sun, 8 Mar 2015 17:24:11 -0400 Subject: [PATCH 08/34] CLOUDSTACK-1601: add getting help page on main doc site --- rtd/source/_static/images/60recipe.gif | Bin 0 -> 19564 bytes rtd/source/_static/images/jp1.jpg | Bin 0 -> 13705 bytes rtd/source/_static/images/jp2.jpg | Bin 0 -> 14846 bytes rtd/source/_static/images/packt.png | Bin 0 -> 57435 bytes rtd/source/get_help.rst | 91 +++++++++++++++++++++++++ rtd/source/index.rst | 1 + 6 files changed, 92 insertions(+) create mode 100644 rtd/source/_static/images/60recipe.gif create mode 100644 rtd/source/_static/images/jp1.jpg create mode 100644 rtd/source/_static/images/jp2.jpg create mode 100644 rtd/source/_static/images/packt.png create mode 100644 rtd/source/get_help.rst diff --git a/rtd/source/_static/images/60recipe.gif b/rtd/source/_static/images/60recipe.gif new file mode 100644 index 0000000000000000000000000000000000000000..a47a3999941e4d5677f07fe4ea27049c2b30b50c GIT binary patch literal 19564 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 literal 0 HcmV?d00001 diff --git a/rtd/source/get_help.rst b/rtd/source/get_help.rst new file mode 100644 index 0000000..94154d8 --- /dev/null +++ b/rtd/source/get_help.rst @@ -0,0 +1,91 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information# + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + +Getting Help +============ + +Need some help getting started? Feel free to ask on the `mailing list +`_: + +- `users@ `_: This + list is for users of CloudStack to seek and provide support. This is a + moderately high volume list. +- `dev@ `_: Where + discussions about development and the project itself happen. This is a high + volume list. + + +Or on one of the following IRC channels on irc.freenode.net: + +- #cloudstack - General Apache CloudStack conversation and end user support +- #cloudstack-dev - Development discussions +- #cloudstack-meeting - Weekly and ad-hoc meeting room for the Apache CloudStack community + + +Documentation Available +----------------------- + +The following guides are available: + +- `CloudStack Installation Guide`_ - Covers initial installation of CloudStack. It aims to cover in full detail all the + steps and requirements to obtain a functioning cloud deployment. + At times, this guide mentions additional topics in the context of installation tasks, but does not + give full details on every topic. Additional details on many of these topics can be found in the + Administration Guide. For example, security groups, firewall and load balancing + rules, IP address allocation, and virtual routers are covered in more detail in the Administration + Guide. + +- `CloudStack Administrator's Guide`_ - Discusses how to set up services for the end users of your cloud. Also + covers ongoing runtime management and maintenance. This guide discusses topics like domains, + accounts, service offerings, projects, guest networks, administrator alerts, virtual machines, storage, + and measuring resource usage. + +- `Developer's Guide `_ - How to use the API to interact with CloudStack programmatically. Includes + links to the complete API Reference. + +- `CloudStack Apidocs`_ - API documentation reference. + +- `Release Notes`_ - release specific documentation, including upgrade + instructions from prior releases, new features added to CloudStack, API changes, and fixed issues. + + +Books +----- + +|60recipe| |acs-packt| |jp1| |jp2| + + +Commercial support +------------------ + +Some companies offer commercial support for Apache CloudStack or their own +product based on CloudStack. + + +.. include:: _global.rst + +.. |60recipe| image:: _static/images/60recipe.gif + :alt: O'Reilly 60 Recipes for Apache CloudStack + :target: http://shop.oreilly.com/product/0636920034377.do +.. |acs-packt| image:: _static/images/packt.png + :alt: Apache CloudStack Cloud Computing + :target: https://www.packtpub.com/virtualization-and-cloud/apache-cloudstack-cloud-computing +.. |jp1| image:: _static/images/jp1.jpg + :alt: CloudStack徹底入門 大型本 + :target: http://www.amazon.co.jp/gp/product/4798130583/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=4798130583&linkCode=as2&tag=aaaaaaaeaeaea-22 +.. |jp2| image:: _static/images/jp2.jpg + :alt: CloudStack実践ガイド[前編] + :target: http://www.amazon.co.jp/CloudStack%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%89%8D%E7%B7%A8-NextPublishing-%E5%A4%A7%E5%89%8A-%E7%B7%91/dp/4844395920/ref=pd_bxgy_b_img_y \ No newline at end of file diff --git a/rtd/source/index.rst b/rtd/source/index.rst index 398a1f6..94ba4ad 100644 --- a/rtd/source/index.rst +++ b/rtd/source/index.rst @@ -95,3 +95,4 @@ Developers Guide plugins alloc.rst ansible + get_help From ef6c162d024dc48e98a224b2a5fb98a7034dd498 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Dion Date: Sun, 8 Mar 2015 18:13:08 -0400 Subject: [PATCH 09/34] CLOUDSTACK-4799: rewrite section based on the patch since the doc Migrate to rst format --- rtd/source/concepts.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rtd/source/concepts.rst b/rtd/source/concepts.rst index c8aa36f..5db3653 100644 --- a/rtd/source/concepts.rst +++ b/rtd/source/concepts.rst @@ -15,7 +15,7 @@ Concepts and Terminology -======================== +========================Primary storage is associated with a cluster What is Apache CloudStack? -------------------------- @@ -410,8 +410,9 @@ For a host to function in CloudStack, you must do the following: About Primary Storage ~~~~~~~~~~~~~~~~~~~~~ -Primary storage is associated with a cluster or (in KVM and VMware) a -zone, and it stores the disk volumes for all the VMs running on hosts. +Primary storage is associated with a cluster, and it stores +virtual disks for all the VMs running on hosts in that cluster. +On KVM and VMware, you can provision primary storage on a per-zone basis. You can add multiple primary storage servers to a cluster or zone. At least one is required. It is typically located close to the hosts for From f4915dc93b5a0adac4543446a017b0eb7962a268 Mon Sep 17 00:00:00 2001 From: Pierre-Luc Dion Date: Mon, 11 May 2015 09:07:01 -0400 Subject: [PATCH 10/34] change sphinx theme to bootstrap --- rtd/source/conf.py | 112 +- rtd/sphinx_bootstrap_theme/__init__.py | 12 + rtd/sphinx_bootstrap_theme/__init__.pyc | Bin 0 -> 966 bytes .../bootstrap/globaltoc.html | 2 + .../bootstrap/layout.html | 156 + .../bootstrap/localtoc.html | 1 + .../bootstrap/navbar-2.html | 51 + .../bootstrap/navbar.html | 60 + .../bootstrap/navbarsearchbox.html | 9 + .../bootstrap/navbartoc.html | 10 + .../bootstrap/relations.html | 19 + .../bootstrap/search.html | 71 + .../bootstrap/searchbox.html | 9 + .../bootstrap/searchresults.html | 38 + .../bootstrap/sourcelink.html | 6 + .../css/bootstrap-responsive.css | 1109 +++ .../css/bootstrap-responsive.min.css | 9 + .../static/bootstrap-2.3.2/css/bootstrap.css | 6168 ++++++++++++++++ .../bootstrap-2.3.2/css/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../static/bootstrap-2.3.2/js/bootstrap.js | 2287 ++++++ .../bootstrap-2.3.2/js/bootstrap.min.js | 6 + .../bootstrap-3.2.0/css/bootstrap-theme.css | 442 ++ .../css/bootstrap-theme.css.map | 1 + .../css/bootstrap-theme.min.css | 5 + .../static/bootstrap-3.2.0/css/bootstrap.css | 6203 +++++++++++++++++ .../bootstrap-3.2.0/css/bootstrap.css.map | 1 + .../bootstrap-3.2.0/css/bootstrap.min.css | 5 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes .../static/bootstrap-3.2.0/js/bootstrap.js | 2114 ++++++ .../bootstrap-3.2.0/js/bootstrap.min.js | 6 + .../bootstrap/static/bootstrap-sphinx.css_t | 258 + .../bootstrap/static/bootstrap-sphinx.js_t | 173 + .../bootswatch-2.3.2/amelia/bootstrap.min.css | 9 + .../cerulean/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cosmo/bootstrap.min.css | 9 + .../bootswatch-2.3.2/cyborg/bootstrap.min.css | 9 + .../bootswatch-2.3.2/flatly/bootstrap.min.css | 9 + .../img/glyphicons-halflings-white.png | Bin 0 -> 8777 bytes .../img/glyphicons-halflings.png | Bin 0 -> 12799 bytes .../journal/bootstrap.min.css | 9 + .../readable/bootstrap.min.css | 9 + .../simplex/bootstrap.min.css | 9 + .../bootswatch-2.3.2/slate/bootstrap.min.css | 9 + .../spacelab/bootstrap.min.css | 9 + .../bootswatch-2.3.2/spruce/bootstrap.min.css | 9 + .../superhero/bootstrap.min.css | 9 + .../bootswatch-2.3.2/united/bootstrap.min.css | 9 + .../bootswatch-3.2.0/amelia/bootstrap.min.css | 7 + .../cerulean/bootstrap.min.css | 7 + .../bootswatch-3.2.0/cosmo/bootstrap.min.css | 7 + .../bootswatch-3.2.0/custom/bootstrap.min.css | 7 + .../bootswatch-3.2.0/cyborg/bootstrap.min.css | 7 + .../bootswatch-3.2.0/darkly/bootstrap.min.css | 7 + .../bootswatch-3.2.0/flatly/bootstrap.min.css | 7 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20290 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41236 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23292 bytes .../journal/bootstrap.min.css | 7 + .../bootswatch-3.2.0/lumen/bootstrap.min.css | 7 + .../bootswatch-3.2.0/paper/bootstrap.min.css | 7 + .../readable/bootstrap.min.css | 7 + .../sandstone/bootstrap.min.css | 7 + .../simplex/bootstrap.min.css | 7 + .../bootswatch-3.2.0/slate/bootstrap.min.css | 7 + .../spacelab/bootstrap.min.css | 7 + .../superhero/bootstrap.min.css | 7 + .../bootswatch-3.2.0/united/bootstrap.min.css | 7 + .../bootswatch-3.2.0/yeti/bootstrap.min.css | 7 + .../bootstrap/static/js/jquery-1.11.0.min.js | 4 + .../bootstrap/static/js/jquery-fix.js | 2 + .../bootstrap/theme.conf | 61 + 77 files changed, 20099 insertions(+), 21 deletions(-) create mode 100644 rtd/sphinx_bootstrap_theme/__init__.py create mode 100644 rtd/sphinx_bootstrap_theme/__init__.pyc create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/globaltoc.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/layout.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/localtoc.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/navbar-2.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/navbar.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/navbarsearchbox.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/navbartoc.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/relations.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/search.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/searchbox.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/searchresults.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/sourcelink.html create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings-white.png create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings.png create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/js/bootstrap.js create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/js/bootstrap.min.js create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap-theme.css create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap-theme.css.map create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap-theme.min.css create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap.css create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap.css.map create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/css/bootstrap.min.css create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/fonts/glyphicons-halflings-regular.eot create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/fonts/glyphicons-halflings-regular.svg create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/fonts/glyphicons-halflings-regular.ttf create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/fonts/glyphicons-halflings-regular.woff create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/js/bootstrap.js create mode 100755 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-3.2.0/js/bootstrap.min.js create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-sphinx.css_t create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-sphinx.js_t create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/amelia/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/cerulean/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/cosmo/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/cyborg/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/flatly/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/img/glyphicons-halflings-white.png create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/img/glyphicons-halflings.png create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/journal/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/readable/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/simplex/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/slate/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/spacelab/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/spruce/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/superhero/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-2.3.2/united/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/amelia/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/cerulean/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/cosmo/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/custom/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/cyborg/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/darkly/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/flatly/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/fonts/glyphicons-halflings-regular.eot create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/fonts/glyphicons-halflings-regular.svg create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/fonts/glyphicons-halflings-regular.ttf create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/fonts/glyphicons-halflings-regular.woff create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/journal/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/lumen/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/paper/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/readable/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/sandstone/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/simplex/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/slate/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/spacelab/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/superhero/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/united/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/bootswatch-3.2.0/yeti/bootstrap.min.css create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/js/jquery-1.11.0.min.js create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/static/js/jquery-fix.js create mode 100644 rtd/sphinx_bootstrap_theme/bootstrap/theme.conf diff --git a/rtd/source/conf.py b/rtd/source/conf.py index 2076d96..0069926 100644 --- a/rtd/source/conf.py +++ b/rtd/source/conf.py @@ -31,7 +31,8 @@ import sys import os -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +sys.path.insert(0, os.path.abspath('../')) +import sphinx_bootstrap_theme # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -46,7 +47,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -62,16 +63,16 @@ # General information about the project. project = u'Apache CloudStack' -copyright = u'2014, Apache CloudStack' +copyright = u'2015, Apache CloudStack' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.3' +version = '4.5' # The full version, including alpha/beta/rc tags. -release = '4.3.0' +release = '4.5.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -116,22 +117,87 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' -if not on_rtd: - try: - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - except ImportError: - pass - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} +html_theme = 'bootstrap' +html_theme_options = { + # Navigation bar title. (Default: ``project`` value) + 'navbar_title': "Release Notes", + + # Tab name for entire site. (Default: "Site") + 'navbar_site_name': "Sections", + + # Tab name for the current pages TOC. (Default: "Page") + #'navbar_pagenav_name': "Page", + 'navbar_pagenav': "false", + # A list of tuples containing pages or urls to link to. + # Valid tuples should be in the following forms: + # (name, page) # a link to a page + # (name, "/aa/bb", 1) # a link to an arbitrary relative url + # (name, "http://example.com", True) # arbitrary absolute url + # Note the "1" or "True" value above as the third argument to indicate + # an arbitrary url. + # 'navbar_links': [ + # ("Examples", "examples"), + # ("Link", "http://example.com", True), + # ], + + # Global TOC depth for "site" navbar tab. (Default: 1) + # Switching to -1 shows all levels. + 'globaltoc_depth': 1, + + # Include hidden TOCs in Site navbar? + # + # Note: If this is "false", you cannot have mixed ``:hidden:`` and + # non-hidden ``toctree`` directives in the same page, or else the build + # will break. + # + # Values: "true" (default) or "false" + 'globaltoc_includehidden': "false", + + # HTML navbar class (Default: "navbar") to attach to

element. + # For black navbar, do "navbar navbar-inverse" + 'navbar_class': "navbar navbar-inverse", + + # Fix navigation bar to top of page? + # Values: "true" (default) or "false" + 'navbar_fixed_top': "true", + + # Location of link to source. + # Options are "nav" (default), "footer" or anything else to exclude. + 'source_link_position': "footer", + + # Bootswatch (http://bootswatch.com/) theme. + # + # Options are nothing (default) or the name of a valid theme such + # as "amelia" or "cosmo". + # + # Themes: + # * amelia + # * cerulean + # * cosmo + # * cyborg + # * cupid (v3 only) + # * flatly + # * journal + # * lumen (v3 only) + # * readable + # * simplex + # * slate + # * spacelab + # * spruce (v2 only) + # * superhero + # * united + # * yeti (v3 only) + 'bootswatch_theme': "spacelab", + + # Choose Bootstrap version. + # Values: "3" (default) or "2" (in quotes) + 'bootstrap_version': "3", +} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# ``get_html_theme_path`` returns a list, so you can concatenate with +# any other theme directories you would like. +html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -168,7 +234,10 @@ #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +html_sidebars = { + '**': ['localtoc.html'], + 'index': ['globaltoc.html'] +} # Additional templates that should be rendered to pages, maps page names to # template names. @@ -188,6 +257,7 @@ # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True +html_show_sphinx = False # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True @@ -289,7 +359,7 @@ epub_title = u'CloudStack Docs' epub_author = u'Apache CloudStack' epub_publisher = u'Apache CloudStack' -epub_copyright = u'2014, Apache CloudStack' +epub_copyright = u'2015, Apache CloudStack' # The basename for the epub file. It defaults to the project name. #epub_basename = u'CloudStack Docs' diff --git a/rtd/sphinx_bootstrap_theme/__init__.py b/rtd/sphinx_bootstrap_theme/__init__.py new file mode 100644 index 0000000..340c011 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/__init__.py @@ -0,0 +1,12 @@ +"""Sphinx bootstrap theme.""" +import os + +VERSION = (0, 4, 5) + +__version__ = ".".join(str(v) for v in VERSION) +__version_full__ = __version__ + +def get_html_theme_path(): + """Return list of HTML theme paths.""" + cur_dir = os.path.abspath(os.path.dirname(__file__)) + return [cur_dir] diff --git a/rtd/sphinx_bootstrap_theme/__init__.pyc b/rtd/sphinx_bootstrap_theme/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36fccfae4f2d9cc0b5edfb1996c1361ed29c6450 GIT binary patch literal 966 zcmcgq&5G1O5U$S5W`9&rJctOAi;#RH#H2iPY0QeCO)s_*NX{J3*4e1CpY!PT1Z_n2QlW6%HvqXHd4qo818ABqTc z44Vn)UHArIBA9(uz)vv+GlgOY^q%}EVo6)32Xfj2hGk#d?jkvJjyw%zpHOXDli8oV z=9UA%P6c)tNHJuUV8pL^#n%ZWoEK1L!s24I2Jyxm6_umAi(sp2p$XA89 zkm%qzeYse^em4(VY@F@r7XLv!=P}?JK%~3>>{nycaJtO#AO1HwKjBgiTc^jy9LczN OX(m>;qd0n~;^-HEW9wxA literal 0 HcmV?d00001 diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/globaltoc.html b/rtd/sphinx_bootstrap_theme/bootstrap/globaltoc.html new file mode 100644 index 0000000..7094f72 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/globaltoc.html @@ -0,0 +1,2 @@ +{{ toctree(maxdepth=theme_globaltoc_depth|toint, collapse=False, includehidden=theme_globaltoc_includehidden|tobool) }} + diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/layout.html b/rtd/sphinx_bootstrap_theme/bootstrap/layout.html new file mode 100644 index 0000000..bf143fe --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/layout.html @@ -0,0 +1,156 @@ +{% extends "basic/layout.html" %} + +{% set theme_css_files = [] %} +{% if theme_bootstrap_version == "3" %} + {% set bootstrap_version, bootstrap_additional_css, navbar_version = "3.2.0", "theme", "" %} + {% set bs_span_prefix = "col-md-" %} +{% else %} + {% set bootstrap_version, bootstrap_additional_css, navbar_version = "2.3.2", "responsive", "-2" %} + {% set bs_span_prefix = "span" %} +{% endif %} + +{% if theme_bootswatch_theme and theme_bootswatch_theme != "\"\"" %} + {# BS2 needs "bootstrap-responsive.css". BS3 doesn't. #} + {% if theme_bootstrap_version == "3" %} + {% set theme_css_files = theme_css_files + [ + '_static/bootswatch-' + bootstrap_version + '/' + theme_bootswatch_theme + '/bootstrap.min.css', + '_static/bootstrap-sphinx.css' + ] + %} + {% else %} + {% set theme_css_files = theme_css_files + [ + '_static/bootswatch-' + bootstrap_version + '/' + theme_bootswatch_theme + '/bootstrap.min.css', + '_static/bootstrap-' + bootstrap_version + '/css/bootstrap-' + bootstrap_additional_css + '.min.css', + '_static/bootstrap-sphinx.css' + ] + %} + {% endif %} +{% else %} + {% set theme_css_files = theme_css_files + [ + '_static/bootstrap-' + bootstrap_version + '/css/bootstrap.min.css', + '_static/bootstrap-' + bootstrap_version + '/css/bootstrap-' + bootstrap_additional_css + '.min.css', + '_static/bootstrap-sphinx.css' + ] + %} +{% endif %} + +{% if not bootswatch_css_custom %} + {% set bootswatch_css_custom = [] %} +{% endif %} +{% set css_files = css_files + theme_css_files + bootswatch_css_custom %} + +{% set script_files = script_files + [ + '_static/js/jquery-1.11.0.min.js', + '_static/js/jquery-fix.js', + '_static/bootstrap-' + bootstrap_version + '/js/bootstrap.min.js', + '_static/bootstrap-sphinx.js' + ] +%} + +{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and sidebars %} + +{%- set bs_content_width = render_sidebar and "9" or "12"%} + +{%- block doctype -%} + +{%- endblock %} + +{# Sidebar: Rework into our Bootstrap nav section. #} +{% macro navBar() %} +{% include "navbar" + navbar_version + ".html" %} +{% endmacro %} + +{% if theme_bootstrap_version == "3" %} + {%- macro bsidebar() %} + {%- if render_sidebar %} +
+ +
+ {%- endif %} + {%- endmacro %} +{% else %} + {%- macro bsidebar() %} + {%- if render_sidebar %} +
+ +
+ {%- endif %} + {%- endmacro %} +{% endif %} + +{%- block extrahead %} + + + + +{% endblock %} + +{# Silence the sidebar's, relbar's #} +{% block header %}{% endblock %} +{% block relbar1 %}{% endblock %} +{% block relbar2 %}{% endblock %} +{% block sidebarsourcelink %}{% endblock %} + +{%- block content %} +{{ navBar() }} +
+
+ {%- block sidebar1 %}{{ bsidebar() }}{% endblock %} +
+ {% block body %}{% endblock %} +
+ {% block sidebar2 %} {# possible location for sidebar #} {% endblock %} +
+
+{%- endblock %} + +{%- block footer %} +
+{%- endblock %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/localtoc.html b/rtd/sphinx_bootstrap_theme/bootstrap/localtoc.html new file mode 100644 index 0000000..6e6c03b --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/localtoc.html @@ -0,0 +1 @@ +{{ toc }} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/navbar-2.html b/rtd/sphinx_bootstrap_theme/bootstrap/navbar-2.html new file mode 100644 index 0000000..5f7116f --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/navbar-2.html @@ -0,0 +1,51 @@ + diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/navbar.html b/rtd/sphinx_bootstrap_theme/bootstrap/navbar.html new file mode 100644 index 0000000..7880089 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/navbar.html @@ -0,0 +1,60 @@ + diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/navbarsearchbox.html b/rtd/sphinx_bootstrap_theme/bootstrap/navbarsearchbox.html new file mode 100644 index 0000000..82e9338 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/navbarsearchbox.html @@ -0,0 +1,9 @@ +{%- if pagename != "search" %} + +{%- endif %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/navbartoc.html b/rtd/sphinx_bootstrap_theme/bootstrap/navbartoc.html new file mode 100644 index 0000000..8def043 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/navbartoc.html @@ -0,0 +1,10 @@ + diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/relations.html b/rtd/sphinx_bootstrap_theme/bootstrap/relations.html new file mode 100644 index 0000000..3afab53 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/relations.html @@ -0,0 +1,19 @@ +{# Switch to icon instead of text in `sm` view size for BS3 only. #} +{%- if prev %} +
  • + + {%- if theme_bootstrap_version == "2" -%}{%- endif -%} + {%- if theme_bootstrap_version == "3" -%}{%- endif -%} + + +
  • +{%- endif %} +{%- if next %} +
  • + + {%- if theme_bootstrap_version == "2" -%}{%- endif -%} + {%- if theme_bootstrap_version == "3" -%}{%- endif -%} + + +
  • +{%- endif %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/search.html b/rtd/sphinx_bootstrap_theme/bootstrap/search.html new file mode 100644 index 0000000..0332637 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/search.html @@ -0,0 +1,71 @@ +{# + basic/search.html + ~~~~~~~~~~~~~~~~~ + + Template for the search page. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- extends "layout.html" %} +{% set title = _('Search') %} +{% set script_files = script_files + ['_static/searchtools.js'] %} +{% block extrahead %} + + {# this is used when loading the search index using $.ajax fails, + such as on Chrome for documents on localhost #} + + {{ super() }} +{% endblock %} +{% block body %} +

    {{ _('Search') }}

    +
    + +

    + {% trans %}Please activate JavaScript to enable the search + functionality.{% endtrans %} +

    +
    +

    + {% trans %}From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list.{% endtrans %} +

    + + {% if theme_bootstrap_version == "3" %} +
    +
    + +
    + + +
    + {% else %} + + {% endif %} + + {% if search_performed %} +

    {{ _('Search Results') }}

    + {% if not search_results %} +

    {{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}

    + {% endif %} + {% endif %} +
    + {% if search_results %} +
      + {% for href, caption, context in search_results %} +
    • {{ caption }} +
      {{ context|e }}
      +
    • + {% endfor %} +
    + {% endif %} +
    +{% endblock %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/searchbox.html b/rtd/sphinx_bootstrap_theme/bootstrap/searchbox.html new file mode 100644 index 0000000..53755f3 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/searchbox.html @@ -0,0 +1,9 @@ +{%- if pagename != "search" %} +
    +
    + +
    + + +
    +{%- endif %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/searchresults.html b/rtd/sphinx_bootstrap_theme/bootstrap/searchresults.html new file mode 100644 index 0000000..cfb0aa4 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/searchresults.html @@ -0,0 +1,38 @@ +{# + basic/searchresults.html + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Template for the body of the search results page. + + :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +

    Search

    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". +

    + + + +{%- if search_performed %} +

    Search Results

    + {%- if not search_results %} +

    Your search did not match any results.

    + {%- endif %} +{%- endif %} +
    + {%- if search_results %} + + {%- endif %} +
    diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/sourcelink.html b/rtd/sphinx_bootstrap_theme/bootstrap/sourcelink.html new file mode 100644 index 0000000..3cf7335 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/sourcelink.html @@ -0,0 +1,6 @@ +{%- if show_source and has_source and sourcename %} + +{%- endif %} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.css b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.css new file mode 100644 index 0000000..09e88ce --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.css @@ -0,0 +1,1109 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +@-ms-viewport { + width: device-width; +} + +.hidden { + display: none; + visibility: hidden; +} + +.visible-phone { + display: none !important; +} + +.visible-tablet { + display: none !important; +} + +.hidden-desktop { + display: none !important; +} + +.visible-desktop { + display: inherit !important; +} + +@media (min-width: 768px) and (max-width: 979px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important ; + } + .visible-tablet { + display: inherit !important; + } + .hidden-tablet { + display: none !important; + } +} + +@media (max-width: 767px) { + .hidden-desktop { + display: inherit !important; + } + .visible-desktop { + display: none !important; + } + .visible-phone { + display: inherit !important; + } + .hidden-phone { + display: none !important; + } +} + +.visible-print { + display: none !important; +} + +@media print { + .visible-print { + display: inherit !important; + } + .hidden-print { + display: none !important; + } +} + +@media (min-width: 1200px) { + .row { + margin-left: -30px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 30px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 1170px; + } + .span12 { + width: 1170px; + } + .span11 { + width: 1070px; + } + .span10 { + width: 970px; + } + .span9 { + width: 870px; + } + .span8 { + width: 770px; + } + .span7 { + width: 670px; + } + .span6 { + width: 570px; + } + .span5 { + width: 470px; + } + .span4 { + width: 370px; + } + .span3 { + width: 270px; + } + .span2 { + width: 170px; + } + .span1 { + width: 70px; + } + .offset12 { + margin-left: 1230px; + } + .offset11 { + margin-left: 1130px; + } + .offset10 { + margin-left: 1030px; + } + .offset9 { + margin-left: 930px; + } + .offset8 { + margin-left: 830px; + } + .offset7 { + margin-left: 730px; + } + .offset6 { + margin-left: 630px; + } + .offset5 { + margin-left: 530px; + } + .offset4 { + margin-left: 430px; + } + .offset3 { + margin-left: 330px; + } + .offset2 { + margin-left: 230px; + } + .offset1 { + margin-left: 130px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.564102564102564%; + *margin-left: 2.5109110747408616%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.564102564102564%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.45299145299145%; + *width: 91.39979996362975%; + } + .row-fluid .span10 { + width: 82.90598290598291%; + *width: 82.8527914166212%; + } + .row-fluid .span9 { + width: 74.35897435897436%; + *width: 74.30578286961266%; + } + .row-fluid .span8 { + width: 65.81196581196582%; + *width: 65.75877432260411%; + } + .row-fluid .span7 { + width: 57.26495726495726%; + *width: 57.21176577559556%; + } + .row-fluid .span6 { + width: 48.717948717948715%; + *width: 48.664757228587014%; + } + .row-fluid .span5 { + width: 40.17094017094017%; + *width: 40.11774868157847%; + } + .row-fluid .span4 { + width: 31.623931623931625%; + *width: 31.570740134569924%; + } + .row-fluid .span3 { + width: 23.076923076923077%; + *width: 23.023731587561375%; + } + .row-fluid .span2 { + width: 14.52991452991453%; + *width: 14.476723040552828%; + } + .row-fluid .span1 { + width: 5.982905982905983%; + *width: 5.929714493544281%; + } + .row-fluid .offset12 { + margin-left: 105.12820512820512%; + *margin-left: 105.02182214948171%; + } + .row-fluid .offset12:first-child { + margin-left: 102.56410256410257%; + *margin-left: 102.45771958537915%; + } + .row-fluid .offset11 { + margin-left: 96.58119658119658%; + *margin-left: 96.47481360247316%; + } + .row-fluid .offset11:first-child { + margin-left: 94.01709401709402%; + *margin-left: 93.91071103837061%; + } + .row-fluid .offset10 { + margin-left: 88.03418803418803%; + *margin-left: 87.92780505546462%; + } + .row-fluid .offset10:first-child { + margin-left: 85.47008547008548%; + *margin-left: 85.36370249136206%; + } + .row-fluid .offset9 { + margin-left: 79.48717948717949%; + *margin-left: 79.38079650845607%; + } + .row-fluid .offset9:first-child { + margin-left: 76.92307692307693%; + *margin-left: 76.81669394435352%; + } + .row-fluid .offset8 { + margin-left: 70.94017094017094%; + *margin-left: 70.83378796144753%; + } + .row-fluid .offset8:first-child { + margin-left: 68.37606837606839%; + *margin-left: 68.26968539734497%; + } + .row-fluid .offset7 { + margin-left: 62.393162393162385%; + *margin-left: 62.28677941443899%; + } + .row-fluid .offset7:first-child { + margin-left: 59.82905982905982%; + *margin-left: 59.72267685033642%; + } + .row-fluid .offset6 { + margin-left: 53.84615384615384%; + *margin-left: 53.739770867430444%; + } + .row-fluid .offset6:first-child { + margin-left: 51.28205128205128%; + *margin-left: 51.175668303327875%; + } + .row-fluid .offset5 { + margin-left: 45.299145299145295%; + *margin-left: 45.1927623204219%; + } + .row-fluid .offset5:first-child { + margin-left: 42.73504273504273%; + *margin-left: 42.62865975631933%; + } + .row-fluid .offset4 { + margin-left: 36.75213675213675%; + *margin-left: 36.645753773413354%; + } + .row-fluid .offset4:first-child { + margin-left: 34.18803418803419%; + *margin-left: 34.081651209310785%; + } + .row-fluid .offset3 { + margin-left: 28.205128205128204%; + *margin-left: 28.0987452264048%; + } + .row-fluid .offset3:first-child { + margin-left: 25.641025641025642%; + *margin-left: 25.53464266230224%; + } + .row-fluid .offset2 { + margin-left: 19.65811965811966%; + *margin-left: 19.551736679396257%; + } + .row-fluid .offset2:first-child { + margin-left: 17.094017094017094%; + *margin-left: 16.98763411529369%; + } + .row-fluid .offset1 { + margin-left: 11.11111111111111%; + *margin-left: 11.004728132387708%; + } + .row-fluid .offset1:first-child { + margin-left: 8.547008547008547%; + *margin-left: 8.440625568285142%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 30px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 1156px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 1056px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 956px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 856px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 756px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 656px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 556px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 456px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 356px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 256px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 156px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 56px; + } + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + .row-fluid .thumbnails { + margin-left: 0; + } +} + +@media (min-width: 768px) and (max-width: 979px) { + .row { + margin-left: -20px; + *zoom: 1; + } + .row:before, + .row:after { + display: table; + line-height: 0; + content: ""; + } + .row:after { + clear: both; + } + [class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; + } + .container, + .navbar-static-top .container, + .navbar-fixed-top .container, + .navbar-fixed-bottom .container { + width: 724px; + } + .span12 { + width: 724px; + } + .span11 { + width: 662px; + } + .span10 { + width: 600px; + } + .span9 { + width: 538px; + } + .span8 { + width: 476px; + } + .span7 { + width: 414px; + } + .span6 { + width: 352px; + } + .span5 { + width: 290px; + } + .span4 { + width: 228px; + } + .span3 { + width: 166px; + } + .span2 { + width: 104px; + } + .span1 { + width: 42px; + } + .offset12 { + margin-left: 764px; + } + .offset11 { + margin-left: 702px; + } + .offset10 { + margin-left: 640px; + } + .offset9 { + margin-left: 578px; + } + .offset8 { + margin-left: 516px; + } + .offset7 { + margin-left: 454px; + } + .offset6 { + margin-left: 392px; + } + .offset5 { + margin-left: 330px; + } + .offset4 { + margin-left: 268px; + } + .offset3 { + margin-left: 206px; + } + .offset2 { + margin-left: 144px; + } + .offset1 { + margin-left: 82px; + } + .row-fluid { + width: 100%; + *zoom: 1; + } + .row-fluid:before, + .row-fluid:after { + display: table; + line-height: 0; + content: ""; + } + .row-fluid:after { + clear: both; + } + .row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.7624309392265194%; + *margin-left: 2.709239449864817%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="span"]:first-child { + margin-left: 0; + } + .row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.7624309392265194%; + } + .row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; + } + .row-fluid .span11 { + width: 91.43646408839778%; + *width: 91.38327259903608%; + } + .row-fluid .span10 { + width: 82.87292817679558%; + *width: 82.81973668743387%; + } + .row-fluid .span9 { + width: 74.30939226519337%; + *width: 74.25620077583166%; + } + .row-fluid .span8 { + width: 65.74585635359117%; + *width: 65.69266486422946%; + } + .row-fluid .span7 { + width: 57.18232044198895%; + *width: 57.12912895262725%; + } + .row-fluid .span6 { + width: 48.61878453038674%; + *width: 48.56559304102504%; + } + .row-fluid .span5 { + width: 40.05524861878453%; + *width: 40.00205712942283%; + } + .row-fluid .span4 { + width: 31.491712707182323%; + *width: 31.43852121782062%; + } + .row-fluid .span3 { + width: 22.92817679558011%; + *width: 22.87498530621841%; + } + .row-fluid .span2 { + width: 14.3646408839779%; + *width: 14.311449394616199%; + } + .row-fluid .span1 { + width: 5.801104972375691%; + *width: 5.747913483013988%; + } + .row-fluid .offset12 { + margin-left: 105.52486187845304%; + *margin-left: 105.41847889972962%; + } + .row-fluid .offset12:first-child { + margin-left: 102.76243093922652%; + *margin-left: 102.6560479605031%; + } + .row-fluid .offset11 { + margin-left: 96.96132596685082%; + *margin-left: 96.8549429881274%; + } + .row-fluid .offset11:first-child { + margin-left: 94.1988950276243%; + *margin-left: 94.09251204890089%; + } + .row-fluid .offset10 { + margin-left: 88.39779005524862%; + *margin-left: 88.2914070765252%; + } + .row-fluid .offset10:first-child { + margin-left: 85.6353591160221%; + *margin-left: 85.52897613729868%; + } + .row-fluid .offset9 { + margin-left: 79.8342541436464%; + *margin-left: 79.72787116492299%; + } + .row-fluid .offset9:first-child { + margin-left: 77.07182320441989%; + *margin-left: 76.96544022569647%; + } + .row-fluid .offset8 { + margin-left: 71.2707182320442%; + *margin-left: 71.16433525332079%; + } + .row-fluid .offset8:first-child { + margin-left: 68.50828729281768%; + *margin-left: 68.40190431409427%; + } + .row-fluid .offset7 { + margin-left: 62.70718232044199%; + *margin-left: 62.600799341718584%; + } + .row-fluid .offset7:first-child { + margin-left: 59.94475138121547%; + *margin-left: 59.838368402492065%; + } + .row-fluid .offset6 { + margin-left: 54.14364640883978%; + *margin-left: 54.037263430116376%; + } + .row-fluid .offset6:first-child { + margin-left: 51.38121546961326%; + *margin-left: 51.27483249088986%; + } + .row-fluid .offset5 { + margin-left: 45.58011049723757%; + *margin-left: 45.47372751851417%; + } + .row-fluid .offset5:first-child { + margin-left: 42.81767955801105%; + *margin-left: 42.71129657928765%; + } + .row-fluid .offset4 { + margin-left: 37.01657458563536%; + *margin-left: 36.91019160691196%; + } + .row-fluid .offset4:first-child { + margin-left: 34.25414364640884%; + *margin-left: 34.14776066768544%; + } + .row-fluid .offset3 { + margin-left: 28.45303867403315%; + *margin-left: 28.346655695309746%; + } + .row-fluid .offset3:first-child { + margin-left: 25.69060773480663%; + *margin-left: 25.584224756083227%; + } + .row-fluid .offset2 { + margin-left: 19.88950276243094%; + *margin-left: 19.783119783707537%; + } + .row-fluid .offset2:first-child { + margin-left: 17.12707182320442%; + *margin-left: 17.02068884448102%; + } + .row-fluid .offset1 { + margin-left: 11.32596685082873%; + *margin-left: 11.219583872105325%; + } + .row-fluid .offset1:first-child { + margin-left: 8.56353591160221%; + *margin-left: 8.457152932878806%; + } + input, + textarea, + .uneditable-input { + margin-left: 0; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; + } + input.span12, + textarea.span12, + .uneditable-input.span12 { + width: 710px; + } + input.span11, + textarea.span11, + .uneditable-input.span11 { + width: 648px; + } + input.span10, + textarea.span10, + .uneditable-input.span10 { + width: 586px; + } + input.span9, + textarea.span9, + .uneditable-input.span9 { + width: 524px; + } + input.span8, + textarea.span8, + .uneditable-input.span8 { + width: 462px; + } + input.span7, + textarea.span7, + .uneditable-input.span7 { + width: 400px; + } + input.span6, + textarea.span6, + .uneditable-input.span6 { + width: 338px; + } + input.span5, + textarea.span5, + .uneditable-input.span5 { + width: 276px; + } + input.span4, + textarea.span4, + .uneditable-input.span4 { + width: 214px; + } + input.span3, + textarea.span3, + .uneditable-input.span3 { + width: 152px; + } + input.span2, + textarea.span2, + .uneditable-input.span2 { + width: 90px; + } + input.span1, + textarea.span1, + .uneditable-input.span1 { + width: 28px; + } +} + +@media (max-width: 767px) { + body { + padding-right: 20px; + padding-left: 20px; + } + .navbar-fixed-top, + .navbar-fixed-bottom, + .navbar-static-top { + margin-right: -20px; + margin-left: -20px; + } + .container-fluid { + padding: 0; + } + .dl-horizontal dt { + float: none; + width: auto; + clear: none; + text-align: left; + } + .dl-horizontal dd { + margin-left: 0; + } + .container { + width: auto; + } + .row-fluid { + width: 100%; + } + .row, + .thumbnails { + margin-left: 0; + } + .thumbnails > li { + float: none; + margin-left: 0; + } + [class*="span"], + .uneditable-input[class*="span"], + .row-fluid [class*="span"] { + display: block; + float: none; + width: 100%; + margin-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .span12, + .row-fluid .span12 { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .row-fluid [class*="offset"]:first-child { + margin-left: 0; + } + .input-large, + .input-xlarge, + .input-xxlarge, + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .input-prepend input, + .input-append input, + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + display: inline-block; + width: auto; + } + .controls-row [class*="span"] + [class*="span"] { + margin-left: 0; + } + .modal { + position: fixed; + top: 20px; + right: 20px; + left: 20px; + width: auto; + margin: 0; + } + .modal.fade { + top: -100px; + } + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 480px) { + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); + } + .page-header h1 small { + display: block; + line-height: 20px; + } + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + .form-horizontal .control-label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + .form-horizontal .controls { + margin-left: 0; + } + .form-horizontal .control-list { + padding-top: 0; + } + .form-horizontal .form-actions { + padding-right: 10px; + padding-left: 10px; + } + .media .pull-left, + .media .pull-right { + display: block; + float: none; + margin-bottom: 10px; + } + .media-object { + margin-right: 0; + margin-left: 0; + } + .modal { + top: 10px; + right: 10px; + left: 10px; + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + .carousel-caption { + position: static; + } +} + +@media (max-width: 979px) { + body { + padding-top: 0; + } + .navbar-fixed-top, + .navbar-fixed-bottom { + position: static; + } + .navbar-fixed-top { + margin-bottom: 20px; + } + .navbar-fixed-bottom { + margin-top: 20px; + } + .navbar-fixed-top .navbar-inner, + .navbar-fixed-bottom .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + .navbar .brand { + padding-right: 10px; + padding-left: 10px; + margin: 0 0 0 -5px; + } + .nav-collapse { + clear: both; + } + .nav-collapse .nav { + float: none; + margin: 0 0 10px; + } + .nav-collapse .nav > li { + float: none; + } + .nav-collapse .nav > li > a { + margin-bottom: 2px; + } + .nav-collapse .nav > .divider-vertical { + display: none; + } + .nav-collapse .nav .nav-header { + color: #777777; + text-shadow: none; + } + .nav-collapse .nav > li > a, + .nav-collapse .dropdown-menu a { + padding: 9px 15px; + font-weight: bold; + color: #777777; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + } + .nav-collapse .btn { + padding: 4px 10px 4px; + font-weight: normal; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + .nav-collapse .dropdown-menu li + li a { + margin-bottom: 2px; + } + .nav-collapse .nav > li > a:hover, + .nav-collapse .nav > li > a:focus, + .nav-collapse .dropdown-menu a:hover, + .nav-collapse .dropdown-menu a:focus { + background-color: #f2f2f2; + } + .navbar-inverse .nav-collapse .nav > li > a, + .navbar-inverse .nav-collapse .dropdown-menu a { + color: #999999; + } + .navbar-inverse .nav-collapse .nav > li > a:hover, + .navbar-inverse .nav-collapse .nav > li > a:focus, + .navbar-inverse .nav-collapse .dropdown-menu a:hover, + .navbar-inverse .nav-collapse .dropdown-menu a:focus { + background-color: #111111; + } + .nav-collapse.in .btn-group { + padding: 0; + margin-top: 5px; + } + .nav-collapse .dropdown-menu { + position: static; + top: auto; + left: auto; + display: none; + float: none; + max-width: none; + padding: 0; + margin: 0 15px; + background-color: transparent; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + .nav-collapse .open > .dropdown-menu { + display: block; + } + .nav-collapse .dropdown-menu:before, + .nav-collapse .dropdown-menu:after { + display: none; + } + .nav-collapse .dropdown-menu .divider { + display: none; + } + .nav-collapse .nav > li > .dropdown-menu:before, + .nav-collapse .nav > li > .dropdown-menu:after { + display: none; + } + .nav-collapse .navbar-form, + .nav-collapse .navbar-search { + float: none; + padding: 10px 15px; + margin: 10px 0; + border-top: 1px solid #f2f2f2; + border-bottom: 1px solid #f2f2f2; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + } + .navbar-inverse .nav-collapse .navbar-form, + .navbar-inverse .nav-collapse .navbar-search { + border-top-color: #111111; + border-bottom-color: #111111; + } + .navbar .nav-collapse .nav.pull-right { + float: none; + margin-left: 0; + } + .nav-collapse, + .nav-collapse.collapse { + height: 0; + overflow: hidden; + } + .navbar .btn-navbar { + display: block; + } + .navbar-static .navbar-inner { + padding-right: 10px; + padding-left: 10px; + } +} + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + overflow: visible !important; + } +} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.min.css b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.min.css new file mode 100644 index 0000000..f4ede63 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap-responsive.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap Responsive v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.css b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.css new file mode 100644 index 0000000..a11b392 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.css @@ -0,0 +1,6168 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +audio:not([controls]) { + display: none; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; + margin-left: 25px; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.min.css b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.min.css new file mode 100644 index 0000000..b6428e6 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/css/bootstrap.min.css @@ -0,0 +1,9 @@ +/*! + * Bootstrap v2.3.2 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings-white.png b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings-white.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf6484a29d8da269f9bc874b25493a45fae3bae GIT binary patch literal 8777 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 B7G?kd literal 0 HcmV?d00001 diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings.png b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/img/glyphicons-halflings.png new file mode 100644 index 0000000000000000000000000000000000000000..a9969993201f9cee63cf9f49217646347297b643 GIT binary patch literal 12799 zcma*OWmH^Ivn@*S;K3nSf_t!#;0f+&pm7Po8`nk}2q8f5;M%x$SdAkd9FAvlc$ zx660V9e3Ox@4WZ^?7jZ%QFGU-T~%||Ug4iK6bbQY@zBuF2$hxOw9wF=A)nUSxR_5@ zEX>HBryGrjyuOFFv$Y4<+|3H@gQfEqD<)+}a~mryD|1U9*I_FOG&F%+Ww{SJ-V2BR zjt<81Ek$}Yb*95D4RS0HCps|uLyovt;P05hchQb-u2bzLtmog&f2}1VlNhxXV);S9 zM2buBg~!q9PtF)&KGRgf3#z7B(hm5WlNClaCWFs!-P!4-u*u5+=+D|ZE9e`KvhTHT zJBnLwGM%!u&vlE%1ytJ=!xt~y_YkFLQb6bS!E+s8l7PiPGSt9xrmg?LV&&SL?J~cI zS(e9TF1?SGyh+M_p@o1dyWu7o7_6p;N6hO!;4~ z2B`I;y`;$ZdtBpvK5%oQ^p4eR2L)BH>B$FQeC*t)c`L71gXHPUa|vyu`Bnz)H$ZcXGve(}XvR!+*8a>BLV;+ryG1kt0=)ytl zNJxFUN{V7P?#|Cp85QTa@(*Q3%K-R(Pkv1N8YU*(d(Y}9?PQ(j;NzWoEVWRD-~H$=f>j9~PN^BM2okI(gY-&_&BCV6RP&I$FnSEM3d=0fCxbxA6~l>54-upTrw zYgX@%m>jsSGi`0cQt6b8cX~+02IghVlNblR7eI;0ps}mpWUcxty1yG56C5rh%ep(X z?)#2d?C<4t-KLc*EAn>>M8%HvC1TyBSoPNg(4id~H8JwO#I)Bf;N*y6ai6K9_bA`4 z_g9(-R;qyH&6I$`b42v|0V3Z8IXN*p*8g$gE98+JpXNY+jXxU0zsR^W$#V=KP z3AEFp@OL}WqwOfsV<)A^UTF4&HF1vQecz?LWE@p^Z2){=KEC_3Iopx_eS42>DeiDG zWMXGbYfG~W7C8s@@m<_?#Gqk;!&)_Key@^0xJxrJahv{B&{^!>TV7TEDZlP|$=ZCz zmX=ZWtt4QZKx**)lQQoW8y-XLiOQy#T`2t}p6l*S`68ojyH@UXJ-b~@tN`WpjF z%7%Yzv807gsO!v=!(2uR)16!&U5~VPrPHtGzUU?2w(b1Xchq}(5Ed^G|SD7IG+kvgyVksU) z(0R)SW1V(>&q2nM%Z!C9=;pTg!(8pPSc%H01urXmQI6Gi^dkYCYfu6b4^tW))b^U+ z$2K&iOgN_OU7n#GC2jgiXU{caO5hZt0(>k+c^(r><#m|#J^s?zA6pi;^#*rp&;aqL zRcZi0Q4HhVX3$ybclxo4FFJW*`IV`)Bj_L3rQe?5{wLJh168Ve1jZv+f1D}f0S$N= zm4i|9cEWz&C9~ZI3q*gwWH^<6sBWuphgy@S3Qy?MJiL>gwd|E<2h9-$3;gT9V~S6r z)cAcmE0KXOwDA5eJ02-75d~f?3;n7a9d_xPBJaO;Z)#@s7gk5$Qn(Fc^w@9c5W0zY z59is0?Mt^@Rolcn{4%)Ioat(kxQH6}hIykSA)zht=9F_W*D#<}N(k&&;k;&gKkWIL z0Of*sP=X(Uyu$Pw;?F@?j{}=>{aSHFcii#78FC^6JGrg-)!)MV4AKz>pXnhVgTgx8 z1&5Y=>|8RGA6++FrSy=__k_imx|z-EI@foKi>tK0Hq2LetjUotCgk2QFXaej!BWYL zJc{fv(&qA7UUJ|AXLc5z*_NW#yWzKtl(c8mEW{A>5Hj^gfZ^HC9lQNQ?RowXjmuCj4!!54Us1=hY z0{@-phvC}yls!PmA~_z>Y&n&IW9FQcj}9(OLO-t^NN$c0o}YksCUWt|DV(MJB%%Sr zdf}8!9ylU2TW!=T{?)g-ojAMKc>3pW;KiZ7f0;&g)k}K^#HBhE5ot)%oxq$*$W@b# zg4p<Ou`ME|Kd1WHK@8 zzLD+0(NHWa`B{em3Ye?@aVsEi>y#0XVZfaFuq#;X5C3{*ikRx7UY4FF{ZtNHNO?A_ z#Q?hwRv~D8fPEc%B5E-ZMI&TAmikl||EERumQCRh7p;)>fdZMxvKq;ky0}7IjhJph zW*uuu*(Y6)S;Od--8uR^R#sb$cmFCnPcj9PPCWhPN;n`i1Q#Qn>ii z{WR|0>8F`vf&#E(c2NsoH=I7Cd-FV|%(7a`i}gZw4N~QFFG2WtS^H%@c?%9UZ+kez z;PwGgg_r6V>Kn5n(nZ40P4qMyrCP3bDkJp@hp6&X3>gzC>=f@Hsen<%I~7W+x@}b> z0}Et*vx_50-q@PIV=(3&Tbm}}QRo*FP2@)A#XX-8jYspIhah`9ukPBr)$8>Tmtg&R z?JBoH17?+1@Y@r>anoKPQ}F8o9?vhcG79Cjv^V6ct709VOQwg{c0Q#rBSsSmK3Q;O zBpNihl3S0_IGVE)^`#94#j~$;7+u870yWiV$@={|GrBmuz4b)*bCOPkaN0{6$MvazOEBxFdKZDlbVvv{8_*kJ zfE6C`4&Kkz<5u%dEdStd85-5UHG5IOWbo8i9azgg#zw-(P1AA049hddAB*UdG3Vn0 zX`OgM+EM|<+KhJ<=k?z~WA5waVj?T9eBdfJGebVifBKS1u<$#vl^BvSg)xsnT5Aw_ZY#}v*LXO#htB>f}x3qDdDHoFeb zAq7;0CW;XJ`d&G*9V)@H&739DpfWYzdQt+Kx_E1K#Cg1EMtFa8eQRk_JuUdHD*2;W zR~XFnl!L2A?48O;_iqCVr1oxEXvOIiN_9CUVTZs3C~P+11}ebyTRLACiJuMIG#`xP zKlC|E(S@QvN+%pBc6vPiQS8KgQAUh75C0a2xcPQDD$}*bM&z~g8+=9ltmkT$;c;s z5_=8%i0H^fEAOQbHXf0;?DN5z-5+1 zDxj50yYkz4ox9p$HbZ|H?8ukAbLE^P$@h}L%i6QVcY>)i!w=hkv2zvrduut%!8>6b zcus3bh1w~L804EZ*s96?GB&F7c5?m?|t$-tp2rKMy>F*=4;w*jW}^;8v`st&8)c; z2Ct2{)?S(Z;@_mjAEjb8x=qAQvx=}S6l9?~H?PmP`-xu;ME*B8sm|!h@BX4>u(xg_ zIHmQzp4Tgf*J}Y=8STR5_s)GKcmgV!$JKTg@LO402{{Wrg>#D4-L%vjmtJ4r?p&$F!o-BOf7ej~ z6)BuK^^g1b#(E>$s`t3i13{6-mmSp7{;QkeG5v}GAN&lM2lQT$@(aQCcFP(%UyZbF z#$HLTqGT^@F#A29b0HqiJsRJAlh8kngU`BDI6 zJUE~&!cQ*&f95Ot$#mxU5+*^$qg_DWNdfu+1irglB7yDglzH()2!@#rpu)^3S8weW z_FE$=j^GTY*|5SH95O8o8W9FluYwB=2PwtbW|JG6kcV^dMVmX(wG+Otj;E$%gfu^K z!t~<3??8=()WQSycsBKy24>NjRtuZ>zxJIED;YXaUz$@0z4rl+TW zWxmvM$%4jYIpO>j5k1t1&}1VKM~s!eLsCVQ`TTjn3JRXZD~>GM z$-IT~(Y)flNqDkC%DfbxaV9?QuWCV&-U1yzrV@0jRhE;)ZO0=r-{s@W?HOFbRHDDV zq;eLo+wOW;nI|#mNf(J?RImB9{YSO2Y`9825Lz#u4(nk3)RGv3X8B(A$TsontJ8L! z9JP^eWxtKC?G8^xAZa1HECx*rp35s!^%;&@Jyk)NexVc)@U4$^X1Dag6`WKs|(HhZ#rzO2KEw3xh~-0<;|zcs0L>OcO#YYX{SN8m6`9pp+ zQG@q$I)T?aoe#AoR@%om_#z=c@ych!bj~lV13Qi-xg$i$hXEAB#l=t7QWENGbma4L zbBf*X*4oNYZUd_;1{Ln_ZeAwQv4z?n9$eoxJeI?lU9^!AB2Y~AwOSq67dT9ADZ)s@ zCRYS7W$Zpkdx$3T>7$I%3EI2ik~m!f7&$Djpt6kZqDWZJ-G{*_eXs*B8$1R4+I}Kf zqniwCI64r;>h2Lu{0c(#Atn)%E8&)=0S4BMhq9$`vu|Ct;^ur~gL`bD>J@l)P$q_A zO7b3HGOUG`vgH{}&&AgrFy%K^>? z>wf**coZ2vdSDcNYSm~dZ(vk6&m6bVKmVgrx-X<>{QzA!)2*L+HLTQz$e8UcB&Djq zl)-%s$ZtUN-R!4ZiG=L0#_P=BbUyH+YPmFl_ogkkQ$=s@T1v}rNnZ^eMaqJ|quc+6 z*ygceDOrldsL30w`H;rNu+IjlS+G~p&0SawXCA1+D zC%cZtjUkLNq%FadtHE?O(yQTP486A{1x<{krq#rpauNQaeyhM3*i0%tBpQHQo-u)x z{0{&KS`>}vf2_}b160XZO2$b)cyrHq7ZSeiSbRvaxnKUH{Q`-P(nL&^fcF2){vhN- zbX&WEjP7?b4A%0y6n_=m%l00uZ+}mCYO(!x?j$+O$*TqoD_Q5EoyDJ?w?^UIa491H zE}87(bR`X;@u#3Qy~9wWdWQIg1`cXrk$x9=ccR|RY1~%{fAJ@uq@J3e872x0v$hmv ze_KcL(wM|n0EOp;t{hKoohYyDmYO;!`7^Lx;0k=PWPGZpI>V5qYlzjSL_(%|mud50 z7#{p97s`U|Sn$WYF>-i{i4`kzlrV6a<}=72q2sAT7Zh{>P%*6B;Zl;~0xWymt10Mo zl5{bmR(wJefJpNGK=fSRP|mpCI-)Nf6?Pv==FcFmpSwF1%CTOucV{yqxSyx4Zws3O z8hr5Uyd%ezIO7?PnEO0T%af#KOiXD$e?V&OX-B|ZX-YsgSs%sv-6U+sLPuz{D4bq| zpd&|o5tNCmpT>(uIbRf?8c}d3IpOb3sn6>_dr*26R#ev<_~vi)wleW$PX|5)$_ z+_|=pi(0D(AB_sjQ;sQQSM&AWqzDO1@NHw;C9cPdXRKRI#@nUW)CgFxzQ1nyd!+h& zcjU!U=&u|>@}R(9D$%lu2TlV>@I2-n@fCr5PrZNVyKWR7hm zWjoy^p7v8m#$qN0K#8jT- zq`mSirDZDa1Jxm;Rg3rAPhC)LcI4@-RvKT+@9&KsR3b0_0zuM!Fg7u>oF>3bzOxZPU&$ab$Z9@ zY)f7pKh22I7ZykL{YsdjcqeN++=0a}elQM-4;Q)(`Ep3|VFHqnXOh14`!Bus& z9w%*EWK6AiAM{s$6~SEQS;A>ey$#`7)khZvamem{P?>k)5&7Sl&&NXKk}o!%vd;-! zpo2p-_h^b$DNBO>{h4JdGB=D>fvGIYN8v&XsfxU~VaefL?q} z3ekM?iOKkCzQHkBkhg=hD!@&(L}FcHKoa zbZ7)H1C|lHjwEb@tu=n^OvdHOo7o+W`0-y3KdP#bb~wM=Vr_gyoEq|#B?$&d$tals ziIs-&7isBpvS|CjC|7C&3I0SE?~`a%g~$PI%;au^cUp@ER3?mn-|vyu!$7MV6(uvt z+CcGuM(Ku2&G0tcRCo7#D$Dirfqef2qPOE5I)oCGzmR5G!o#Q~(k~)c=LpIfrhHQk zeAva6MilEifE7rgP1M7AyWmLOXK}i8?=z2;N=no)`IGm#y%aGE>-FN zyXCp0Sln{IsfOBuCdE*#@CQof%jzuU*jkR*Su3?5t}F(#g0BD0Zzu|1MDes8U7f9; z$JBg|mqTXt`muZ8=Z`3wx$uizZG_7>GI7tcfOHW`C2bKxNOR)XAwRkLOaHS4xwlH4 zDpU29#6wLXI;H?0Se`SRa&I_QmI{zo7p%uveBZ0KZKd9H6@U?YGArbfm)D*^5=&Rp z`k{35?Z5GbZnv>z@NmJ%+sx=1WanWg)8r}C_>EGR8mk(NR$pW<-l8OTU^_u3M@gwS z7}GGa1)`z5G|DZirw;FB@VhH7Dq*0qc=|9lLe{w2#`g+_nt>_%o<~9(VZe=zI*SSz4w43-_o>4E4`M@NPKTWZuQJs)?KXbWp1M zimd5F;?AP(LWcaI-^Sl{`~>tmxsQB9Y$Xi*{Zr#py_+I$vx7@NY`S?HFfS!hUiz$a z{>!&e1(16T!Om)m)&k1W#*d#GslD^4!TwiF2WjFBvi=Ms!ADT)ArEW6zfVuIXcXVk z>AHjPADW+mJzY`_Ieq(s?jbk4iD2Rb8*V3t6?I+E06(K8H!!xnDzO%GB;Z$N-{M|B zeT`jo%9)s%op*XZKDd6*)-^lWO{#RaIGFdBH+;XXjI(8RxpBc~azG1H^2v7c^bkFE zZCVPE+E*Q=FSe8Vm&6|^3ki{9~qafiMAf7i4APZg>b%&5>nT@pHH z%O*pOv(77?ZiT{W zBibx}Q12tRc7Py1NcZTp`Q4ey%T_nj@1WKg5Fz_Rjl4wlJQj)rtp8yL3r!Shy zvZvnmh!tH4T6Js-?vI0<-rzzl{mgT*S0d_7^AU_8gBg^03o-J=p(1o6kww2hx|!%T z-jqp}m^G*W?$!R#M%Ef?&2jYxmx+lXWZszpI4d$pUN`(S)|*c^CgdwY>Fa>> zgGBJhwe8y#Xd*q0=@SLEgPF>+Qe4?%E*v{a`||luZ~&dqMBrRfJ{SDMaJ!s_;cSJp zSqZHXIdc@@XteNySUZs^9SG7xK`8=NBNM)fRVOjw)D^)w%L2OPkTQ$Tel-J)GD3=YXy+F4in(ILy*A3m@3o73uv?JC}Q>f zrY&8SWmesiba0|3X-jmlMT3 z*ST|_U@O=i*sM_*48G)dgXqlwoFp5G6qSM3&%_f_*n!PiT>?cNI)fAUkA{qWnqdMi+aNK_yVQ&lx4UZknAc9FIzVk% zo6JmFH~c{_tK!gt4+o2>)zoP{sR}!!vfRjI=13!z5}ijMFQ4a4?QIg-BE4T6!#%?d&L;`j5=a`4is>U;%@Rd~ zXC~H7eGQhhYWhMPWf9znDbYIgwud(6$W3e>$W4$~d%qoJ z+JE`1g$qJ%>b|z*xCKenmpV$0pM=Gl-Y*LT8K+P)2X#;XYEFF4mRbc~jj?DM@(1e`nL=F4Syv)TKIePQUz)bZ?Bi3@G@HO$Aps1DvDGkYF50O$_welu^cL7;vPiMGho74$;4fDqKbE{U zd1h{;LfM#Fb|Z&uH~Rm_J)R~Vy4b;1?tW_A)Iz#S_=F|~pISaVkCnQ0&u%Yz%o#|! zS-TSg87LUfFSs{tTuM3$!06ZzH&MFtG)X-l7>3)V?Txuj2HyG*5u;EY2_5vU0ujA? zHXh5G%6e3y7v?AjhyX79pnRBVr}RmPmtrxoB7lkxEzChX^(vKd+sLh?SBic=Q)5nA zdz7Mw3_iA>;T^_Kl~?1|5t%GZ;ki_+i>Q~Q1EVdKZ)$Sh3LM@ea&D~{2HOG++7*wF zAC6jW4>fa~!Vp5+$Z{<)Qxb|{unMgCv2)@%3j=7)Zc%U<^i|SAF88s!A^+Xs!OASYT%7;Jx?olg_6NFP1475N z#0s<@E~FI}#LNQ{?B1;t+N$2k*`K$Hxb%#8tRQi*Z#No0J}Pl;HWb){l7{A8(pu#@ zfE-OTvEreoz1+p`9sUI%Y{e5L-oTP_^NkgpYhZjp&ykinnW;(fu1;ttpSsgYM8ABX4dHe_HxU+%M(D=~) zYM}XUJ5guZ;=_ZcOsC`_{CiU$zN3$+x&5C`vX-V3`8&RjlBs^rf00MNYZW+jCd~7N z%{jJuUUwY(M`8$`B>K&_48!Li682ZaRknMgQ3~dnlp8C?__!P2z@=Auv;T^$yrsNy zCARmaA@^Yo2sS%2$`031-+h9KMZsIHfB>s@}>Y(z988e!`%4=EDoAQ0kbk>+lCoK60Mx9P!~I zlq~wf7kcm_NFImt3ZYlE(b3O1K^QWiFb$V^a2Jlwvm(!XYx<`i@ZMS3UwFt{;x+-v zhx{m=m;4dgvkKp5{*lfSN3o^keSpp9{hlXj%=}e_7Ou{Yiw(J@NXuh*;pL6@$HsfB zh?v+r^cp@jQ4EspC#RqpwPY(}_SS$wZ{S959`C25777&sgtNh%XTCo9VHJC-G z;;wi9{-iv+ETiY;K9qvlEc04f;ZnUP>cUL_T*ms``EtGoP^B#Q>n2dSrbAg8a>*Lg zd0EJ^=tdW~7fbcLFsqryFEcy*-8!?;n%;F+8i{eZyCDaiYxghr z$8k>L|2&-!lhvuVdk!r-kpSFl`5F5d4DJr%M4-qOy3gdmQbqF1=aBtRM7)c_Ae?$b8 zQg4c8*KQ{XJmL)1c7#0Yn0#PTMEs4-IHPjkn0!=;JdhMXqzMLeh`yOylXROP- zl#z3+fwM9l3%VN(6R77ua*uI9%hO7l7{+Hcbr(peh;afUK?B4EC09J{-u{mv)+u#? zdKVBCPt`eU@IzL)OXA`Ebu`Xp?u0m%h&X41}FNfnJ*g1!1wcbbpo%F4x!-#R9ft!8{5`Ho}04?FI#Kg zL|k`tF1t_`ywdy8(wnTut>HND(qNnq%Sq=AvvZbXnLx|mJhi!*&lwG2g|edBdVgLy zjvVTKHAx(+&P;P#2Xobo7_RttUi)Nllc}}hX>|N?-u5g7VJ-NNdwYcaOG?NK=5)}` zMtOL;o|i0mSKm(UI_7BL_^6HnVOTkuPI6y@ZLR(H?c1cr-_ouSLp{5!bx^DiKd*Yb z{K78Ci&Twup zTKm)ioN|wcYy%Qnwb)IzbH>W!;Ah5Zdm_jRY`+VRJ2 zhkspZ9hbK3iQD91A$d!0*-1i#%x81|s+SPRmD}d~<1p6!A13(!vABP2kNgqEG z?AMgl^P+iRoIY(9@_I?n1829lGvAsRnHwS~|5vD2+Zi53j<5N4wNn0{q>>jF9*bI) zL$kMXM-awNOElF>{?Jr^tOz1glbwaD-M0OKOlTeW3C!1ZyxRbB>8JDof(O&R1bh%3x#>y2~<>OXO#IIedH0Q`(&&?eo-c~ z>*Ah#3~09unym~UC-UFqqI>{dmUD$Y4@evG#ORLI*{ZM)Jl=e1it!XzY($S3V zLG!Y6fCjE>x6r@5FG1n|8ompSZaJ>9)q6jqU;XxCQk9zV(?C9+i*>w z21+KYt1gXX&0`x3E)hS7I5}snbBzox9C@Xzcr|{B8Hw;SY1$}&BoYKXH^hpjW-RgJ z-Fb}tannKCv>y~^`r|(1Q9;+sZlYf3XPSX|^gR01UFtu$B*R;$sPZdIZShRr>|b@J z;#G{EdoY+O;REEjQ}X7_YzWLO+Ey3>a_KDe1CjSe| z6arqcEZ)CX!8r(si`dqbF$uu&pnf^Np{1f*TdJ`r2;@SaZ z#hb4xlaCA@Pwqj#LlUEe5L{I$k(Zj$d3(~)u(F%&xb8={N9hKxlZIO1ABsM{Mt|)2 zJ^t9Id;?%4PfR4&Ph9B9cFK~@tG3wlFW-0fXZS_L4U*EiAA%+`h%q2^6BCC;t0iO4V=s4Qug{M|iDV@s zC7|ef-dxiR7T&Mpre!%hiUhHM%3Qxi$Lzw6&(Tvlx9QA_7LhYq<(o~=Y>3ka-zrQa zhGpfFK@)#)rtfz61w35^sN1=IFw&Oc!Nah+8@qhJ0UEGr;JplaxOGI82OVqZHsqfX ze1}r{jy;G?&}Da}a7>SCDsFDuzuseeCKof|Dz2BPsP8? zY;a)Tkr2P~0^2BeO?wnzF_Ul-ekY=-w26VnU%U3f19Z-pj&2 z4J_a|o4Dci+MO)mPQIM>kdPG1xydiR9@#8m zh27D7GF{p|a{8({Q-Pr-;#jV{2zHR>lGoFtIfIpoMo?exuQyX_A;;l0AP4!)JEM$EwMInZkj+8*IHP4vKRd zKx_l-i*>A*C@{u%ct`y~s6MWAfO{@FPIX&sg8H{GMDc{4M3%$@c8&RAlw0-R<4DO3 trJqdc$mBpWeznn?E0M$F`|3v=`3%T2A17h;rxP7$%JLd=6(2u;`(N3pt&so# literal 0 HcmV?d00001 diff --git a/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/js/bootstrap.js b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/js/bootstrap.js new file mode 100644 index 0000000..638bb18 --- /dev/null +++ b/rtd/sphinx_bootstrap_theme/bootstrap/static/bootstrap-2.3.2/js/bootstrap.js @@ -0,0 +1,2287 @@ +/* =================================================== + * bootstrap-transition.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-alert.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-button.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.$jqTheme || window.jQuery); +/* ========================================================== + * bootstrap-carousel.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================= + * bootstrap-collapse.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.$jqTheme || window.jQuery); +/* ============================================================ + * bootstrap-dropdown.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement) { + // if mobile we we use a backdrop because click events don't delegate + $('