diff options
Diffstat (limited to 'longbow')
230 files changed, 38786 insertions, 0 deletions
diff --git a/longbow/.gitignore b/longbow/.gitignore new file mode 100644 index 00000000..bd57cd42 --- /dev/null +++ b/longbow/.gitignore @@ -0,0 +1,32 @@ +build +======= +VERSION +liblongbow*tar.gz +lib +bin +include +*.o +*.lo +*.a +*.la +.libs +a.out +.DS_Store +.gcda +.gcno +.dSYM +autom4te.cache +config.h +config.log +config.status +stamp-h1 +*.trs +Makefile +.deps +*.pyc +.dirstamp +*.swp +libtool +*~ +*.pyc +.idea diff --git a/longbow/AUTHORS b/longbow/AUTHORS new file mode 100644 index 00000000..0bb46a2f --- /dev/null +++ b/longbow/AUTHORS @@ -0,0 +1,7 @@ +LongBow authors are listed below + + Glenn Scott <Glenn.Scott@parc.com> + +Copyright (c) 2013-2016 Xerox Corporation (Xerox) and Palo Alto Reserch Center, Inc (PARC) +Copyright (c) 2017 Cisco and/or its affiliates. + diff --git a/longbow/BASE_VERSION b/longbow/BASE_VERSION new file mode 100644 index 00000000..d3827e75 --- /dev/null +++ b/longbow/BASE_VERSION @@ -0,0 +1 @@ +1.0 diff --git a/longbow/CMakeLists.txt b/longbow/CMakeLists.txt new file mode 100644 index 00000000..46c9fd9f --- /dev/null +++ b/longbow/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.2) +project(LongBow) + +include( CTest ) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +execute_process(COMMAND ${PROJECT_SOURCE_DIR}/cmake/get_version.sh ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE RELEASE_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) + +execute_process(COMMAND date -u +%Y-%m-%dT%H:%M:%SZ + OUTPUT_VARIABLE ISO_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE) + +MESSAGE( STATUS "Configuring version ${RELEASE_VERSION}" ) + +add_definitions("-DRELEASE_VERSION=\"${RELEASE_VERSION}\"") +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3") + +#set(CMAKE_C_FLAGS_NOPANTS "${CMAKE_C_FLAGS_NOPANTS} -O3 -DNDEBUG -DLongBow_DISABLE_ASSERTIONS") + + +find_package( Doxygen ) +find_package( Uncrustify ) +find_package( PythonInterp ) + +set( DEPENDENCY_DIR $ENV{CCNX_DEPENDENCIES} ) +if( NOT DEPENDENCY_DIR ) + set( DEPENDENCY_DIR /usr ) +endif() + +set( PYVERSION ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} ) + +set( INSTALL_BASE_PYTHON_DIR ${CMAKE_INSTALL_PREFIX}/lib/python${PYVERSION}/site-packages ) +set( INSTALL_PYTHON_DIR ${INSTALL_BASE_PYTHON_DIR}/longbow ) +set( DEPENDENCY_PYTHON_DIR ${DEPENDENCY_DIR}/etc/site-packages ) +set( VERSION ${RELEASE_VERSION} ) +set( DATE ${ISO_DATE} ) +set( UNCRUSTIFY_BIN ${UNCRUSTIFY_BIN} ) +set( UNCRUSTIFY_CONFIG ${CMAKE_INSTALL_PREFIX}/etc/parc_uncrustify.cfg ) + +message( "-- Install Python Dir: ${INSTALL_PYTHON_DIR}") +message( "-- Dependency Python Dir: ${DEPENDENCY_DIR}/etc/site-packages") +include_directories(${PROJECT_BINARY_DIR}/src/LongBow ${PROJECT_SOURCE_DIR}/src) + +if(ANDROID_API) + message("############ Detected cross compile for ${CMAKE_SYSTEM_NAME}") + message("############ This build will not include doxygen, tools, or tests") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ANDROID_C_FLAGS} -Wall") + + macro(AddTest testFile) + message("Android build: Skipping test ${ARGV0}") + endmacro(AddTest) + + add_subdirectory(src) +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -DNDEBUG -DLongBow_DISABLE_ASSERTIONS -D_GNU_SOURCE") + macro(AddTest testFile) + add_executable(${ARGV0} ${ARGV0}.c) + target_link_libraries(${ARGV0} ${PARC_BIN_LIBRARIES}) + add_test(${ARGV0} ${ARGV0}) + set_target_properties(${ARGV0} PROPERTIES FOLDER Test) + endmacro(AddTest) + + add_subdirectory(src) + add_subdirectory(documentation) +endif()
\ No newline at end of file diff --git a/longbow/LICENSE b/longbow/LICENSE new file mode 100644 index 00000000..99c77d9d --- /dev/null +++ b/longbow/LICENSE @@ -0,0 +1,14 @@ +Copyright (c) 2017 Cisco and/or its affiliates. +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. + + diff --git a/longbow/README.md b/longbow/README.md new file mode 100644 index 00000000..66c75d1e --- /dev/null +++ b/longbow/README.md @@ -0,0 +1,112 @@ +LongBow +======= +_The Best Defense is a Good Offense_ + +The LongBow C language software framework + +## Quick Start ## +``` +$ git clone -b cframework/master https://gerrit.fd.io/r/cicn cframework +$ cd cframework/longbow +$ mkdir build +$ cd build +$ cmake .. +$ make +$ make test +$ make install +``` + +## Introduction ## + +LongBow is a C language software framework that combines the fail-fast philosophy of an offensive-stance of program +development and xUnit style unit testing. Using LongBow's to aid an offensive-development stance is largely a matter +of using its entry and exit assertions in your code. Similarly using LongBow's unit-test framework uses the same entry +and exit assertions in the unit test cases themselves. The runtime assertions and the unit-test assertions work +together in the unit test framework and do not conflict. This framework grew out of the need for a unit testing for +Test Driven Development on the CCNx Distillery software distribution. +Two other test frameworks were considered and used to develop unit tests: Unity and GoogleTest. Ultimately Unity +was not used (although this framework is indebted to Unity for inspiration) mainly due to ease-of-use problems, +and Googletest was not used mainly because it is a C++ framework, is not compatible with some features of C99, and is +difficult to use. + +## Using LongBow ## + +### Platforms ### + +LongBow has been tested in: + +- Ubuntu 16.04 (x86_64) +- Debian Testing +- MacOSX 10.12 + +Other platforms and architectures may work. + +### Dependencies ### + +- c99 (clang / gcc) +- CMake 3.4 +- Python 2.7 + +While the LongBow unit test framework and runtime assertions don't have any unusual requirements other than CMake, +the software quality development tools that LongBow provides can make use of the following tools: + +- Doxygen +- Uncrustify + +### Using LongBow ### + +#### LongBow Lib + +To use LongBow in your software you will need to link your programs to the LongBow libraries. +Longbow comes as a set of libraries. A main library and a set of reporting libraries. Your software will need to +link to the main library (`liblongbow`) and one of the reporting libraries. Currently there are 2 reporting libraries +available `longbow-textplain` and `longbow-ansiterm`. + +``` +LONGBOW_DIR=<directory-where-longbow-is-installed> + +-I${LONGBOW_DIR}/include -L${LONGBOW_DIR}/lib -llongbow -llongbow_textplain.a +``` + +#### LongBow Unit Testing + +LongBow unit testing works in conjuction with the LongBow library. Please take a look at the examples and the +documentation for information on how to write unit tests. You can also look at some of the software that uses LongBow +for unit testing as examples. A good starting point would be Libparc. + +#### LongBow Utilities + +LongBow comes with a set of utilities (scripts) to make C programs better. This includes code analysis and reporting +tools. You will find these in the `${INSTALL_DIR}/bin` directory. Each of those utilities should come with a `-h` +option that will give you online help. For more information please check the LongBow documentation. + +### GDB and LongBow ### +LongBow uses signals to interrupt program flow when an assertion fails. +When using `gdb` this will cause `gdb` to stop running of the test which probably isn't what you want. +You probably would prefer that gdb just ignore the signal and let the LongBow unit test signal handler take care of the +signal. To do this, you must configure `gdb` to ignore the signal and to allow it to pass to the programme being +executed. + +`handle 6 nostop pass` + + +### License ### + +This software is distributed under the following license: + +``` +Copyright (c) 2017 Cisco and/or its affiliates. +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. +``` + + diff --git a/longbow/cmake/Modules/FindUncrustify.cmake b/longbow/cmake/Modules/FindUncrustify.cmake new file mode 100644 index 00000000..e53f65fe --- /dev/null +++ b/longbow/cmake/Modules/FindUncrustify.cmake @@ -0,0 +1,8 @@ +# Find uncrustify program +# +find_program( UNCRUSTIFY_BIN uncrustify + PATHS + $ENV{UNCRUSTIFY_HOME} + ) + +message( "-- UNCRUSTIFY found in ${UNCRUSTIFY_BIN}" ) diff --git a/longbow/cmake/get_version.sh b/longbow/cmake/get_version.sh new file mode 100755 index 00000000..34c6ddb2 --- /dev/null +++ b/longbow/cmake/get_version.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +DATE_VERSION=`date "+%Y%m%d"` + +if [ ! -d $1 ]; then + echo 0.$DATE_VERSION + exit +fi + +if [ -f $1/BASE_VERSION ]; then + BASE_VERSION=`cat $1/BASE_VERSION`. +fi + +GIT=`which git` + +if test -x $GIT -a -f $1/.git/config; then + GIT_VERSION=.`git -C $1 rev-parse HEAD | cut -c 1-8` +fi + +echo $BASE_VERSION$DATE_VERSION$GIT_VERSION diff --git a/longbow/documentation/.gitignore b/longbow/documentation/.gitignore new file mode 100644 index 00000000..3d3b0c69 --- /dev/null +++ b/longbow/documentation/.gitignore @@ -0,0 +1,4 @@ +build +*.log +longbow-documentation +longbow.doctags diff --git a/longbow/documentation/CMakeLists.txt b/longbow/documentation/CMakeLists.txt new file mode 100644 index 00000000..c25ffc16 --- /dev/null +++ b/longbow/documentation/CMakeLists.txt @@ -0,0 +1,45 @@ +find_package(Doxygen) + +if(DOXYGEN_FOUND) + set(PARC_REMOTE http://githubenterprise.parc.com/CCNX/LongBow) + set(GITHUB_REMOTE http://github.com/PARC/LongBow) + configure_file(longbow.doxygen.in config.doxygen @ONLY) + + install(DIRECTORY images/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/images) + install(DIRECTORY doxygen-extras/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/doxygen-extras) + install(DIRECTORY examples/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/examples) + install(FILES DoxygenLayout.xml DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + set(HTML_PATH ${CMAKE_CURRENT_BINARY_DIR}/generated-documentation/html) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/documentation.tar + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/config.doxygen + COMMAND tar cf documentation.tar -C ${HTML_PATH} . + COMMENT "The file documentation.tar contains the HTML website suitable to update/replace the gh-pages branch of this repository." VERBATIM ) + + add_custom_target(documentation + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/documentation.tar + WORKING_DIRECTORY ${HTML_PATH}) + + add_custom_command(OUTPUT ${HTML_PATH}/.git/config + DEPENDS documentation + WORKING_DIRECTORY ${HTML_PATH} + COMMAND git init . + COMMAND git checkout -B gh-pages + COMMAND git add . + COMMAND git commit -am 'Override all previous versions' + COMMAND git remote add parc ${PARC_REMOTE} + COMMAND git remote add github ${GITHUB_REMOTE}) + + add_custom_target(documentation-install-parc + DEPENDS ${HTML_PATH}/.git/config + WORKING_DIRECTORY ${HTML_PATH} + COMMAND git push parc gh-pages -f) + + add_custom_target(documentation-install-github + DEPENDS ${HTML_PATH}/.git/config + WORKING_DIRECTORY ${HTML_PATH} + COMMAND git push github gh-pages -f) + +endif(DOXYGEN_FOUND) diff --git a/longbow/documentation/DoxygenLayout.xml b/longbow/documentation/DoxygenLayout.xml new file mode 100644 index 00000000..759a9cd4 --- /dev/null +++ b/longbow/documentation/DoxygenLayout.xml @@ -0,0 +1,196 @@ +<doxygenlayout version="1.0"> + <!-- Generated by doxygen 1.8.9.1 --> + <!-- Navigation index tabs for HTML output --> + <navindex> + <tab type="mainpage" visible="yes" title="Overview"/> + <tab type="pages" visible="yes" title="" intro=""/> + <tab type="modules" visible="yes" title="" intro=""/> + <tab type="namespaces" visible="yes" title=""> + <tab type="namespacelist" visible="yes" title="" intro=""/> + <tab type="namespacemembers" visible="yes" title="" intro=""/> + </tab> + <tab type="classes" visible="yes" title="Public Types"> + <tab type="classlist" visible="yes" title="Type List" intro=""/> + <tab type="classindex" visible="$ALPHABETICAL_INDEX" title="Type Index"/> + <tab type="hierarchy" visible="yes" title="" intro=""/> + <tab type="classmembers" visible="no" title="" intro=""/> + </tab> + <tab type="globals" visible="yes" title="Global Entities" intro=""/> + + <tab type="files" visible="no" title=""> + <tab type="filelist" visible="yes" title="" intro=""/> + <tab type="globals" visible="yes" title="" intro=""/> + </tab> + <tab type="examples" visible="yes" title="" intro=""/> + </navindex> + + <!-- Layout definition for a class page --> + <class> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <inheritancegraph visible="$CLASS_GRAPH"/> + <collaborationgraph visible="$COLLABORATION_GRAPH"/> + <memberdecl> + <nestedclasses visible="yes" title=""/> + <publictypes title=""/> + <services title=""/> + <interfaces title=""/> + <publicslots title=""/> + <signals title=""/> + <publicmethods title=""/> + <publicstaticmethods title=""/> + <publicattributes title=""/> + <publicstaticattributes title=""/> + <protectedtypes title=""/> + <protectedslots title=""/> + <protectedmethods title=""/> + <protectedstaticmethods title=""/> + <protectedattributes title=""/> + <protectedstaticattributes title=""/> + <packagetypes title=""/> + <packagemethods title=""/> + <packagestaticmethods title=""/> + <packageattributes title=""/> + <packagestaticattributes title=""/> + <properties title=""/> + <events title=""/> + <privatetypes title=""/> + <privateslots title=""/> + <privatemethods title=""/> + <privatestaticmethods title=""/> + <privateattributes title=""/> + <privatestaticattributes title=""/> + <friends title=""/> + <related title="" subtitle=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <services title=""/> + <interfaces title=""/> + <constructors title=""/> + <functions title=""/> + <related title=""/> + <variables title=""/> + <properties title=""/> + <events title=""/> + </memberdef> + <allmemberslink visible="yes"/> + <usedfiles visible="$SHOW_USED_FILES"/> + <authorsection visible="yes"/> + </class> + + <!-- Layout definition for a namespace page --> + <namespace> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <memberdecl> + <nestednamespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <classes visible="yes" title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection visible="yes"/> + </namespace> + + <!-- Layout definition for a file page --> + <file> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <includes visible="$SHOW_INCLUDE_FILES"/> + <includegraph visible="$INCLUDE_GRAPH"/> + <includedbygraph visible="$INCLUDED_BY_GRAPH"/> + <sourcelink visible="yes"/> + <memberdecl> + <classes visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <constantgroups visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <functions title=""/> + <variables title=""/> + </memberdef> + <authorsection/> + </file> + + <!-- Layout definition for a group page --> + <group> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <groupgraph visible="$GROUP_GRAPHS"/> + <memberdecl> + <nestedgroups visible="yes" title=""/> + <dirs visible="yes" title=""/> + <files visible="yes" title=""/> + <namespaces visible="yes" title=""/> + <classes visible="yes" title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + <membergroups visible="yes"/> + </memberdecl> + <memberdef> + <pagedocs/> + <inlineclasses title=""/> + <defines title=""/> + <typedefs title=""/> + <enums title=""/> + <enumvalues title=""/> + <functions title=""/> + <variables title=""/> + <signals title=""/> + <publicslots title=""/> + <protectedslots title=""/> + <privateslots title=""/> + <events title=""/> + <properties title=""/> + <friends title=""/> + </memberdef> + <authorsection visible="yes"/> + </group> + + <!-- Layout definition for a directory page --> + <directory> + <briefdescription visible="yes"/> + <detaileddescription title=""/> + <directorygraph visible="yes"/> + <memberdecl> + <dirs visible="yes"/> + <files visible="yes"/> + </memberdecl> + </directory> +</doxygenlayout> diff --git a/longbow/documentation/LaTeX Documentation/.gitignore b/longbow/documentation/LaTeX Documentation/.gitignore new file mode 100644 index 00000000..a9f1afaf --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/.gitignore @@ -0,0 +1,7 @@ +.texpadtmp +*.aux +*.log +*.pdf +*.out +*.toc +*.synctex.gz diff --git a/longbow/documentation/LaTeX Documentation/Abstract.tex b/longbow/documentation/LaTeX Documentation/Abstract.tex new file mode 100644 index 00000000..0c394e76 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/Abstract.tex @@ -0,0 +1,7 @@ +%- +% ABSTRACT +%- +% +\Abstract{Software testing, validation, and measurable quality metics are an important element in modern software development. +LongBow is a software framework and facility for writing software using invariants, runtime validation, unit testing, and code analysis for the C programming language. +} diff --git a/longbow/documentation/LaTeX Documentation/Document.tex b/longbow/documentation/LaTeX Documentation/Document.tex new file mode 100644 index 00000000..273336ef --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/Document.tex @@ -0,0 +1,730 @@ +\begin{document} + +\flushbottom % Makes all text pages the same height + +\maketitle % Print the title and abstract box + +% Use the multicols package to a make multi-column table of contents. +\begin{multicols}{2} +\tableofcontents +\end{multicols} + +%For a single column table of contents just use this +%\tableofcontents % Print the contents section + +\thispagestyle{empty} % Removes page numbering from the first page + +%\newcommand{\HRule}{\rule{\linewidth}{0.5mm}} % Defines a new command for the horizontal lines, change thickness here + +\section{Overview} % The \section{} command stops section numbering + +LongBow is software to help you write better C programs. It provides: +\begin{itemize} +\item A run-time assertion facility to establish strict rules on the state of your program. +\item A testing facility based on the xUnit testing model. +\item Compile-time assistance for writing code meant to be compiled by compilers with different features. +\end{itemize} + +LongBow can help you find and manage problems early, establish and maintain confidence in the correctness of your code, make collaboration easier, facilitate future change, and improve overall design. + +LongBow allows you to take control and establish invariant pre- and post-conditions that detect inconsistencies and unexpected results in your programs in order to find bugs and design deficiencies in the code during development rather than waiting for others to find your bugs for you. + +\section{Set up and installation} +How to install, configure, link, and run LongBow. + +\subsection {Installation} +Get the tar file from xxx. +untar and do a make install. +The resulting LongBow directory will contain the C header files, C source files, and runtime libraries needed. + +\subsection {Configuration} + +\subsubsection{LongBow with LLDB} +The {\tt lldb} debugger is aware when C source files (not header files) are included in another source file. +This induces a problem where the breakpoints in the included source files are not set. +But you can configure lldb to set them: In the file {\tt \~/.lldbinit}, +add the line: + +\begin{lstlisting} +settings set target.inline-breakpoint-strategy always +process handle -p true -s false SIGABRT +\end{lstlisting} + +\subsubsection{LongBow with GDB} +LongBow uses signals to interrupt program flow when an assertion fails. +When using gdb this will cause gdb to stop running of the test. +This probably isn't what you want and would rather prefer that gdb just +ignore the signal and let the LongBow unit test signal handler take care of the signal. +To do this, you must configure gdb to ignore the signal and to allow it to pass to the program being executed. +In the file {\tt \~/.gdbinit}, add the line: + +\begin{lstlisting} +handle 6 nostop pass +\end{lstlisting} + +\subsubsection{Linking and Libraries} +There are two LongBow libraries that must be linked with the application: the primary LongBow library, (\url{liblongbow.a}) and one of the LongBow reporter libraries. +The reporter libraries enable the reporting mechanism for Longbow. +Currently two reporter libraries have been implemented: +\begin{enumerate} +\item \url{liblongbow-plaintext.a} which displays output as simple text; and +\item \url{liblongbow-ansiterm.a} which displays output as an ANSI colorized output. +\end{enumerate} + +Both display to standard output. + +\subsubsection{Running and Runtime Behavior} +You can "run" Longbow in one of two ways: you can run your application with assertions turned on in order to test expected invariance during runtime; or you can run your tests using Longbow's Test Runner. +Turning off assertions for runtime is not currently supported. + +\section{Programming with Assertions} + +Longbow's Assertions offer a way to check runtime invariance throughout your program. +Traps are a subset of Assertions that are executed at runtime even if Assertions have been turned off during deployment. They should be used when program failure is the correct response to assertion failure. + +The assertion framework is based on the following design principles: +\begin{itemize} +\item It is intentionally simple and can be extended. +\item You don't have to change your program design to accommodate assertions. +\item It is designed specifically for C programs. +\item It is based on programming with invariance. +\item Assertions may be used only during development as a debugging aid, or in deployment as well to offer more descriptive errors to users. +\end{itemize} + + +\subsection{Designing with Assertions } +Assertions can be used to debug code and give better information about errors to users. +They should not be used for error handling. +Assertions should be used to explicitly test for conditions that must be true in order for an operation to work. Examples include testing for NULL pointers, out-of-bounds array indices, and incorrect dependent relationships. Ultimately your code should work every time under all input conditions without ever triggering an assertion although passing tests don't guarantee proper design. You should aim for 100\% code coverage. + +Be strategic about where the assertions are located and what they test for. +A failed assertion should be considered a bug should be treated as such. +For example a failure to open a file is likely not a bug in your program, per se, but indicative of some other problem and programmatic error handling would probably be the best approach to handling the missing file. + +Assertions can be included or excluded at compile-time. In many cases, it is reasonable to keep the assertions in production releases as an aid to future bug reporting. + +\subsection{Using the Assertion Libraries } + +LongBow provides a basic set of assertions that test a condition and trigger the assertion if the condition fails to be true. When an assertion triggers the following occurs: +\begin{itemize} +\item An Event is created which records the kind of assertion that failed and the location of the assertion's failure. +\item The formatted message of the failed assertion is reported via the LongBow report library. +\item The running program is sent a {\tt SIGABRT} signal. +\end{itemize} + +The following four assertions are currently supported: +\begin{itemize} +\item {\tt assertTrue} +\item {\tt assertFalse} +\item {\tt assertNull} +\item {\ttfamily assertNotNull} +\end{itemize} + +The function signatures for assertions follow the pattern: + +\Cfunctiondef{\tt void}{assertX}{{\it condition}, {\tt "message", ...}} + +Where {\tt "message"} is a printf(3) format, nul-terminated C-String that will be displayed when the assertion triggers. The ... represents the arguments that might be used to create the string. + +There is one C header file that must be required to use the assertion mechanism: +\begin{itemize} +\item \textbf{LongBow/runtime.h} is the basic header file needed for assertions. +\end{itemize} + +\subsection {Using Traps} +LongBow traps are subsets of assertions and are intended for simple error reporting. +There is no functional difference between a trap and an assertion, however, a traps cannot be shut off during runtime so they are good to use for deployment if you plan to turn assertions off and the program should terminate when the assertion is not met. + +Traps take as arguments a condition and a printf(3) format C string of explanatory text along with any values necessary to format the string. + +A typical trap function signature is: + +\Cfunctiondef{\tt void}{trap{\it Kind}}{{\it condition}, {\tt "message", ...}} + +Where {\it Kind} represents the kind of trap (see {\tt LongBow/traps.h}. +If the {\it condition} is evaluated to {\tt true}, the trap is triggered. + +where {\tt ...} is the printf format string and values. + +\noindent Currently supported traps are defined in \texttt{traps.h} and include: +\begin{itemize} +\item \textbf{trapIllegalValue:} Used for capturing failed parameter validation, for example. +\item \textbf{trapIllegalValueIf:} Used to trap an illegal value if a condition is met. +\item \textbf{trapNotImplemented:} Used to report and abort an unimplemented capability. +\item \textbf{trapOutOfBounds:} Used to trap an out-of-bounds condition on an index. +\item \textbf{trapOutOfBoundsIf:} Used to trap an out-of-bounds condition for a specific value. +\item \textbf{trapOutOfMemory:} Used to signal that no more memory can be allocated. +\item \textbf{trapUnexpectedState:} Used to signal that an unexpected or inconsistent state was encountered. +\item \textbf{trapUnexpectedStateIf:} If the given condition is true, used to signal that an unexpected state was encountered. +\item \textbf{trapUnrecoverableState:} Used to report an unrecoverable state in program execution. +\end{itemize} + +\subsection{Examples } + +\paragraph {assertNotNull example} + +\begin{lstlisting} +#include <LongBow/assertions> +#include <unistd.h> +#include <string.h> + +void +function(char *pointer) +{ + assertNotNull(pointer, "The pointer cannot be NULL."); + + write(1, pointer, strlen(pointer)); +} + +int +main(int argc, char *argv[]) +{ + function(0); +} +\end{lstlisting} + + +In this case the {\tt assertNotNull} will trigger and the program will immediately terminate with the following output: + +\begin{lstlisting} +Assert pointer.c:8 function() pointer != NULL The pointer cannot be NULL. +0 pointer 0x0000000107840d4c function + 188 +1 pointer 0x0000000107840dd1 main + 33 +2 libdyld.dylib 0x00007fff887595fd start + 1 + +\end{lstlisting} + +\paragraph {assertTrue example} + +\begin{lstlisting} +LONGBOW_TEST_CASE(Global, myTest) +{ + struct timeval timeval; + timeval.tv_sec = 0; + timeval.tv_usec = 1000; + + char *expected = "0.001000"; + char *actual = parcTime\_FormatTimeval(timeval); + assertTrue(strcmp(expected, actual) == 0, "Expected \%s, actual \%s", expected, actual); + parc_free(actual); +} + \end{lstlisting} + +\paragraph{Example using assertNull, assertNotNull, and assertTrue} + +\begin{lstlisting} +static void +parcDeque_AssertInvariants(const PARCDeque *deque) +{ + assertNotNull(deque, "Parameter cannot be null."); + if (deque->head != NULL) { + assertTrue(deque->size != 0, "PARCDeque head is not-null, but size is zero."); + assertNotNull(deque->tail, "PARCDeque head is not-null, but tail is null."); + parcDequeNode_AssertInvariants(deque->head); + parcDequeNode_AssertInvariants(deque->tail); + } else { + assertNull(deque->tail, "PARCDeque head is null, but tail is not null."); + assertTrue(deque->size == 0, "PARCDeque head is null, but size is not zero."); + } +} + +\end{lstlisting} + +\paragraph {assertFalse example} +\begin{lstlisting} +RtaCommand * +rtaCommand_Read(int fd) +{ + ssize_t readlen; + uint32_t netbyteorder; + size_t len; + char *p; + RtaCommand *command; + + readlen = read(fd, &netbyteorder, 4); + assertFalse(readlen < 0, "socket read error: \%s\n", strerror(errno)); + assertTrue(readlen == 4, "Partial read on command length"); + + len = ntohl(netbyteorder); + p = parc_malloc(len); + readlen = read(fd, p, len); + assertTrue(readlen == len, "Partial read on command"); + + command = rtaCommand_Parse(p); + parc_free(p); + return command; +} +\end{lstlisting} + + +\section{Unit testing} +Longbow provides an xUnit-style unit testing framework. The framework is a mechanism for organizing and running trees of test code. It is organized hierarchically into three components: a Test Runner, Test Fixtures, and Test Cases. + +A Test Runner file is associated 1:1 with a C source file, with the word "test\_" prepended on the C source file name. For example, the Test Runner file for {\tt parc\_Buffer.c} would be {\tt test\_parc\_Buffer.c}. +This file contains all of the Test Fixtures and Test Cases needed to test the associated C source file. + +Each Test Runner will run a set of Test Fixtures. +Test Fixtures are an organizational unit that allows you to group your Test Cases. +The grouping may be done by functionality, by static vs non static functions, or by any other organizing principle that you choose. + +A Test Fixture runs a set of Test Cases each of which is responsible for testing some aspect of the C module. + +Tests are run in the order they are defined. +The Test Runner will start with Test Fixture1 and all of its Test Cases, move on to Test Fixture2 and its Test Cases etc. Tests should be idempotent, however, and not assume any particular order or be dependent on each other. +They should not leave state such that the next Test Case inherits that state. + +%\subsection{Designing tests } +%\textcolor{red}{Put something here} + +\subsection{Writing tests with the Test Runner module } +\subsubsection{Test Runners} +A Test Runner is the top-level executable unit in a test. +It is responsible for establishing the necessary state for the set of tests it contains, executing the tests via Test Fixtures and Test Cases, and tearing down state when the tests have completed. + +A Test Runner requires the following header files: +\begin{itemize} +\item \textbf{LongBow/runtime.h} is the basic header file needed for assertions and testing. +\item \textbf{LongBow/unit-test.h} is the basic header file needed for testing. +\item \textbf{LongBow/compiling.h} is used when you have code that needs to work across multiple compilers - it contains the matrix of compiler and / you are using. +\end{itemize} + +\noindent The source code of a Test Runner has the following basic structure: + +\begin{lstlisting} +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(myRunner) +{ +} + +LONGBOW_TEST_RUNNER_SETUP(myRunner) +{ + // Code to set up required state + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myRunner) +{ + //Code to clean up state + return LONGBOW_STATUS_SUCCEEDED; +} + +\end{lstlisting} + + +Each of these functions has a local variable - {\tt LongBowRunner *testRunner} - which may be used to manipulate the clipboard (as an example). The Text Fixtures and Test Cases launched by the Test Runner will have access to this variable as well as their own local variable. Thus a Test Fixture will have access to the {\tt testRunner} that is passed to it as well as its own {\tt LongBowFixture *testFixture} and a Test Case will have access to {\tt testRunner, testFixture} and its own {\tt LongBowCase *testCase}. + +\subsubsection{Test Fixtures} + +A Test Fixture is a subcomponent which has the same structure as a Test Runner. +The following code adds Test Fixture to a Test Runner: + +\begin{lstlisting} +LONGBOW_TEST_RUNNER(myRunner) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} +\end{lstlisting} + + +Like the Test Runner, it is responsible for setting up and tearing down state needed by the Test Cases. + +\begin{lstlisting} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, myTest); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} +\end{lstlisting} + +\subsubsection{Test Cases} +Test Cases are the leaf nodes of the testing tree. Each Test Case tests one aspect of the C module. + +\paragraph {Handling Test Case state safely} + +Every Test Case has access to a private \"clipboard\" that contains data shared between the Test Case and the set up and teardown functions of its encapsulating Test Fixture. +This shared state is used to provide specific environment or initialized variables for the test and for the test to communicate specialized information to the teardown function. + +For example, a Test Case which is expected to fail as the result of testing a failure condition might exit without releasing resources which are left in an unsafe state. +As multiple tests may be run in one process, it is important to clean these up before launching the next test. + +The following example demonstrates the clipboard mechanism: +\begin{itemize} +\item{The Test Fixture setup function allocates the necessary resources and puts references to them into the clipboard.} +\item{The Test Case gets these references, uses them, and fails.} +\item{The Test Fixture tear-down function obtains the resources from the clipboard and deallocates them.} +\end{itemize} + +\subsubsection {Test Runner Example} +The following is an example of a test file : + +\begin{lstlisting} +#include <stdio.h> +#include <string.h> + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(testClipboard) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, testClipboard); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + char *testData = strdup("Hello World"); + longBowTest Case_SetClipBoardData(testCase, testData, free); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, testClipboard) +{ + char *testData = longBowTest Case_GetClipBoardData(testCase); + printf("Shared state '%s'\n", testData); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(testClipboard); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTest Runner_Destroy(&testRunner); + exit(exitStatus); +} +\end{lstlisting} + +\subsubsection {Testing for Successful Failure} +Testing for success is straightforward but we also may have to test that something fails when it is supposed to. +This section describes how to test for an expected non-success result. + +To compose a Test Case that expects a result other than success, use the {\tt LONGBOW\_TEST\_CASE\_EXPECTS} function which takes the expected event as a parameter and completes. The example below shows the capture of a successful segmentation fault. + + +\begin{lstlisting} +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> + +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(LongBow) +{ + LONGBOW_RUN_TEST_FIXTURE(MyFixture); +} + +LONGBOW_TEST_RUNNER_SETUP(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(MyFixture) +{ + LONGBOW_RUN_TEST_CASE(MyFixture, alwaysSEGV); +} + +LONGBOW_TEST_FIXTURE_SETUP(MyFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(MyFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE_EXPECTS(MyFixture, alwaysSEGV, .event = &LongBowEventSIGSEGV) +{ + int *p = 0; + int i = *p; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(LongBow); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner, NULL); + longBowTest Runner_Destroy(&testRunner); + + exit(status); +} + +\end{lstlisting} + +\subsection{Running tests} + +The overall process for writing and running your tests: +\begin{itemize} +\item Write a Test Runner file for every .c file that completely tests all of the code container in the .c file. This filename should be "test\_" prepended to the name of the file you are testing. +\item Compile the Test Runner file with one of: +\begin {itemize} +\item -llongbow -llongbow-ansiterm +\item -llongbow -llongbow-textplain +\end{itemize} +\item Execute the Test Runner. +\end{itemize} + + +\subsection{Examples } + +Here is an example of a C source file and its associated Test file. Tutorial.c is a small C program which simply provides an uninteresting but useful exemplar of the test framework. + + +\noindent \textbf{Tutorial.c} + +\begin{lstlisting} +#include <unistd.h> +#include <stdbool.h> +#include <signal.h> + +static bool +_privateFunction() +{ + return true; +} + +bool +alwaysSucceed() +{ + return _privateFunction(); +} + +bool +alwaysFail() +{ + return false; +} + +bool +blowUp() +{ + char *p = 0; + *p = 0; + + return true; +} + +\end{lstlisting} + +The following code is the test file for the Tutorial.c. Note that the file name is simply the C source file name with "test\_" prepended. In this example, the Test Runner divides the Test Cases into two Test Fixtures: one to focus on the Static functions and one to focus on the Global functions. + +\noindent \textbf{test\_Tutorial.c} +\begin{lstlisting} + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Static); + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); + LONGBOW_RUN_TEST_CASE(Global, blowUp); + +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + bool result = alwaysFail(); + + assertTrue(result, "This test will fail."); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, blowUp, .event = &LongBowEventSIGSEGV) +{ + blowUp(); + + assertTrue(false, "This will not be executed"); +} + + +LONGBOW_TEST_FIXTURE(Static) +{ + LONGBOW_RUN_TEST_CASE(Static, _privateFunction); +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Static, _privateFunction) +{ + bool result = _privateFunction(); + + assertTrue(result, "This test must always succeed."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTest Runner_Destroy(&testRunner); + exit(status); +} + +\end{lstlisting} + +\section {Compiling and Compiler Support} +LongBow consolidates a variety of compile-time options that you include in your code. + +For example, the C99 standard defines the pragma operator and various compilers support this in various ways. + +\section{The LongBow Reporter} +The Longbow reporter offers a more user-friendly option for viewing the output of the running tests. In addition to linking with the primary LongBow library ({\tt liblongbow.a}), you also need to link with one of the following reporting libraries to control presentation of the test output. +\begin{itemize} +\item {\bf liblongbow-ansiterm.a} This option produces output that is color coded to indicate the degree of success: green for a successful test; yellow for warnings; and red for failure. +\item {\bf liblongbow-plaintext.a} This option produces plain text output. +\item {\bf liblongbow-json.a} This option is in development and will produce output in JSON format. +\end{itemize} + + + +\section {Appendices} +\subsection {Function Documentation} +The following modules are included in LongBow: +\begin {itemize} +\item \textbf{Runtime:} LongBow functions and macros for runtime. +\item \textbf{Testing:} LongBow functions and macros for writing tests. +\item \textbf{Internals:} LongBow functions and macros used internally. +\item \textbf{Reporting:} LongBow functions and definitions for writing report libraries. +\item \textbf{Performance testing:} LongBow functions and definitions for writing performance tests. +\end{itemize} + +\paragraph {Runtime} +LongBow runtime support consists primarily of assertions and traps. Developers insert assertions to insist that certain conditions are true before permitting the program to continue. If the assertion fails, the program is abnormally terminated. It uses the following files: + +\begin{itemize} +\item {\bf assertions.h:} Runtime and Test Assertions. + \item {\bf longBow\_EventType.h:} LongBow Events and Support. + \item {\bf longBow\_Runtime.h:} The LongBow Runtime support. + \item {\bf runtime.h:} LongBow Runtime Support. + \item {\bf traps.h:} Runtime and Test Traps. +\end{itemize} + + +\paragraph {Testing} +LongBow testing support consists of macros and ancillary functions to implement an xUnit style of writing and running tests. Test writers create a LONGBOW\_TEST\_RUNNER function which invokes one or more LONGBOW\_TEST\_FIXTURE functions, each of which invoke a specific LONGBOW\_TEST\_CASE. It uses the following files: + +\begin{itemize} +\item {\bf longBow\_EventType.h:} LongBow Events and Support. + \item {\bf longBow\_Main.h:} A main() function to run one or more LongBow Test Runners. + \item {\bf longBow\_OpenFile.h:} LongBow support for files and file descriptors. + \item {\bf longBow\_Runner.h:} LongBow Test Runner Support. + \item {\bf longBow\_Status.h} A simple status representation for a LongBow Test Case. + \item {\bf longBow\_Test CaseClipBoard.h:} LongBow Clipboard shared between the setup, test case, and teardown. + \item {\bf longBow\_UnitTesting.h} Unit Testing Support. . + \item {\bf testing.h:} LongBow testing functionality. + \item {\bf unit-test.h} LongBow Unit Test Support. +\end{itemize} + +\paragraph {Internals} +LongBow functions and macros used internally. +It uses the following files: + +\begin{itemize} + \item {\bf longBow\_ArrayList.h} A simple, list implementation using a dynamic array. + \item {\bf longBow\_Backtrace.h} Support for Stack Traces. + \item {\bf longBow\_Configuration.h} Support for LongBow Configuration. + \item {\bf longBow\_Debugging.h} Support for LongBow and Application Debugging. + \item {\bf longBow\_Event.h} LongBow Event Support. + \item {\bf longBow\_EventType.h} LongBow Events and Support. + \item {\bf longBow\_Fixture.h} Manage the execution of Test Cases. + \item {\bf longBow\_Location.h} LongBow Source File Location. + \item {\bf longBow\_Test Case.h} The interface and supporting functionality of a LongBow Test Case. + \item {\bf longBow\_Test CaseResult.h} LongBow Test Case Results. +\end{itemize} + + + \paragraph {Reporting} +LongBow functions and definitions for writing report libraries. +It uses the following header files: + +\begin{itemize} + \item {\bf longBow\_ReportANSITerminal\_Runtime.h} ANSI Terminal Reporting. +\item {\bf longBow\_Report\_Runtime.h} The LongBow Runtime Report Generator. +\item {\bf longBow\_Report\_Testing.h} The LongBow Test Report Generator. +\end{itemize} + + + \paragraph {Performance Testing} +Using LongBow for performance tests. + +\end{document} diff --git a/longbow/documentation/LaTeX Documentation/LongBow.tex b/longbow/documentation/LaTeX Documentation/LongBow.tex new file mode 100644 index 00000000..8f8a7e60 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/LongBow.tex @@ -0,0 +1,37 @@ +%---------------------------------------------------------------------------------------- +% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS +%---------------------------------------------------------------------------------------- +\documentclass[fleqn,12pt]{PARCOneColumn} % Document font size and equations flushed left +% +%---------------------------------------------------------------------------------------- +% COLUMNS +%---------------------------------------------------------------------------------------- +% +\setlength{\columnsep}{0.55cm} % Distance between the two columns of text +\setlength{\fboxrule}{0.75pt} % Width of the border around the abstract +% +%---------------------------------------------------------------------------------------- +% HYPERLINKS +%---------------------------------------------------------------------------------------- +% +\definecolor{urlcolor}{RGB}{0,0,90} % Color of the article title and sections +\definecolor{citecolor}{RGB}{0,0,90} % Color of the article title and sections +\definecolor{linkcolor}{RGB}{0,0,90} % Color of the article title and sections +\usepackage{hyperref} % Required for hyperlinks +\hypersetup{hidelinks, +colorlinks, +breaklinks=true, +urlcolor=urlcolor, +citecolor=citecolor, +linkcolor=linkcolor, +bookmarksopen=false, +pdftitle={Title}, +pdfauthor={Author}} +% +\input{Packages} +% +\input{title} +% +\input{abstract} +% +\input{document} diff --git a/longbow/documentation/LaTeX Documentation/PARCOneColumn.cls b/longbow/documentation/LaTeX Documentation/PARCOneColumn.cls new file mode 100644 index 00000000..a58d3409 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/PARCOneColumn.cls @@ -0,0 +1,288 @@ +% A PARC specific refinement of: +% +% Stylish Article +% LaTeX Template +% Version 2.0 (13/4/14) +% +% Available from: +% http://www.LaTeXTemplates.com +% +% Original author: +% Mathias Legrand (legrand.mathias@gmail.com) +% +% License: +% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/) +% --------------------------------------------------------------------- +% Conference proceedings and article templates for +% personal open-archiving activities +% September 2012 +% --------------------------------------------------------------------- + +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{PARCOneColumn}[25/01/2012, v1.0] +\RequirePackage{ifthen} +\RequirePackage{calc} +\AtEndOfClass{\RequirePackage{microtype}} +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\ProcessOptions* +\LoadClass{article} +\RequirePackage{ifpdf} % Needed to pick between latex and pdflatex + +%---------------------------------------------------------------------- +% FONTS +%---------------------------------------------------------------------- + +%\RequirePackage{times} % Loads the Times-Roman Fonts +\RequirePackage{palatino} % Loads the Palatino Fonts +%\RequirePackage{mathptmx} % Loads the Times-Roman Math Fonts + +%---------------------------------------------------------------------- +% VARIOUS USEFUL PACKAGES +%---------------------------------------------------------------------- + +\RequirePackage[utf8]{inputenc} +\RequirePackage{amsmath,amsfonts,amssymb} +\RequirePackage{graphicx,xcolor} +\RequirePackage[english]{babel} +\RequirePackage{booktabs} +\RequirePackage{multicol} +\RequirePackage{tabularx} + +%---------------------------------------------------------------------- +% MARGINS +%---------------------------------------------------------------------- + +\RequirePackage[left=2cm,% + right=2cm,% + top=2.25cm,% + bottom=2.25cm,% + headheight=11pt,% + letterpaper]{geometry}% + +%---------------------------------------------------------------------- +% FIGURES AND TABLES CAPTIONS +%---------------------------------------------------------------------- + +\RequirePackage[labelfont={bf,sf,small},% + labelsep=period,% + justification=raggedright]{caption} +\setlength{\abovecaptionskip}{0pt} +\setlength{\belowcaptionskip}{0pt} + +%---------------------------------------------------------------------- +% PARC Colors +%---------------------------------------------------------------------- + +\definecolor{PARCBlue}{RGB}{32,84,105} +\definecolor{PARCDarkBlue}{RGB}{0,35,50} +\definecolor{PARCLightBlue}{RGB}{58,110,143} +\definecolor{PARCOrange}{RGB}{255,102,0} +\definecolor{PARCLightGray}{RGB}{213,213,213} +\definecolor{PARCDarkGray}{RGB}{58,58,58} + +\definecolor{AbstractBackgroundColor}{RGB}{58,110,143} + +\definecolor{SectionColor}{RGB}{0,0,90} % Color of the article title and sections +% +%---------------------------------------------------------------------- +% PAGE HEADER +%---------------------------------------------------------------------- +% +\RequirePackage{fancyhdr} % Needed to define custom headers/footers +\headheight=13.6pt +\RequirePackage{lastpage} % Number of pages in the document +\pagestyle{fancy} % Enables the custom headers/footers +% Headers +\lhead{}% +\chead{}% +\rhead{\small\sffamily\bfseries\@PaperTitle\ --- \thepage/\pageref{LastPage}} +% Footers +\lfoot{\small\sffamily\bfseries\@LeftFooter}% +\cfoot{\small\sffamily\bfseries\@CenterFooter}% +\rfoot{\small\sffamily\bfseries\@RightFooter}% +\renewcommand{\headrulewidth}{0pt}% % No header rule +\renewcommand{\footrulewidth}{0pt}% % No footer rule + +%---------------------------------------------------------------------- +% SECTION/SUBSECTION/PARAGRAPH SET-UP +%---------------------------------------------------------------------- + +\RequirePackage[explicit]{titlesec} +\titleformat{\section} + {\color{PARCDarkBlue}\large\sffamily\bfseries} + {} + {0em} + {\colorbox{PARCDarkBlue!10}{\parbox{\dimexpr\linewidth-2\fboxsep\relax}{\centering\arabic{section}. #1}}} + [] +\titleformat{name=\section,numberless} + {\color{PARCDarkBlue}\large\sffamily\bfseries} + {} + {0em} + {\colorbox{PARCDarkBlue!10}{\parbox{\dimexpr\linewidth-2\fboxsep\relax}{\centering#1}}} + [] +\titleformat{\subsection} + {\color{PARCDarkBlue}\sffamily\bfseries} + {\thesubsection} + {0.5em} + {#1} + [] +\titleformat{\subsubsection} + {\sffamily\small\bfseries} + {\thesubsubsection} + {0.5em} + {#1} + [] +\titleformat{\paragraph}[runin] + {\sffamily\small\bfseries} + {} + {0em} + {#1} +\titlespacing*{\section}{0pc}{3ex \@plus4pt \@minus3pt}{5pt} +\titlespacing*{\subsection}{0pc}{2.5ex \@plus3pt \@minus2pt}{0pt} +\titlespacing*{\subsubsection}{0pc}{2ex \@plus2.5pt \@minus1.5pt}{0pt} +\titlespacing*{\paragraph}{0pc}{1.5ex \@plus2pt \@minus1pt}{10pt} + +%---------------------------------------------------------------------- +% TABLEOFCONTENTS SET-UP +%---------------------------------------------------------------------- +\newlength{\tocsep} +\setlength\tocsep{2em} % Sets the indentation of the sections in the table of contents +\setcounter{tocdepth}{3} % Three levels in the table of contents section: sections, subsections and subsubsections + +\usepackage{titletoc} +\contentsmargin{0cm} +\titlecontents{section}[\tocsep] + {\addvspace{4pt}\small\bfseries\sffamily} + {\contentslabel[\thecontentslabel]{\tocsep}} + {} + {\hfill\thecontentspage} + [] +\titlecontents{subsection}[\tocsep] + {\addvspace{2pt}\sffamily} + {\contentslabel[\thecontentslabel]{\tocsep}} + {} + {\ \titlerule*[.5pc]{.}\ \thecontentspage} + [] +\titlecontents*{subsubsection}[\tocsep] + {\footnotesize\sffamily} + {} + {} + {} + [\ \textbullet\ ] + +%---------------------------------------------------------------------- +% MULTIPLE AUTHOR SET +%---------------------------------------------------------------------- + +\newcount\@authcnt +\newcount\@tmpcnt\@tmpcnt\z@ + +\def\@affiliation{% + \ifnum\@tmpcnt<\@authcnt + \global\advance\@tmpcnt1 + \raggedright \csname @auth\romannumeral\the\@tmpcnt\endcsname\hfill\\% + \let\next\@affiliation \vskip1pt + \else + \let\next\relax + \fi +\next} + +\newcommand{\affiliation}[1]{% + \global\advance\@authcnt1 + \expandafter\gdef\csname @auth\romannumeral\the\@authcnt\endcsname + {#1}} + + +%---------------------------------------------------------------------- +% LIST CONTROL +%---------------------------------------------------------------------- + +\RequirePackage{enumitem} +%\setlist{nolistsep} % Uncomment to remove spacing between items in lists (enumerate, itemize) + +%---------------------------------------------------------------------- +% ABSTRACT+AUTHOR FRAME +%---------------------------------------------------------------------- + +\newcommand{\PaperTitle}[2]{\def\@PaperTitle{#1}\def\@PaperSubtitle{#2}} +\newcommand{\Archive}[1]{\def\@Archive{#1}} +\newcommand{\Authors}[1]{\def\@Authors{#1}} +\newcommand{\JournalInfo}[1]{\def\@JournalInfo{#1}} +\newcommand{\Abstract}[1]{\def\@Abstract{#1}} +\newcommand{\Keywords}[1]{\def\@Keywords{#1}} +\newcommand{\Masthead}[1]{\def\@Masthead{#1}} + +\newcommand{\LeftFooter}[1]{\def\@LeftFooter{#1}} +\newcommand{\CenterFooter}[1]{\def\@CenterFooter{#1}} +\newcommand{\RightFooter}[1]{\def\@RightFooter{#1}} + +\LeftFooter{} +\CenterFooter{} +\RightFooter{} +% +% --------------------------------------------------------------------- +% +\newcommand{\NormalSansBold}[1]{\normalsize\sffamily\bfseries #1} +\newcommand{\SmallSansBold}[1]{\small\sffamily\bfseries #1} +\newcommand{\MastHeadText}[1]{\sffamily\fontsize{10}{12}\selectfont #1} +% +\newcommand{\MakePARCMastHead}[1]{ +\setlength{\tabcolsep}{0pt} +\begin{tabular*}{\textwidth}{l @{\extracolsep{\fill}} p{0.618\textwidth} } + \includegraphics[width=110pt]{parc_black_solid}&\vbox{\raggedleft\MastHeadText{#1}\vskip0.24mm}\\ +\end{tabular*} +\vskip-5mm\hrule +} +% +\newcommand{\MakeTitle}[2]{% +{\raggedright\color{SectionColor}\sffamily\bfseries\fontsize{22}{25}\selectfont #1\par}% +{\raggedright\color{SectionColor}\sffamily\bfseries\fontsize{16}{24}\selectfont #2\par}% +} +% +\newcommand{\MakeAbstract}[2]{% +\parbox{\textwidth-6\fboxsep-2\fboxrule}{% +\ifx\@Keywords\@empty% +\sffamily\textbf{\abstractname}\\#1% +\else% +\sffamily\textbf{\abstractname}\\#1\\[4pt]% +\textbf{\keywordname}\\#2% +\fi% +}% +}% +% +\renewcommand{\@maketitle}{% +\centering{% +\thispagestyle{empty}% +\MakePARCMastHead{\@Masthead}% +\vskip30pt% +\MakeTitle{\@PaperTitle}{\@PaperSubtitle}% +\vskip10pt% +{\raggedright\color{SectionColor}\sffamily\fontsize{12}{16}\selectfont\@Authors\par}% +\vskip18pt% +\fcolorbox{SectionColor}{white}{% +\parbox{\textwidth-2\fboxsep-2\fboxrule}{\centering% +\colorbox{AbstractBackgroundColor!10}{% +\MakeAbstract{\@Abstract}{\@Keywords} +}% +\vskip4pt% +\begingroup% +\raggedright\sffamily\small% +\footnotesize\@affiliation\par% +\endgroup%% +}% +}% +\vskip25pt% +}% +}% +%---------------------------------------------------------------------- +% REFERENCES +%---------------------------------------------------------------------- + +% Remove brackets from numbering in List of References +\renewcommand{\@biblabel}[1]{\bfseries\color{SectionColor}\textsuperscript{[#1]}} +%\setlength{\bibitemsep}{0cm} +\let\oldbibliography\thebibliography +\renewcommand{\thebibliography}[1]{% +\addcontentsline{toc}{section}{\refname}% +\oldbibliography{#1}% +\setlength\itemsep{0pt}}% diff --git a/longbow/documentation/LaTeX Documentation/Packages.tex b/longbow/documentation/LaTeX Documentation/Packages.tex new file mode 100644 index 00000000..90f5f6db --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/Packages.tex @@ -0,0 +1,58 @@ +% +% Specify packages that you need in this file. +% If a package requires configuration, do that here. +\usepackage{lipsum} +\usepackage{tcolorbox} + +\usepackage{listings} + +\definecolor{goodCodeColor}{rgb}{1.0,1.0,1.0} +\definecolor{badCodeColor}{rgb}{1.0,0.95,0.95} +\definecolor{mygreen}{rgb}{0,0.6,0} +\definecolor{mygray}{rgb}{0.5,0.5,0.5} +\definecolor{mymauve}{rgb}{0.58,0,0.82} +\lstset{ % + backgroundcolor=\color{goodCodeColor}, % choose the background color; you must add \usepackage{color} or \usepackage{xcolor} + basicstyle=\tt\small, % the size of the fonts that are used for the code + breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace + breaklines=true, % sets automatic line breaking + captionpos=b, % sets the caption-position to bottom + commentstyle=\color{mygreen}, % comment style + deletekeywords={...}, % if you want to delete keywords from the given language + escapeinside={@}{@}, % if you want to add LaTeX within your code + extendedchars=true, % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8 + frame=single, % adds a frame around the code + keepspaces=true, % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible) + keywordstyle=\color{blue}, % keyword style + language=C, % the language of the code + morekeywords={*,...}, % if you want to add more keywords to the set + numbers=left, % where to put the line-numbers; possible values are (none, left, right) + numbersep=5pt, % how far the line-numbers are from the code + numberstyle=\tiny\color{mygray}, % the style that is used for the line-numbers + rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here)) + showspaces=false, % show spaces everywhere adding particular underscores; it overrides 'showstringspaces' + showstringspaces=false, % underline spaces within strings only + showtabs=false, % show tabs within strings adding particular underscores + stepnumber=2, % the step between two line-numbers. If it's 1, each line will be numbered + stringstyle=\color{mymauve}, % string literal style + tabsize=2, % sets default tabsize to 2 spaces + title=\lstname % show the filename of files included with \lstinputlisting; also try caption instead of title +} + + +\newcommand{\functionBox}[1]{% + \begin{tcolorbox}[boxrule=0.5pt,arc=4pt,left=6pt,right=6pt,top=6pt,bottom=6pt,boxsep=0pt] + #1 + \end{tcolorbox}} + +\newcommand{\Returns}[2]{{\bf Returns:} #1\hfil\break\begin{tabular}{l r l} #2 \end{tabular}} +\newcommand{\retval}[2]{\hbox to1em{} & {#1} & {#2}\\ } + +\newcommand{\Cfunctionparam}[3]{\hbox to1em{} & #1 & {\tt #2} & #3 \\} +\newcommand{\paramdef}[1]{\begin{tabular}{ r r l l } #1\end{tabular}\hfil\break} +\newcommand{\Cfunctiondef}[3]{\functionBox{{#1} {\tt #2(}\hfil\break\paramdef{#3}{\tt )}}} + +\newcommand{\Cfunctionref}[1]{{\tt #1()}} +\newcommand{\functionAbstract}[1]{#1\hfil\break} +\newcommand{\functionReturns}[2]{{\bf Returns:}\hfil\break\indent\hbox to3em{} #1: #2\hfil\break} +\newcommand{\NULL}{{\tt NULL }} diff --git a/longbow/documentation/LaTeX Documentation/Title.tex b/longbow/documentation/LaTeX Documentation/Title.tex new file mode 100644 index 00000000..b05521b7 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/Title.tex @@ -0,0 +1,13 @@ +%---------------------------------------------------------------------------------------- +% ARTICLE INFORMATION +%---------------------------------------------------------------------------------------- +\Masthead{Networking and Distributed Systems\\Computing Science Laboratory\\Copyright 2014} + +\PaperTitle{LongBow}{Write Better C Programs} % Article title + +\Authors{Glenn Scott\textsuperscript{1}*} % Authors +\affiliation{\textsuperscript{1}\textit{Computing Science Laboratory, PARC}} % Author affiliation +\affiliation{*\textbf{Corresponding author}: glenn.scott@parc.com} % Corresponding author + +\Keywords{Software Development --- Software Testing} % Keywords - if you don't want any simply remove all the text between the curly brackets +\newcommand{\keywordname}{Keywords} % Defines the keywords heading name diff --git a/longbow/documentation/LaTeX Documentation/old/Longbow_documentation.tex b/longbow/documentation/LaTeX Documentation/old/Longbow_documentation.tex new file mode 100644 index 00000000..5db370c2 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/old/Longbow_documentation.tex @@ -0,0 +1,769 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Simple Sectioned Essay Template +% LaTeX Template +% +% This template has been downloaded from: +% http://www.latextemplates.com +% +% Note: +% The \lipsum[#] commands throughout this template generate dummy text +% to fill the template out. These commands should all be removed when +% writing essay content. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%---------------------------------------------------------------------------------------- +% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS +%---------------------------------------------------------------------------------------- + +\documentclass[12pt]{article} % Default font size is 12pt, it can be changed here + +\usepackage{graphicx} % Required for including pictures + +\usepackage{float} % Allows putting an [H] in \begin{figure} to specify the exact location of the figure +\usepackage{wrapfig} % Allows in-line images such as the example fish picture + +\usepackage{lipsum} % Required to insert dummy text +\usepackage{hyperref} + +\usepackage{wrapfig} +\usepackage[toc]{appendix} +\usepackage{url} +\usepackage{mdframed} +\usepackage{listings} +\lstset{ % +basicstyle=\tt\footnotesize, +breakatwhitespace=false, + breaklines=true. + tabsize=4 +} + +\usepackage{float} +\restylefloat{table} + + +\linespread{1.2} % Line spacing + +%\setlength\parindent{0pt} % Uncomment to remove all indentation from paragraphs + +\graphicspath{{Pictures/}} % Specifies the directory where pictures are stored + +\begin{document} + +%---------------------------------------------------------------------------------------- +% TITLE PAGE +%---------------------------------------------------------------------------------------- +\begin{titlepage} + +\newcommand{\HRule}{\rule{\linewidth}{0.5mm}} % Defines a new command for the horizontal lines, change thickness here + +\center % Center everything on the page + + +\HRule \\[0.4cm] +{ \huge \bfseries Longbow Documentation}\\[0.4cm] % Title of your document +\HRule \\[1.5cm] + +\begin{minipage}{0.4\textwidth} +\begin{flushleft} \large +\emph{Author:}\\ +Glenn \textsc{Scott} % Your name +\end{flushleft} +\end{minipage} +~ + +{\large \today}\\[3cm] % Date, change the \today to a set date if you want to be precise + +%\includegraphics{Logo}\\[1cm] % Include a department/university logo - this will require the graphicx package + +\vfill % Fill the rest of the page with whitespace + +\end{titlepage} + +%---------------------------------------------------------------------------------------- +% TABLE OF CONTENTS +%---------------------------------------------------------------------------------------- + +\tableofcontents % Include a table of contents +\newpage +\section{Overview} % The \section{} command stops section numbering + +LongBow is software to help you write better C programs. It provides: +\begin{itemize} +\item a run-time assertion facility to establish strict rules on the state of your program. +\item a testing facility based on the xUnit testing model. +\item compile-time assistance for writing code meant to be compiled by compilers with different features. +\end{itemize} + +LongBow can help you find and manage problems early, establish and maintain confidence in the correctness of your code, make collaboration easier, facilitate future change, and improve overall design. + +LongBow allows you to take control and establish invariant pre- and post-conditions that detect inconsistencies and unexpected results in your programs in order to find bugs and design deficiencies in the code during development rather than waiting for others to find your bugs for you. + +\section{Set up and installation} +How to install, configure, link, and run LongBow. +\subsection {Installation} +Get the tar file from xxx. +untar and do a make install. +The resulting LongBow directory will contain the C header files, C source files, and runtime libraries needed. + +\subsection {Configuration} + +\subsubsection{LongBow with LLDB} +The {\tt lldb} debugger is aware when C files are included. This induces a problem where the breakpoints in the included files are not set. But you can configure lldb to set them: In ~/.lldbinit settings set target.inline-breakpoint-strategy always + + +\hfill \texttt{settings set target.inline-breakpoint-strategy always} \hfill \break + +\subsubsection{LongBow with GDB} +LongBow uses signals to interrupt program flow when an assertion fails. When using gdb this will cause gdb to stop running of the test. This probably isn?t what you want and would rather prefer that gdb just ignore the signal and let the LongBow unit test signal handler take care of the signal. To do this, you must configure gdb to ignore the signal and to allow it to pass to the program being executed. + + +\hfill \texttt{handle 6 nostop pass} \hfill \break + +\subsubsection{Linking and Libraries} +There are two LongBow libraries that must be linked with the application: the primary LongBow library, (\url{liblongbow.a}) and one of the LongBow reporter libraries. The reporter libraries enable the reporting mechanism for Longbow. Currently two reporter libraries have been implemented: \url{liblongbow-plaintext.a} which displays output as simple text; and \url{liblongbow-ansiterm.a} which displays output as an ANSI colorized output. Both display to standard output. + +\subsubsection{Running and Runtime Behavior} +You can "run" Longbow in one of two ways: you can run your application with assertions turned on in order to test expected invariance during runtime; or you can run your tests using Longbow's Test Runner. Turning off assertions for runtime is not currently supported. + +\section{Programming with Assertions} + + Longbow's Assertions offer a way to check runtime invariance throughout your program. Traps are a subset of Assertions that are executed at runtime even if Assertions have been turned off during deployment. They should be used when program failure is the correct response to assertion failure. + +The assertion framework is based on the following design principles: +\begin{itemize} +\item It is intentionally simple and can be extended. +\item You don't have to change your program design to accommodate assertions. +\item It is designed specifically for C programs. +\item It is based on programming with invariance. +\item Assertions may be used only during development as a debugging aid, or in deployment as well to offer more descriptive errors to users. +\end{itemize} + + +\subsection{Designing with Assertions } +Assertions can be used to debug code and give better information about errors to users. They should not be used for error handling. Assertions should be used to explicitly test for conditions that must be true in order for an operation to work. Examples include testing for NULL pointers, out-of-bounds array indices, and incorrect dependent relationships. Ultimately your code should work every time under all input conditions without ever triggering an assertion although passing tests don't guarantee proper design. You should aim for 100\% code coverage. + +Be strategic about where the assertions are located and what they test for. +A failed assertion should be considered a bug should be treated as such. For example a failure to open a file is likely not a bug in your program, per se, but indicative of some other problem and programmatic error handling would probably be the best approach to handling the missing file. + +Assertions can be included or excluded at compile-time. In many cases, it is reasonable to keep the assertions in production releases as an aid to future bug reporting. + +\subsection{Using the Assertion Libraries } + +LongBow provides a basic set of assertions that test a condition and trigger the assertion if the condition fails to be true. When an assertion triggers the following occurs: +\begin{itemize} +\item An Event is created which records the kind of assertion that failed and the location of the assertion's failure. +\item The formatted message of the failed assertion is reported via the LongBow report library. +\item The running program is sent a SIGABRT signal. +\end{itemize} + +The following four assertions are currently supported: +\begin{itemize} +\item assertTrue +\item assertFalse +\item assertNull +\item assertNotNull +\end{itemize} + +The function signatures are: + +\hfill \texttt{void assertX(condition, "\_\_\_",...);} \hfill \break +where "\_\_\_" is the printf null-terminated C-String that will be displayed when the assertion triggers. The ... represents the arguments that might be used to create the string. + +There are two basic C header files that are needed: +\begin{itemize} +\item \textbf{LongBow/runtime.h} is the basic header file needed for assertions and testing. +\item \textbf{LongBow/compiling.h} is used when you have code that needs to work across multiple compilers. +\end{itemize} + +\subsection {Using Traps} +LongBow traps are subsets of assertions and are intended for simple error reporting. There is no functional difference between a trap and an assertion, however, Traps cannot be shut off during runtime so they are good to use for deployment if you plan to turn assertions off and the program should terminate when the assertion is not met. + +Traps take as arguments a condition and a printf(3) format string of explanatory text along with any required values. A typical trap is called with: + +{\tt trap (condition, ...) } + +where {\tt ...} is the printf format string and values. + +\noindent Currently supported traps are defined in \texttt{traps.h} and include: +\begin{itemize} +\item \textbf{trapIllegalValue:} Used for capturing failed parameter validation, for example. +\item \textbf{trapIllegalValueIf:} Used to trap an illegal value if a condition is met. +\item \textbf{trapNotImplemented:} Used to report and abort an unimplemented capability. +\item \textbf{trapOutOfBounds:} Used to trap an out-of-bounds condition on an index. +\item \textbf{trapOutOfBoundsIf:} Used to trap an out-of-bounds condition for a specific value. +\item \textbf{trapOutOfMemory:} Used to signal that no more memory can be allocated. +\item \textbf{trapUnexpectedState:} Used to signal that an unexpected or inconsistent state was encountered. +\item \textbf{trapUnexpectedStateIf:} If the given condition is true, used to signal that an unexpected state was encountered. +\item \textbf{trapUnrecoverableState:} Used to report an unrecoverable state in program execution. +\end{itemize} + + + + +\subsection{Examples } + +\paragraph {assertNotNull example} +\paragraph {assertNotNull example} + +\begin{lstlisting} +#include <LongBow/assertions> +#include <unistd.h> +#include <string.h> + +void +function(char *pointer) +{ + assertNotNull(pointer, "The pointer cannot be NULL."); + + write(1, pointer, strlen(pointer)); +} + +int +main(int argc, char *argv[]) +{ + function(0); +} +\end{lstlisting} + + +In this case the assertNotNull will trigger and the program will immediately terminate with the following output: + +\begin{lstlisting} +Assert pointer.c:8 function() pointer != NULL The pointer cannot be NULL. +0 pointer 0x0000000107840d4c function + 188 +1 pointer 0x0000000107840dd1 main + 33 +2 libdyld.dylib 0x00007fff887595fd start + 1 + +\end{lstlisting} + +\paragraph {assertTrue example} + \paragraph {assertTrue example} + + \begin{lstlisting} + LONGBOW_TEST_CASE(Global, myTest) +{ + struct timeval timeval; + timeval.tv_sec = 0; + timeval.tv_usec = 1000; + + char *expected = "0.001000"; + char *actual = parcTime\_FormatTimeval(timeval); + assertTrue(strcmp(expected, actual) == 0, "Expected \%s, actual \%s", expected, actual); + parc_free(actual); +} + \end{lstlisting} + +\paragraph {Example using assertNull, assertNotNull, and assertTrue} + \paragraph {Example using assertNull, assertNotNull, and assertTrue} + + \begin{lstlisting} + static void +parcDeque_AssertInvariants(const PARCDeque *deque) +{ + assertNotNull(deque, "Parameter cannot be null."); + if (deque->head != NULL) { + assertTrue(deque->size != 0, "PARCDeque head is not-null, but size is zero."); + assertNotNull(deque->tail, "PARCDeque head is not-null, but tail is null."); + parcDequeNode_AssertInvariants(deque->head); + parcDequeNode_AssertInvariants(deque->tail); + } else { + assertNull(deque->tail, "PARCDeque head is null, but tail is not null."); + assertTrue(deque->size == 0, "PARCDeque head is null, but size is not zero."); + } +} + +\end{lstlisting} + +\paragraph {assertFalse example} +\paragraph {assertFalse example} + \begin{lstlisting} +RtaCommand * +rtaCommand_Read(int fd) +{ + ssize_t readlen; + uint32_t netbyteorder; + size_t len; + char *p; + RtaCommand *command; + + readlen = read(fd, &netbyteorder, 4); + assertFalse(readlen < 0, "socket read error: %s\n", strerror(errno)); + assertTrue(readlen == 4, "Partial read on command length"); + + len = ntohl(netbyteorder); + p = parc_malloc(len); + readlen = read(fd, p, len); + assertTrue(readlen == len, "Partial read on command"); + + command = rtaCommand_Parse(p); + parc_free(p); + return command; +} +\end{lstlisting} + + +\section{Unit testing} +Longbow provides an xUnit-style unit testing framework. The framework is a mechanism for organizing and running trees of test code. It is organized hierarchically into three components: a Test Runner, Test Fixtures, and Test Cases. + +A Test Runner file is associated 1:1 with a C source file, with the word "test\_" prepended on the C source file name. For example, the Test Runner file for parc\_Buffer.c would be test\_parc\_Buffer.c. This file contains all of the Test Fixtures and Test Cases needed to test the associated C source file. + + Each Test Runner will run a set of Test Fixtures. Test Fixtures are an organizational unit that allows you to group your Test Cases. The grouping may be done by functionality, by static vs non static functions, or by any other organizing principle that you choose. + + A Test Fixture runs a set of Test Cases each of which is responsible for testing some aspect of the C module. + +Tests are run in the order they are defined. The Test Runner will start with Test Fixture1 and all of its Test Cases, move on to Test Fixture2 and its Test Cases etc. Tests should be idempotent, however, and not assume any particular order or be dependent on each other. They should not leave state such that the next Test Case inherits that state. + +\subsection{Designing tests } +\textcolor{red}{Put something here} + +\subsection{Writing tests with the Test Runner module } +\subsubsection{Test Runners} +A Test Runner is the top-level executable unit in a test. It is responsible for establishing the necessary state for the set of tests it contains, executing the tests via Test Fixtures and Test Cases, and tearing down state when the tests have completed. + +A Test Runner requires the following header files: +\begin{itemize} +\item \textbf{LongBow/runtime.h} is the basic header file needed for assertions and testing. +\item \textbf{LongBow/unit-test.h} is the basic header file needed for testing. +\item \textbf{LongBow/compiling.h} is used when you have code that needs to work across multiple compilers - it contains the matrix of compiler and / you are using. +\end{itemize} + +\noindent The source code of a Test Runner has the following basic structure: + +\begin{lstlisting} +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(myRunner) +{ +} + +LONGBOW_TEST_RUNNER_SETUP(myRunner) +{ + // Code to set up required state + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myRunner) +{ + //Code to clean up state + return LONGBOW_STATUS_SUCCEEDED; +} + +\end{lstlisting} + + +Each of these functions has a local variable - {\tt LongBowRunner *testRunner} - which may be used to manipulate the clipboard (as an example). The Text Fixtures and Test Cases launched by the Test Runner will have access to this variable as well as their own local variable. Thus a Test Fixture will have access to the {\tt testRunner} that is passed to it as well as its own {\tt LongBowFixture *testFixture} and a Test Case will have access to {\tt testRunner, testFixture} and its own {\tt LongBowCase *testCase}. + +\subsubsection{Test Fixtures} + + +A Test Fixture is a subcomponent which has the same structure as a Test Runner. The following code adds Test Fixture to a Test Runner: + +\begin{lstlisting} +LONGBOW_TEST_RUNNER(myRunner) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} +\end{lstlisting} + + +Like the Test Runner, it is responsible for setting up and tearing down state needed by the Test Cases. + +\begin{lstlisting} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, myTest); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} +\end{lstlisting} + +\subsubsection{Test Cases} +Test Cases are the leaf nodes of the testing tree. Each Test Case tests one aspect of the C module. + +\paragraph {Handling Test Case state safely} + +Every Test Case has access to a private \"clipboard\" that contains data shared between the Test Case and the set up and teardown functions of its encapsulating Test Fixture. This shared state is used to provide specific environment or initialized variables for the test and for the test to communicate specialized information to the teardown function. + +For example, a Test Case which is expected to fail as the result of testing a failure condition might exit without releasing resources which are left in an unsafe state. As multiple tests may be run in one process, it is important to clean these up before launching the next test. + +The following example demonstrates the clipboard mechanism: +\begin{itemize} +\item{The Test Fixture setup function allocates the necessary resources and puts references to them into the clipboard.} +\item{The Test Case gets these references, uses them, and fails.} +\item{The Test Fixture tear-down function obtains the resources from the clipboard and deallocates them.} +\end{itemize} + +\subsubsection {Test Runner Example} +\noindent The following is an example of a test file : + +\begin{lstlisting} +#include <stdio.h> +#include <string.h> + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(testClipboard) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, testClipboard); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + char *testData = strdup("Hello World"); + longBowTest Case_SetClipBoardData(testCase, testData, free); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, testClipboard) +{ + char *testData = longBowTest Case_GetClipBoardData(testCase); + printf("Shared state '%s'\n", testData); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(testClipboard); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTest Runner_Destroy(&testRunner); + exit(exitStatus); +} +\end{lstlisting} + +\subsubsection {Testing for Successful Failure} +Testing for success is straightforward but we also may have to test that something fails when it is supposed to. +This section describes how to test for an expected non-success result. + +To compose a Test Case that expects a result other than success, use the {\tt LONGBOW\_TEST\_CASE\_EXPECTS} function which takes the expected event as a parameter and completes. The example below shows the capture of a successful segmentation fault. + + +\begin{lstlisting} +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> + +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(LongBow) +{ + LONGBOW_RUN_TEST_FIXTURE(MyFixture); +} + +LONGBOW_TEST_RUNNER_SETUP(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(MyFixture) +{ + LONGBOW_RUN_TEST_CASE(MyFixture, alwaysSEGV); +} + +LONGBOW_TEST_FIXTURE_SETUP(MyFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(MyFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE_EXPECTS(MyFixture, alwaysSEGV, .event = &LongBowEventSIGSEGV) +{ + int *p = 0; + int i = *p; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(LongBow); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner, NULL); + longBowTest Runner_Destroy(&testRunner); + + exit(status); +} + +\end{lstlisting} + +\subsection{Running tests} + +The overall process for writing and running your tests: +\begin{itemize} +\item Write a Test Runner file for every .c file that completely tests all of the code container in the .c file. This filename should be "test\_" prepended to the name of the file you are testing. +\item Compile the Test Runner file with one of: +\begin {itemize} +\item -llongbow -llongbow-ansiterm +\item -llongbow -llongbow-textplain +\end{itemize} +\item Execute the Test Runner. +\end{itemize} + + +\subsection{Examples } + +Here is an example of a C source file and its associated Test file. Tutorial.c is a small C program which simply provides an uninteresting but useful exemplar of the test framework. + + +\noindent \textbf{Tutorial.c} + +\begin{lstlisting} +#include <unistd.h> +#include <stdbool.h> +#include <signal.h> + +static bool +_privateFunction() +{ + return true; +} + +bool +alwaysSucceed() +{ + return _privateFunction(); +} + +bool +alwaysFail() +{ + return false; +} + +bool +blowUp() +{ + char *p = 0; + *p = 0; + + return true; +} + +\end{lstlisting} + +The following code is the test file for the Tutorial.c. Note that the file name is simply the C source file name with "test\_" prepended. In this example, the Test Runner divides the Test Cases into two Test Fixtures: one to focus on the Static functions and one to focus on the Global functions. + +\noindent \textbf{test\_Tutorial.c} +\begin{lstlisting} + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Static); + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); + LONGBOW_RUN_TEST_CASE(Global, blowUp); + +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + bool result = alwaysFail(); + + assertTrue(result, "This test will fail."); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, blowUp, .event = &LongBowEventSIGSEGV) +{ + blowUp(); + + assertTrue(false, "This will not be executed"); +} + + +LONGBOW_TEST_FIXTURE(Static) +{ + LONGBOW_RUN_TEST_CASE(Static, _privateFunction); +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Static, _privateFunction) +{ + bool result = _privateFunction(); + + assertTrue(result, "This test must always succeed."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTest Runner_Destroy(&testRunner); + exit(status); +} + +\end{lstlisting} + +\section {Compiling and Compiler Support} +LongBow consolidates a variety of compile-time options that you include in your code. + +For example, the C99 standard defines the pragma operator and various compilers support this in various ways. + +\section{The LongBow Reporter} +The Longbow reporter offers a more user-friendly option for viewing the output of the running tests. In addition to linking with the primary LongBow library ({\tt liblongbow.a}), you also need to link with one of the following reporting libraries to control presentation of the test output. +\begin{itemize} +\item {\bf liblongbow-ansiterm.a} This option produces output that is color coded to indicate the degree of success: green for a successful test; yellow for warnings; and red for failure. +\item {\bf liblongbow-plaintext.a} This option produces plain text output. +\item {\bf liblongbow-json.a} This option is in development and will produce output in JSON format. +\end{itemize} + + + +\section {Appendices} +\subsection {Function Documentation} +The following modules are included in LongBow: +\begin {itemize} +\item \textbf{Runtime:} LongBow functions and macros for runtime. +\item \textbf{Testing:} LongBow functions and macros for writing tests. +\item \textbf{Internals:} LongBow functions and macros used internally. +\item \textbf{Reporting:} LongBow functions and definitions for writing report libraries. +\item \textbf{Performance testing:} LongBow functions and definitions for writing performance tests. +\end{itemize} + +\paragraph {Runtime} +LongBow runtime support consists primarily of assertions and traps. Developers insert assertions to insist that certain conditions are true before permitting the program to continue. If the assertion fails, the program is abnormally terminated. It uses the following files: + +\begin{itemize} +\item {\bf assertions.h:} Runtime and Test Assertions. + \item {\bf longBow\_EventType.h:} LongBow Events and Support. + \item {\bf longBow\_Runtime.h:} The LongBow Runtime support. + \item {\bf runtime.h:} LongBow Runtime Support. + \item {\bf traps.h:} Runtime and Test Traps. +\end{itemize} + + +\paragraph {Testing} +LongBow testing support consists of macros and ancillary functions to implement an xUnit style of writing and running tests. Test writers create a LONGBOW\_TEST\_RUNNER function which invokes one or more LONGBOW\_TEST\_FIXTURE functions, each of which invoke a specific LONGBOW\_TEST\_CASE. It uses the following files: + +\begin{itemize} +\item {\bf longBow\_EventType.h:} LongBow Events and Support. + \item {\bf longBow\_Main.h:} A main() function to run one or more LongBow Test Runners. + \item {\bf longBow\_OpenFile.h:} LongBow support for files and file descriptors. + \item {\bf longBow\_Runner.h:} LongBow Test Runner Support. + \item {\bf longBow\_Status.h} A simple status representation for a LongBow Test Case. + \item {\bf longBow\_Test CaseClipBoard.h:} LongBow Clipboard shared between the setup, test case, and teardown. + \item {\bf longBow\_UnitTesting.h} Unit Testing Support. . + \item {\bf testing.h:} LongBow testing functionality. + \item {\bf unit-test.h} LongBow Unit Test Support. +\end{itemize} + +\paragraph {Internals} +LongBow functions and macros used internally. +It uses the following files: + +\begin{itemize} + \item {\bf longBow\_ArrayList.h} A simple, list implementation using a dynamic array. + \item {\bf longBow\_Backtrace.h} Support for Stack Traces. + \item {\bf longBow\_Configuration.h} Support for LongBow Configuration. + \item {\bf longBow\_Debugging.h} Support for LongBow and Application Debugging. + \item {\bf longBow\_Event.h} LongBow Event Support. + \item {\bf longBow\_EventType.h} LongBow Events and Support. + \item {\bf longBow\_Fixture.h} Manage the execution of Test Cases. + \item {\bf longBow\_Location.h} LongBow Source File Location. + \item {\bf longBow\_Test Case.h} The interface and supporting functionality of a LongBow Test Case. + \item {\bf longBow\_Test CaseResult.h} LongBow Test Case Results. +\end{itemize} + + + \paragraph {Reporting} +LongBow functions and definitions for writing report libraries. +It uses the following header files: + +\begin{itemize} + \item {\bf longBow\_ReportANSITerminal\_Runtime.h} ANSI Terminal Reporting. +\item {\bf longBow\_Report\_Runtime.h} The LongBow Runtime Report Generator. +\item {\bf longBow\_Report\_Testing.h} The LongBow Test Report Generator. +\end{itemize} + + + \paragraph {Performance Testing} +Using LongBow for performance tests. + + +\end{document}
\ No newline at end of file diff --git a/longbow/documentation/LaTeX Documentation/old/SelfArx2.cls b/longbow/documentation/LaTeX Documentation/old/SelfArx2.cls new file mode 100755 index 00000000..704a5e6e --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/old/SelfArx2.cls @@ -0,0 +1,191 @@ +% --------------------------------------------------------------------- +% Conference proceedings and article templates for +% personal open-archiving activities +% September 2012 +% +% 4/16/14 Marc Mosko - changed \arabic{section} to just {\thesection} so appendix prints as "A", etc. +% 4/16/14 Marc Mosko - Changes how package xcolor is loaded so it has the "table" option +% +% --------------------------------------------------------------------- + +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{SelfArx}[25/01/2012, v1.0] +\RequirePackage{ifthen} +\RequirePackage{calc} +\AtEndOfClass{\RequirePackage{microtype}} +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\ProcessOptions* +\LoadClass{article} + +\RequirePackage{times} % Loads the Times-Roman Fonts +\RequirePackage{mathptmx} % Loads the Times-Roman Math Fonts +\RequirePackage{ifpdf} % Needed to pick between latex and pdflatex + +% --------------------------------------------------------------------- +\RequirePackage[utf8]{inputenc} +\RequirePackage{amsmath,amsfonts,amssymb} +\RequirePackage{graphicx} +\RequirePackage[table]{xcolor} +\RequirePackage[english]{babel} +\RequirePackage{booktabs} +% --------------------------------------------------------------------- + +%%%%% for abstract+authors frames + + +% --------------------------------------------------------------------- +% margins +\RequirePackage[left=2cm,% + right=2cm,% + top=2.25cm,% + bottom=2.25cm,% + headheight=11pt,% + letterpaper]{geometry}% +\RequirePackage[labelfont={bf,sf},% + labelsep=period,% + justification=raggedright]{caption} +% --------------------------------------------------------------------- +\RequirePackage{fancyhdr} % Needed to define custom headers/footers +\RequirePackage{lastpage} % Number of pages in the document +\pagestyle{fancy} % Enables the custom headers/footers +% Headers +\lhead{}% +\chead{}% +\rhead{\small\sffamily\bfseries\@PaperTitle\ --- \thepage/\pageref{LastPage}} +% Footers +\lfoot{}% +\cfoot{}% +\rfoot{}% +\renewcommand{\headrulewidth}{0pt}% % No header rule +\renewcommand{\footrulewidth}{0pt}% % No footer rule +% --------------------------------------------------------------------- +% section/subsection/paragraph set-up +\RequirePackage[explicit]{titlesec} +\titleformat{\section} + {\color{color1}\large\sffamily\bfseries} + {} + {0em} + {\colorbox{color2!10}{\parbox{\dimexpr\linewidth-2\fboxsep\relax}{\centering{\thesection}. #1}}} + [] +\titleformat{name=\section,numberless} + {\color{color1}\large\sffamily\bfseries} + {} + {0em} + {\colorbox{color2!10}{\parbox{\dimexpr\linewidth-2\fboxsep\relax}{\centering#1}}} + [] +\titleformat{\subsection} + {\color{color1}\sffamily\bfseries} + {\thesubsection} + {0.5em} + {#1} + [] +\titleformat{\subsubsection} + {\sffamily\small\bfseries} + {\thesubsubsection} + {0.5em} + {#1} + [] +\titleformat{\paragraph}[runin] + {\sffamily\small\bfseries} + {} + {0em} + {#1} +\titlespacing*{\section}{0pc}{3ex \@plus4pt \@minus3pt}{5pt} +\titlespacing*{\subsection}{0pc}{2.5ex \@plus3pt \@minus2pt}{0pt} +\titlespacing*{\subsubsection}{0pc}{2ex \@plus2.5pt \@minus1.5pt}{0pt} +\titlespacing*{\paragraph}{0pc}{1.5ex \@plus2pt \@minus1pt}{10pt} +% --------------------------------------------------------------------- +% tableofcontents set-up +\usepackage{titletoc} +\contentsmargin{0cm} +\titlecontents{section}[\tocsep] + {\addvspace{4pt}\small\bfseries\sffamily} + {\contentslabel[\thecontentslabel]{\tocsep}} + {} + {\hfill\thecontentspage} + [] +\titlecontents{subsection}[\tocsep] + {\addvspace{2pt}\small\sffamily} + {\contentslabel[\thecontentslabel]{\tocsep}} + {} + {\ \titlerule*[.5pc]{.}\ \thecontentspage} + [] +\titlecontents*{subsubsection}[\tocsep] + {\footnotesize\sffamily} + {} + {} + {} + [\ \textbullet\ ] +% --------------------------------------------------------------------- +% Get the multiple author set +\newcount\@authcnt +\newcount\@tmpcnt\@tmpcnt\z@ + +\def\@affiliation{% + \ifnum\@tmpcnt<\@authcnt + \global\advance\@tmpcnt1 + \raggedright \csname @auth\romannumeral\the\@tmpcnt\endcsname\hfill\\% + \let\next\@affiliation \vskip1pt + \else + \let\next\relax + \fi +\next} + +\newcommand{\affiliation}[1]{% + \global\advance\@authcnt1 + \expandafter\gdef\csname @auth\romannumeral\the\@authcnt\endcsname + {#1}} +% --------------------------------------------------------------------- +\RequirePackage{enumitem} +%\setlist{nolistsep} % Uncomment to remove spacing between items in lists (enumerate, itemize) +% --------------------------------------------------------------------- +% Remove brackets from numbering in List of References +\renewcommand{\@biblabel}[1]{\bfseries\color{color1}\textsuperscript{[#1]}} +%\setlength{\bibitemsep}{0cm} +% --------------------------------------------------------------------- +\newcommand{\PaperTitle}[1]{\def\@PaperTitle{#1}} +\newcommand{\Archive}[1]{\def\@Archive{#1}} +\newcommand{\Authors}[1]{\def\@Authors{#1}} +\newcommand{\JournalInfo}[1]{\def\@JournalInfo{#1}} +\newcommand{\Abstract}[1]{\def\@Abstract{#1}} +\newcommand{\Keywords}[1]{\def\@Keywords{#1}} +% --------------------------------------------------------------------- +\renewcommand{\@maketitle}{% +\twocolumn[{% +\thispagestyle{empty}% +\vskip-36pt% +{\raggedleft\small\sffamily\bfseries\@JournalInfo\\\@Archive\par}% +\vskip20pt% +{\raggedright\color{color1}\sffamily\bfseries\fontsize{20}{25}\selectfont \@PaperTitle\par}% +\vskip10pt +{\raggedright\color{color1}\sffamily\fontsize{12}{16}\selectfont \@Authors\par} +\vskip18pt% +\fcolorbox{color1}{white}{% +\parbox{\textwidth-2\fboxsep-2\fboxrule}{\centering% +\colorbox{color2!10}{% +\parbox{\textwidth-3.5\fboxsep-3.5\fboxrule}{% +\ifx\@Keywords\@empty +\sffamily\small\textbf{\abstractname}\\\@Abstract +\else +\sffamily\small\textbf{\abstractname}\\\@Abstract\\[5pt]% +\textbf{\keywordname}\\\@Keywords% +\fi +}% +}% +\vskip5pt% +\begingroup% +\raggedright\sffamily\small% +\footnotesize\@affiliation\par% +\endgroup%% +}% +}% +\vskip25pt% +}]% +}% +% --------------------------------------------------------------------- +\let\oldbibliography\thebibliography +\renewcommand{\thebibliography}[1]{% +\addcontentsline{toc}{section}{\hspace*{-\tocsep}\refname}% +\oldbibliography{#1}% +\setlength\itemsep{0pt}% +}
\ No newline at end of file diff --git a/longbow/documentation/LaTeX Documentation/parc_black_solid.png b/longbow/documentation/LaTeX Documentation/parc_black_solid.png Binary files differnew file mode 100644 index 00000000..6abcf2f4 --- /dev/null +++ b/longbow/documentation/LaTeX Documentation/parc_black_solid.png diff --git a/longbow/documentation/LongBow.pages/Index.zip b/longbow/documentation/LongBow.pages/Index.zip Binary files differnew file mode 100644 index 00000000..71366536 --- /dev/null +++ b/longbow/documentation/LongBow.pages/Index.zip diff --git a/longbow/documentation/LongBow.pages/Metadata/BuildVersionHistory.plist b/longbow/documentation/LongBow.pages/Metadata/BuildVersionHistory.plist new file mode 100644 index 00000000..e4466590 --- /dev/null +++ b/longbow/documentation/LongBow.pages/Metadata/BuildVersionHistory.plist @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<array> + <string>pages-trunk-20080703_5</string> + <string>pages-trunk-20080707_3</string> + <string>pages-trunk-20080904_1</string> + <string>local build-Nov 15 2011</string> + <string>local build-Oct 16 2012</string> + <string>local build-Nov 15 2011</string> + <string>local build-Oct 16 2012</string> + <string>M5.0-1465-1</string> +</array> +</plist> diff --git a/longbow/documentation/LongBow.pages/Metadata/DocumentIdentifier b/longbow/documentation/LongBow.pages/Metadata/DocumentIdentifier new file mode 100644 index 00000000..e1ab6f9d --- /dev/null +++ b/longbow/documentation/LongBow.pages/Metadata/DocumentIdentifier @@ -0,0 +1 @@ +9F57C025-E7BF-4979-A02B-BE3E828928DC
\ No newline at end of file diff --git a/longbow/documentation/LongBow.pages/Metadata/Properties.plist b/longbow/documentation/LongBow.pages/Metadata/Properties.plist Binary files differnew file mode 100644 index 00000000..8587d44e --- /dev/null +++ b/longbow/documentation/LongBow.pages/Metadata/Properties.plist diff --git a/longbow/documentation/LongBow.pages/preview-micro.jpg b/longbow/documentation/LongBow.pages/preview-micro.jpg Binary files differnew file mode 100644 index 00000000..51318b08 --- /dev/null +++ b/longbow/documentation/LongBow.pages/preview-micro.jpg diff --git a/longbow/documentation/LongBow.pages/preview-web.jpg b/longbow/documentation/LongBow.pages/preview-web.jpg Binary files differnew file mode 100644 index 00000000..3e0f39da --- /dev/null +++ b/longbow/documentation/LongBow.pages/preview-web.jpg diff --git a/longbow/documentation/LongBow.pages/preview.jpg b/longbow/documentation/LongBow.pages/preview.jpg Binary files differnew file mode 100644 index 00000000..54d8ec23 --- /dev/null +++ b/longbow/documentation/LongBow.pages/preview.jpg diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css new file mode 100644 index 00000000..c4cadf15 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css @@ -0,0 +1,470 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-default .badge, +.btn-primary .badge, +.btn-success .badge, +.btn-info .badge, +.btn-warning .badge, +.btn-danger .badge { + text-shadow: none; +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default:disabled, +.btn-default[disabled] { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); + background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #245580; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #265a88; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #265a88; + border-color: #245580; +} +.btn-primary:disabled, +.btn-primary[disabled] { + background-color: #265a88; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success:disabled, +.btn-success[disabled] { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info:disabled, +.btn-info[disabled] { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning:disabled, +.btn-warning[disabled] { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger:disabled, +.btn-danger[disabled] { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #2e6da4; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); + background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); + background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +@media (max-width: 767px) { + .navbar .navbar-nav .open .dropdown-menu > .active > a, + .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; + } +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); + background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #286090; + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); + background-repeat: repeat-x; + border-color: #2b669a; +} +.list-group-item.active .badge, +.list-group-item.active:hover .badge, +.list-group-item.active:focus .badge { + text-shadow: none; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); + background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css.map b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css.map new file mode 100644 index 00000000..016a8dab --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"AAcA;;;;;;EAME,0CAAA;ECgDA,6FAAA;EACQ,qFAAA;EC5DT;AFgBC;;;;;;;;;;;;EC2CA,0DAAA;EACQ,kDAAA;EC7CT;AFVD;;;;;;EAiBI,mBAAA;EECH;AFgCC;;EAEE,wBAAA;EE9BH;AFmCD;EGlDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EA+B2C,2BAAA;EAA2B,oBAAA;EExBvE;AFLC;;EAEE,2BAAA;EACA,8BAAA;EEOH;AFJC;;EAEE,2BAAA;EACA,uBAAA;EEMH;AFHC;;EAEE,2BAAA;EACA,wBAAA;EEKH;AFUD;EGnDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+BD;AF7BC;;EAEE,2BAAA;EACA,8BAAA;EE+BH;AF5BC;;EAEE,2BAAA;EACA,uBAAA;EE8BH;AF3BC;;EAEE,2BAAA;EACA,wBAAA;EE6BH;AFbD;EGpDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEuDD;AFrDC;;EAEE,2BAAA;EACA,8BAAA;EEuDH;AFpDC;;EAEE,2BAAA;EACA,uBAAA;EEsDH;AFnDC;;EAEE,2BAAA;EACA,wBAAA;EEqDH;AFpCD;EGrDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+ED;AF7EC;;EAEE,2BAAA;EACA,8BAAA;EE+EH;AF5EC;;EAEE,2BAAA;EACA,uBAAA;EE8EH;AF3EC;;EAEE,2BAAA;EACA,wBAAA;EE6EH;AF3DD;EGtDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EEuGD;AFrGC;;EAEE,2BAAA;EACA,8BAAA;EEuGH;AFpGC;;EAEE,2BAAA;EACA,uBAAA;EEsGH;AFnGC;;EAEE,2BAAA;EACA,wBAAA;EEqGH;AFlFD;EGvDI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EAEA,wHAAA;ECnBF,qEAAA;EJiCA,6BAAA;EACA,uBAAA;EE+HD;AF7HC;;EAEE,2BAAA;EACA,8BAAA;EE+HH;AF5HC;;EAEE,2BAAA;EACA,uBAAA;EE8HH;AF3HC;;EAEE,2BAAA;EACA,wBAAA;EE6HH;AFnGD;;ECfE,oDAAA;EACQ,4CAAA;ECsHT;AF9FD;;EGxEI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHuEF,2BAAA;EEoGD;AFlGD;;;EG7EI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH6EF,2BAAA;EEwGD;AF/FD;EG1FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EJ4GA,oBAAA;EC9CA,6FAAA;EACQ,qFAAA;ECoJT;AF1GD;;EG1FI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,0DAAA;EACQ,kDAAA;EC8JT;AFvGD;;EAEE,gDAAA;EEyGD;AFrGD;EG7GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ECnBF,qEAAA;EFyOD;AF7GD;;EG7GI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EF2CF,yDAAA;EACQ,iDAAA;ECoLT;AFvHD;;EAYI,2CAAA;EE+GH;AF1GD;;;EAGE,kBAAA;EE4GD;AF5FD;EAVI;;;IAGE,aAAA;IG1IF,0EAAA;IACA,qEAAA;IACA,+FAAA;IAAA,wEAAA;IACA,6BAAA;IACA,wHAAA;IDoPD;EACF;AFnGD;EACE,+CAAA;ECxGA,4FAAA;EACQ,oFAAA;EC8MT;AF3FD;EGnKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EEuGD;AFlGD;EGpKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EE+GD;AFzGD;EGrKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EEuHD;AFhHD;EGtKI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH2JF,uBAAA;EE+HD;AFhHD;EG9KI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDiSH;AF7GD;EGxLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDwSH;AFnHD;EGzLI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED+SH;AFzHD;EG1LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDsTH;AF/HD;EG3LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED6TH;AFrID;EG5LI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDoUH;AFxID;EG/JI,+MAAA;EACA,0MAAA;EACA,uMAAA;ED0SH;AFpID;EACE,oBAAA;EC3JA,oDAAA;EACQ,4CAAA;ECkST;AFrID;;;EAGE,+BAAA;EGhNE,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EH8MF,uBAAA;EE2ID;AFhJD;;;EAQI,mBAAA;EE6IH;AFnID;EChLE,mDAAA;EACQ,2CAAA;ECsTT;AF7HD;EGzOI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDyWH;AFnID;EG1OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDgXH;AFzID;EG3OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDuXH;AF/ID;EG5OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED8XH;AFrJD;EG7OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EDqYH;AF3JD;EG9OI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;ED4YH;AF3JD;EGrPI,0EAAA;EACA,qEAAA;EACA,+FAAA;EAAA,wEAAA;EACA,6BAAA;EACA,wHAAA;EHmPF,uBAAA;ECxMA,2FAAA;EACQ,mFAAA;EC0WT","file":"bootstrap-theme.css","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n .badge {\n text-shadow: none;\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-link-active-bg, 5%); @end-color: darken(@navbar-default-link-active-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n .navbar-nav > .open > a,\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-link-active-bg; @end-color: lighten(@navbar-inverse-link-active-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n// Fix active state of dropdown items in collapsed mode\n@media (max-width: @grid-float-breakpoint-max) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: #fff;\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n }\n }\n}\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n\n .badge {\n text-shadow: none;\n }\n}\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",".btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-default .badge,\n.btn-primary .badge,\n.btn-success .badge,\n.btn-info .badge,\n.btn-warning .badge,\n.btn-danger .badge {\n text-shadow: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n}\n.btn-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #dbdbdb;\n text-shadow: 0 1px 0 #fff;\n border-color: #ccc;\n}\n.btn-default:hover,\n.btn-default:focus {\n background-color: #e0e0e0;\n background-position: 0 -15px;\n}\n.btn-default:active,\n.btn-default.active {\n background-color: #e0e0e0;\n border-color: #dbdbdb;\n}\n.btn-default:disabled,\n.btn-default[disabled] {\n background-color: #e0e0e0;\n background-image: none;\n}\n.btn-primary {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #245580;\n}\n.btn-primary:hover,\n.btn-primary:focus {\n background-color: #265a88;\n background-position: 0 -15px;\n}\n.btn-primary:active,\n.btn-primary.active {\n background-color: #265a88;\n border-color: #245580;\n}\n.btn-primary:disabled,\n.btn-primary[disabled] {\n background-color: #265a88;\n background-image: none;\n}\n.btn-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #3e8f3e;\n}\n.btn-success:hover,\n.btn-success:focus {\n background-color: #419641;\n background-position: 0 -15px;\n}\n.btn-success:active,\n.btn-success.active {\n background-color: #419641;\n border-color: #3e8f3e;\n}\n.btn-success:disabled,\n.btn-success[disabled] {\n background-color: #419641;\n background-image: none;\n}\n.btn-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #28a4c9;\n}\n.btn-info:hover,\n.btn-info:focus {\n background-color: #2aabd2;\n background-position: 0 -15px;\n}\n.btn-info:active,\n.btn-info.active {\n background-color: #2aabd2;\n border-color: #28a4c9;\n}\n.btn-info:disabled,\n.btn-info[disabled] {\n background-color: #2aabd2;\n background-image: none;\n}\n.btn-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #e38d13;\n}\n.btn-warning:hover,\n.btn-warning:focus {\n background-color: #eb9316;\n background-position: 0 -15px;\n}\n.btn-warning:active,\n.btn-warning.active {\n background-color: #eb9316;\n border-color: #e38d13;\n}\n.btn-warning:disabled,\n.btn-warning[disabled] {\n background-color: #eb9316;\n background-image: none;\n}\n.btn-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n background-repeat: repeat-x;\n border-color: #b92c28;\n}\n.btn-danger:hover,\n.btn-danger:focus {\n background-color: #c12e2a;\n background-position: 0 -15px;\n}\n.btn-danger:active,\n.btn-danger.active {\n background-color: #c12e2a;\n border-color: #b92c28;\n}\n.btn-danger:disabled,\n.btn-danger[disabled] {\n background-color: #c12e2a;\n background-image: none;\n}\n.thumbnail,\n.img-thumbnail {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n background-color: #e8e8e8;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n background-color: #2e6da4;\n}\n.navbar-default {\n background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);\n background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n.navbar-inverse {\n background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: -o-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .active > a {\n background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);\n background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);\n -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n@media (max-width: 767px) {\n .navbar .navbar-nav .open .dropdown-menu > .active > a,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n }\n}\n.alert {\n text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.alert-success {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n border-color: #b2dba1;\n}\n.alert-info {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n border-color: #9acfea;\n}\n.alert-warning {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n border-color: #f5e79e;\n}\n.alert-danger {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n border-color: #dca7a7;\n}\n.progress {\n background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n.progress-bar {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);\n}\n.progress-bar-success {\n background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n.progress-bar-info {\n background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n.progress-bar-warning {\n background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n.progress-bar-danger {\n background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n.progress-bar-striped {\n 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);\n 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);\n 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);\n}\n.list-group {\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 #286090;\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);\n border-color: #2b669a;\n}\n.list-group-item.active .badge,\n.list-group-item.active:hover .badge,\n.list-group-item.active:focus .badge {\n text-shadow: none;\n}\n.panel {\n -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n.panel-default > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n.panel-primary > .panel-heading {\n background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);\n background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);\n}\n.panel-success > .panel-heading {\n background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n.panel-info > .panel-heading {\n background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n.panel-warning > .panel-heading {\n background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n.panel-danger > .panel-heading {\n background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n.well {\n background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n border-color: #dcdcdc;\n -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n/*# sourceMappingURL=bootstrap-theme.css.map */","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]}
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.min.css b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.min.css new file mode 100644 index 00000000..4c3e7bad --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:hover,.btn-primary:focus{background-color:#265a88;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#265a88;border-color:#245580}.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:hover .badge,.list-group-item.active:focus .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css new file mode 100644 index 00000000..c6f3d210 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css @@ -0,0 +1,6332 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #337ab7; + text-decoration: none; +} +a:hover, +a:focus { + color: #23527c; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #337ab7; +} +a.text-primary:hover { + color: #286090; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #337ab7; +} +a.bg-primary:hover { + background-color: #286090; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .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; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #777; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + min-height: .01%; + overflow-x: auto; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #999; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #999; +} +.form-control::-webkit-input-placeholder { + color: #999; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: 34px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg { + line-height: 46px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 20px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm, +.form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm, +select.form-group-sm .form-control { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +textarea.form-group-sm .form-control, +select[multiple].input-sm, +select[multiple].form-group-sm .form-control { + height: auto; +} +.input-lg, +.form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-lg, +select.form-group-lg .form-control { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +textarea.form-group-lg .form-control, +select[multiple].input-lg, +select[multiple].form-group-lg .form-control { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label ~ .form-control-feedback { + top: 25px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.3px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default.focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary.focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #286090; + border-color: #204d74; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #337ab7; + border-color: #2e6da4; +} +.btn-primary .badge { + color: #337ab7; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success.focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info.focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning.focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger.focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #337ab7; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #23527c; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; + visibility: hidden; +} +.collapse.in { + display: block; + visibility: visible; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; + -webkit-transition-duration: .35s; + -o-transition-duration: .35s; + transition-duration: .35s; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #337ab7; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.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 { + content: ""; + border-top: 0; + border-bottom: 4px solid; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #337ab7; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #337ab7; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; + visibility: hidden; +} +.tab-content > .active { + display: block; + visibility: visible; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + visibility: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #9d9d9d; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a { + color: #9d9d9d; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #9d9d9d; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #9d9d9d; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #9d9d9d; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #337ab7; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #23527c; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #337ab7; + border-color: #337ab7; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.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: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #337ab7; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #286090; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #337ab7; + background-color: #fff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px 15px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron, +.container-fluid .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding: 48px 0; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border .2s ease-in-out; + -o-transition: border .2s ease-in-out; + transition: border .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #337ab7; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #337ab7; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + cursor: not-allowed; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #c7ddef; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-right: 15px; + padding-left: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #337ab7; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #337ab7; +} +.panel-primary > .panel-heading .badge { + color: #337ab7; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #337ab7; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: absolute; + top: 0; + right: 0; + left: 0; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.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; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: normal; + line-height: 1.4; + visibility: visible; + filter: alpha(opacity=0); + opacity: 0; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.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: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + right: 5px; + bottom: 0; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: left; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} +.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; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + 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, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-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 { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform .6s ease-in-out; + -o-transition: -o-transform .6s ease-in-out; + transition: transform .6s ease-in-out; + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000; + perspective: 1000; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + left: 0; + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + left: 0; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + left: 0; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css.map b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css.map new file mode 100644 index 00000000..a02f6ba0 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"AAAA,6DAA4D;ACQ5D;EACE,yBAAA;EACA,4BAAA;EACA,gCAAA;EDND;ACaD;EACE,WAAA;EDXD;ACwBD;;;;;;;;;;;;;EAaE,gBAAA;EDtBD;AC8BD;;;;EAIE,uBAAA;EACA,0BAAA;ED5BD;ACoCD;EACE,eAAA;EACA,WAAA;EDlCD;AC0CD;;EAEE,eAAA;EDxCD;ACkDD;EACE,+BAAA;EDhDD;ACuDD;;EAEE,YAAA;EDrDD;AC+DD;EACE,2BAAA;ED7DD;ACoED;;EAEE,mBAAA;EDlED;ACyED;EACE,oBAAA;EDvED;AC+ED;EACE,gBAAA;EACA,kBAAA;ED7ED;ACoFD;EACE,kBAAA;EACA,aAAA;EDlFD;ACyFD;EACE,gBAAA;EDvFD;AC8FD;;EAEE,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,0BAAA;ED5FD;AC+FD;EACE,aAAA;ED7FD;ACgGD;EACE,iBAAA;ED9FD;ACwGD;EACE,WAAA;EDtGD;AC6GD;EACE,kBAAA;ED3GD;ACqHD;EACE,kBAAA;EDnHD;AC0HD;EACE,8BAAA;EACA,iCAAA;UAAA,yBAAA;EACA,WAAA;EDxHD;AC+HD;EACE,gBAAA;ED7HD;ACoID;;;;EAIE,mCAAA;EACA,gBAAA;EDlID;ACoJD;;;;;EAKE,gBAAA;EACA,eAAA;EACA,WAAA;EDlJD;ACyJD;EACE,mBAAA;EDvJD;ACiKD;;EAEE,sBAAA;ED/JD;AC0KD;;;;EAIE,4BAAA;EACA,iBAAA;EDxKD;AC+KD;;EAEE,iBAAA;ED7KD;ACoLD;;EAEE,WAAA;EACA,YAAA;EDlLD;AC0LD;EACE,qBAAA;EDxLD;ACmMD;;EAEE,gCAAA;KAAA,6BAAA;UAAA,wBAAA;EACA,YAAA;EDjMD;AC0MD;;EAEE,cAAA;EDxMD;ACiND;EACE,+BAAA;EACA,8BAAA;EACA,iCAAA;EACA,yBAAA;ED/MD;ACwND;;EAEE,0BAAA;EDtND;AC6ND;EACE,2BAAA;EACA,eAAA;EACA,gCAAA;ED3ND;ACmOD;EACE,WAAA;EACA,YAAA;EDjOD;ACwOD;EACE,gBAAA;EDtOD;AC8OD;EACE,mBAAA;ED5OD;ACsPD;EACE,2BAAA;EACA,mBAAA;EDpPD;ACuPD;;EAEE,YAAA;EDrPD;AACD,sFAAqF;AE1ErF;EAnGI;;;IAGI,oCAAA;IACA,wBAAA;IACA,qCAAA;YAAA,6BAAA;IACA,8BAAA;IFgLL;EE7KC;;IAEI,4BAAA;IF+KL;EE5KC;IACI,8BAAA;IF8KL;EE3KC;IACI,+BAAA;IF6KL;EExKC;;IAEI,aAAA;IF0KL;EEvKC;;IAEI,wBAAA;IACA,0BAAA;IFyKL;EEtKC;IACI,6BAAA;IFwKL;EErKC;;IAEI,0BAAA;IFuKL;EEpKC;IACI,4BAAA;IFsKL;EEnKC;;;IAGI,YAAA;IACA,WAAA;IFqKL;EElKC;;IAEI,yBAAA;IFoKL;EE7JC;IACI,6BAAA;IF+JL;EE3JC;IACI,eAAA;IF6JL;EE3JC;;IAGQ,mCAAA;IF4JT;EEzJC;IACI,wBAAA;IF2JL;EExJC;IACI,sCAAA;IF0JL;EE3JC;;IAKQ,mCAAA;IF0JT;EEvJC;;IAGQ,mCAAA;IFwJT;EACF;AGpPD;EACE,qCAAA;EACA,uDAAA;EACA,6TAAA;EHsPD;AG/OD;EACE,oBAAA;EACA,UAAA;EACA,uBAAA;EACA,qCAAA;EACA,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,qCAAA;EACA,oCAAA;EHiPD;AG7OmC;EAAW,gBAAA;EHgP9C;AG/OmC;EAAW,gBAAA;EHkP9C;AGhPmC;;EAAW,kBAAA;EHoP9C;AGnPmC;EAAW,kBAAA;EHsP9C;AGrPmC;EAAW,kBAAA;EHwP9C;AGvPmC;EAAW,kBAAA;EH0P9C;AGzPmC;EAAW,kBAAA;EH4P9C;AG3PmC;EAAW,kBAAA;EH8P9C;AG7PmC;EAAW,kBAAA;EHgQ9C;AG/PmC;EAAW,kBAAA;EHkQ9C;AGjQmC;EAAW,kBAAA;EHoQ9C;AGnQmC;EAAW,kBAAA;EHsQ9C;AGrQmC;EAAW,kBAAA;EHwQ9C;AGvQmC;EAAW,kBAAA;EH0Q9C;AGzQmC;EAAW,kBAAA;EH4Q9C;AG3QmC;EAAW,kBAAA;EH8Q9C;AG7QmC;EAAW,kBAAA;EHgR9C;AG/QmC;EAAW,kBAAA;EHkR9C;AGjRmC;EAAW,kBAAA;EHoR9C;AGnRmC;EAAW,kBAAA;EHsR9C;AGrRmC;EAAW,kBAAA;EHwR9C;AGvRmC;EAAW,kBAAA;EH0R9C;AGzRmC;EAAW,kBAAA;EH4R9C;AG3RmC;EAAW,kBAAA;EH8R9C;AG7RmC;EAAW,kBAAA;EHgS9C;AG/RmC;EAAW,kBAAA;EHkS9C;AGjSmC;EAAW,kBAAA;EHoS9C;AGnSmC;EAAW,kBAAA;EHsS9C;AGrSmC;EAAW,kBAAA;EHwS9C;AGvSmC;EAAW,kBAAA;EH0S9C;AGzSmC;EAAW,kBAAA;EH4S9C;AG3SmC;EAAW,kBAAA;EH8S9C;AG7SmC;EAAW,kBAAA;EHgT9C;AG/SmC;EAAW,kBAAA;EHkT9C;AGjTmC;EAAW,kBAAA;EHoT9C;AGnTmC;EAAW,kBAAA;EHsT9C;AGrTmC;EAAW,kBAAA;EHwT9C;AGvTmC;EAAW,kBAAA;EH0T9C;AGzTmC;EAAW,kBAAA;EH4T9C;AG3TmC;EAAW,kBAAA;EH8T9C;AG7TmC;EAAW,kBAAA;EHgU9C;AG/TmC;EAAW,kBAAA;EHkU9C;AGjUmC;EAAW,kBAAA;EHoU9C;AGnUmC;EAAW,kBAAA;EHsU9C;AGrUmC;EAAW,kBAAA;EHwU9C;AGvUmC;EAAW,kBAAA;EH0U9C;AGzUmC;EAAW,kBAAA;EH4U9C;AG3UmC;EAAW,kBAAA;EH8U9C;AG7UmC;EAAW,kBAAA;EHgV9C;AG/UmC;EAAW,kBAAA;EHkV9C;AGjVmC;EAAW,kBAAA;EHoV9C;AGnVmC;EAAW,kBAAA;EHsV9C;AGrVmC;EAAW,kBAAA;EHwV9C;AGvVmC;EAAW,kBAAA;EH0V9C;AGzVmC;EAAW,kBAAA;EH4V9C;AG3VmC;EAAW,kBAAA;EH8V9C;AG7VmC;EAAW,kBAAA;EHgW9C;AG/VmC;EAAW,kBAAA;EHkW9C;AGjWmC;EAAW,kBAAA;EHoW9C;AGnWmC;EAAW,kBAAA;EHsW9C;AGrWmC;EAAW,kBAAA;EHwW9C;AGvWmC;EAAW,kBAAA;EH0W9C;AGzWmC;EAAW,kBAAA;EH4W9C;AG3WmC;EAAW,kBAAA;EH8W9C;AG7WmC;EAAW,kBAAA;EHgX9C;AG/WmC;EAAW,kBAAA;EHkX9C;AGjXmC;EAAW,kBAAA;EHoX9C;AGnXmC;EAAW,kBAAA;EHsX9C;AGrXmC;EAAW,kBAAA;EHwX9C;AGvXmC;EAAW,kBAAA;EH0X9C;AGzXmC;EAAW,kBAAA;EH4X9C;AG3XmC;EAAW,kBAAA;EH8X9C;AG7XmC;EAAW,kBAAA;EHgY9C;AG/XmC;EAAW,kBAAA;EHkY9C;AGjYmC;EAAW,kBAAA;EHoY9C;AGnYmC;EAAW,kBAAA;EHsY9C;AGrYmC;EAAW,kBAAA;EHwY9C;AGvYmC;EAAW,kBAAA;EH0Y9C;AGzYmC;EAAW,kBAAA;EH4Y9C;AG3YmC;EAAW,kBAAA;EH8Y9C;AG7YmC;EAAW,kBAAA;EHgZ9C;AG/YmC;EAAW,kBAAA;EHkZ9C;AGjZmC;EAAW,kBAAA;EHoZ9C;AGnZmC;EAAW,kBAAA;EHsZ9C;AGrZmC;EAAW,kBAAA;EHwZ9C;AGvZmC;EAAW,kBAAA;EH0Z9C;AGzZmC;EAAW,kBAAA;EH4Z9C;AG3ZmC;EAAW,kBAAA;EH8Z9C;AG7ZmC;EAAW,kBAAA;EHga9C;AG/ZmC;EAAW,kBAAA;EHka9C;AGjamC;EAAW,kBAAA;EHoa9C;AGnamC;EAAW,kBAAA;EHsa9C;AGramC;EAAW,kBAAA;EHwa9C;AGvamC;EAAW,kBAAA;EH0a9C;AGzamC;EAAW,kBAAA;EH4a9C;AG3amC;EAAW,kBAAA;EH8a9C;AG7amC;EAAW,kBAAA;EHgb9C;AG/amC;EAAW,kBAAA;EHkb9C;AGjbmC;EAAW,kBAAA;EHob9C;AGnbmC;EAAW,kBAAA;EHsb9C;AGrbmC;EAAW,kBAAA;EHwb9C;AGvbmC;EAAW,kBAAA;EH0b9C;AGzbmC;EAAW,kBAAA;EH4b9C;AG3bmC;EAAW,kBAAA;EH8b9C;AG7bmC;EAAW,kBAAA;EHgc9C;AG/bmC;EAAW,kBAAA;EHkc9C;AGjcmC;EAAW,kBAAA;EHoc9C;AGncmC;EAAW,kBAAA;EHsc9C;AGrcmC;EAAW,kBAAA;EHwc9C;AGvcmC;EAAW,kBAAA;EH0c9C;AGzcmC;EAAW,kBAAA;EH4c9C;AG3cmC;EAAW,kBAAA;EH8c9C;AG7cmC;EAAW,kBAAA;EHgd9C;AG/cmC;EAAW,kBAAA;EHkd9C;AGjdmC;EAAW,kBAAA;EHod9C;AGndmC;EAAW,kBAAA;EHsd9C;AGrdmC;EAAW,kBAAA;EHwd9C;AGvdmC;EAAW,kBAAA;EH0d9C;AGzdmC;EAAW,kBAAA;EH4d9C;AG3dmC;EAAW,kBAAA;EH8d9C;AG7dmC;EAAW,kBAAA;EHge9C;AG/dmC;EAAW,kBAAA;EHke9C;AGjemC;EAAW,kBAAA;EHoe9C;AGnemC;EAAW,kBAAA;EHse9C;AGremC;EAAW,kBAAA;EHwe9C;AGvemC;EAAW,kBAAA;EH0e9C;AGzemC;EAAW,kBAAA;EH4e9C;AG3emC;EAAW,kBAAA;EH8e9C;AG7emC;EAAW,kBAAA;EHgf9C;AG/emC;EAAW,kBAAA;EHkf9C;AGjfmC;EAAW,kBAAA;EHof9C;AGnfmC;EAAW,kBAAA;EHsf9C;AGrfmC;EAAW,kBAAA;EHwf9C;AGvfmC;EAAW,kBAAA;EH0f9C;AGzfmC;EAAW,kBAAA;EH4f9C;AG3fmC;EAAW,kBAAA;EH8f9C;AG7fmC;EAAW,kBAAA;EHggB9C;AG/fmC;EAAW,kBAAA;EHkgB9C;AGjgBmC;EAAW,kBAAA;EHogB9C;AGngBmC;EAAW,kBAAA;EHsgB9C;AGrgBmC;EAAW,kBAAA;EHwgB9C;AGvgBmC;EAAW,kBAAA;EH0gB9C;AGzgBmC;EAAW,kBAAA;EH4gB9C;AG3gBmC;EAAW,kBAAA;EH8gB9C;AG7gBmC;EAAW,kBAAA;EHghB9C;AG/gBmC;EAAW,kBAAA;EHkhB9C;AGjhBmC;EAAW,kBAAA;EHohB9C;AGnhBmC;EAAW,kBAAA;EHshB9C;AGrhBmC;EAAW,kBAAA;EHwhB9C;AGvhBmC;EAAW,kBAAA;EH0hB9C;AGzhBmC;EAAW,kBAAA;EH4hB9C;AG3hBmC;EAAW,kBAAA;EH8hB9C;AG7hBmC;EAAW,kBAAA;EHgiB9C;AG/hBmC;EAAW,kBAAA;EHkiB9C;AGjiBmC;EAAW,kBAAA;EHoiB9C;AGniBmC;EAAW,kBAAA;EHsiB9C;AGriBmC;EAAW,kBAAA;EHwiB9C;AGviBmC;EAAW,kBAAA;EH0iB9C;AGziBmC;EAAW,kBAAA;EH4iB9C;AG3iBmC;EAAW,kBAAA;EH8iB9C;AG7iBmC;EAAW,kBAAA;EHgjB9C;AG/iBmC;EAAW,kBAAA;EHkjB9C;AGjjBmC;EAAW,kBAAA;EHojB9C;AGnjBmC;EAAW,kBAAA;EHsjB9C;AGrjBmC;EAAW,kBAAA;EHwjB9C;AGvjBmC;EAAW,kBAAA;EH0jB9C;AGzjBmC;EAAW,kBAAA;EH4jB9C;AG3jBmC;EAAW,kBAAA;EH8jB9C;AG7jBmC;EAAW,kBAAA;EHgkB9C;AG/jBmC;EAAW,kBAAA;EHkkB9C;AGjkBmC;EAAW,kBAAA;EHokB9C;AGnkBmC;EAAW,kBAAA;EHskB9C;AGrkBmC;EAAW,kBAAA;EHwkB9C;AGvkBmC;EAAW,kBAAA;EH0kB9C;AGzkBmC;EAAW,kBAAA;EH4kB9C;AG3kBmC;EAAW,kBAAA;EH8kB9C;AG7kBmC;EAAW,kBAAA;EHglB9C;AG/kBmC;EAAW,kBAAA;EHklB9C;AGjlBmC;EAAW,kBAAA;EHolB9C;AGnlBmC;EAAW,kBAAA;EHslB9C;AGrlBmC;EAAW,kBAAA;EHwlB9C;AGvlBmC;EAAW,kBAAA;EH0lB9C;AGzlBmC;EAAW,kBAAA;EH4lB9C;AG3lBmC;EAAW,kBAAA;EH8lB9C;AG7lBmC;EAAW,kBAAA;EHgmB9C;AG/lBmC;EAAW,kBAAA;EHkmB9C;AGjmBmC;EAAW,kBAAA;EHomB9C;AGnmBmC;EAAW,kBAAA;EHsmB9C;AGrmBmC;EAAW,kBAAA;EHwmB9C;AGvmBmC;EAAW,kBAAA;EH0mB9C;AGzmBmC;EAAW,kBAAA;EH4mB9C;AG3mBmC;EAAW,kBAAA;EH8mB9C;AG7mBmC;EAAW,kBAAA;EHgnB9C;AG/mBmC;EAAW,kBAAA;EHknB9C;AGjnBmC;EAAW,kBAAA;EHonB9C;AGnnBmC;EAAW,kBAAA;EHsnB9C;AGrnBmC;EAAW,kBAAA;EHwnB9C;AGvnBmC;EAAW,kBAAA;EH0nB9C;AGznBmC;EAAW,kBAAA;EH4nB9C;AG3nBmC;EAAW,kBAAA;EH8nB9C;AI71BD;ECgEE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELgyBT;AI/1BD;;EC6DE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELsyBT;AI71BD;EACE,iBAAA;EACA,+CAAA;EJ+1BD;AI51BD;EACE,6DAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EJ81BD;AI11BD;;;;EAIE,sBAAA;EACA,oBAAA;EACA,sBAAA;EJ41BD;AIt1BD;EACE,gBAAA;EACA,uBAAA;EJw1BD;AIt1BC;;EAEE,gBAAA;EACA,4BAAA;EJw1BH;AIr1BC;EErDA,sBAAA;EAEA,4CAAA;EACA,sBAAA;EN44BD;AI/0BD;EACE,WAAA;EJi1BD;AI30BD;EACE,wBAAA;EJ60BD;AIz0BD;;;;;EGvEE,gBAAA;EACA,iBAAA;EACA,cAAA;EPu5BD;AI70BD;EACE,oBAAA;EJ+0BD;AIz0BD;EACE,cAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EC6FA,0CAAA;EACK,qCAAA;EACG,kCAAA;EEvLR,uBAAA;EACA,iBAAA;EACA,cAAA;EPu6BD;AIz0BD;EACE,oBAAA;EJ20BD;AIr0BD;EACE,kBAAA;EACA,qBAAA;EACA,WAAA;EACA,+BAAA;EJu0BD;AI/zBD;EACE,oBAAA;EACA,YAAA;EACA,aAAA;EACA,cAAA;EACA,YAAA;EACA,kBAAA;EACA,wBAAA;EACA,WAAA;EJi0BD;AIzzBC;;EAEE,kBAAA;EACA,aAAA;EACA,cAAA;EACA,WAAA;EACA,mBAAA;EACA,YAAA;EJ2zBH;AQt8BD;;;;;;;;;;;;EAEE,sBAAA;EACA,kBAAA;EACA,kBAAA;EACA,gBAAA;ERk9BD;AQv9BD;;;;;;;;;;;;;;;;;;;;;;;;EASI,qBAAA;EACA,gBAAA;EACA,gBAAA;ERw+BH;AQp+BD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERy+BD;AQ7+BD;;;;;;;;;;;;EAQI,gBAAA;ERm/BH;AQh/BD;;;;;;EAGE,kBAAA;EACA,qBAAA;ERq/BD;AQz/BD;;;;;;;;;;;;EAQI,gBAAA;ER+/BH;AQ3/BD;;EAAU,iBAAA;ER+/BT;AQ9/BD;;EAAU,iBAAA;ERkgCT;AQjgCD;;EAAU,iBAAA;ERqgCT;AQpgCD;;EAAU,iBAAA;ERwgCT;AQvgCD;;EAAU,iBAAA;ER2gCT;AQ1gCD;;EAAU,iBAAA;ER8gCT;AQxgCD;EACE,kBAAA;ER0gCD;AQvgCD;EACE,qBAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;ERygCD;AQpgCD;EAAA;IAFI,iBAAA;IR0gCD;EACF;AQlgCD;;EAEE,gBAAA;ERogCD;AQjgCD;;EAEE,2BAAA;EACA,eAAA;ERmgCD;AQ//BD;EAAuB,kBAAA;ERkgCtB;AQjgCD;EAAuB,mBAAA;ERogCtB;AQngCD;EAAuB,oBAAA;ERsgCtB;AQrgCD;EAAuB,qBAAA;ERwgCtB;AQvgCD;EAAuB,qBAAA;ER0gCtB;AQvgCD;EAAuB,2BAAA;ER0gCtB;AQzgCD;EAAuB,2BAAA;ER4gCtB;AQ3gCD;EAAuB,4BAAA;ER8gCtB;AQ3gCD;EACE,gBAAA;ER6gCD;AQ3gCD;ECrGE,gBAAA;ETmnCD;ASlnCC;EACE,gBAAA;ETonCH;AQ9gCD;ECxGE,gBAAA;ETynCD;ASxnCC;EACE,gBAAA;ET0nCH;AQjhCD;EC3GE,gBAAA;ET+nCD;AS9nCC;EACE,gBAAA;ETgoCH;AQphCD;EC9GE,gBAAA;ETqoCD;ASpoCC;EACE,gBAAA;ETsoCH;AQvhCD;ECjHE,gBAAA;ET2oCD;AS1oCC;EACE,gBAAA;ET4oCH;AQthCD;EAGE,aAAA;EE3HA,2BAAA;EVkpCD;AUjpCC;EACE,2BAAA;EVmpCH;AQvhCD;EE9HE,2BAAA;EVwpCD;AUvpCC;EACE,2BAAA;EVypCH;AQ1hCD;EEjIE,2BAAA;EV8pCD;AU7pCC;EACE,2BAAA;EV+pCH;AQ7hCD;EEpIE,2BAAA;EVoqCD;AUnqCC;EACE,2BAAA;EVqqCH;AQhiCD;EEvIE,2BAAA;EV0qCD;AUzqCC;EACE,2BAAA;EV2qCH;AQ9hCD;EACE,qBAAA;EACA,qBAAA;EACA,kCAAA;ERgiCD;AQxhCD;;EAEE,eAAA;EACA,qBAAA;ER0hCD;AQ7hCD;;;;EAMI,kBAAA;ER6hCH;AQthCD;EACE,iBAAA;EACA,kBAAA;ERwhCD;AQphCD;EALE,iBAAA;EACA,kBAAA;EAMA,mBAAA;ERuhCD;AQzhCD;EAKI,uBAAA;EACA,mBAAA;EACA,oBAAA;ERuhCH;AQlhCD;EACE,eAAA;EACA,qBAAA;ERohCD;AQlhCD;;EAEE,yBAAA;ERohCD;AQlhCD;EACE,mBAAA;ERohCD;AQlhCD;EACE,gBAAA;ERohCD;AQ3/BD;EAAA;IAVM,aAAA;IACA,cAAA;IACA,aAAA;IACA,mBAAA;IGtNJ,kBAAA;IACA,yBAAA;IACA,qBAAA;IXguCC;EQrgCH;IAHM,oBAAA;IR2gCH;EACF;AQlgCD;;EAGE,cAAA;EACA,mCAAA;ERmgCD;AQjgCD;EACE,gBAAA;EACA,2BAAA;ERmgCD;AQ//BD;EACE,oBAAA;EACA,kBAAA;EACA,mBAAA;EACA,gCAAA;ERigCD;AQ5/BG;;;EACE,kBAAA;ERggCL;AQ1gCD;;;EAmBI,gBAAA;EACA,gBAAA;EACA,yBAAA;EACA,gBAAA;ER4/BH;AQ1/BG;;;EACE,wBAAA;ER8/BL;AQt/BD;;EAEE,qBAAA;EACA,iBAAA;EACA,iCAAA;EACA,gBAAA;EACA,mBAAA;ERw/BD;AQl/BG;;;;;;EAAW,aAAA;ER0/Bd;AQz/BG;;;;;;EACE,wBAAA;ERggCL;AQ1/BD;EACE,qBAAA;EACA,oBAAA;EACA,yBAAA;ER4/BD;AYlyCD;;;;EAIE,gEAAA;EZoyCD;AYhyCD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EZkyCD;AY9xCD;EACE,kBAAA;EACA,gBAAA;EACA,gBAAA;EACA,2BAAA;EACA,oBAAA;EACA,wDAAA;UAAA,gDAAA;EZgyCD;AYtyCD;EASI,YAAA;EACA,iBAAA;EACA,mBAAA;EACA,0BAAA;UAAA,kBAAA;EZgyCH;AY3xCD;EACE,gBAAA;EACA,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,uBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EZ6xCD;AYxyCD;EAeI,YAAA;EACA,oBAAA;EACA,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,kBAAA;EZ4xCH;AYvxCD;EACE,mBAAA;EACA,oBAAA;EZyxCD;Aan1CD;ECHE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;Edy1CD;Aan1CC;EAAA;IAFE,cAAA;Iby1CD;EACF;Aar1CC;EAAA;IAFE,cAAA;Ib21CD;EACF;Aav1CD;EAAA;IAFI,eAAA;Ib61CD;EACF;Aap1CD;ECvBE,oBAAA;EACA,mBAAA;EACA,oBAAA;EACA,qBAAA;Ed82CD;Aaj1CD;ECvBE,oBAAA;EACA,qBAAA;Ed22CD;Ae32CG;EACE,oBAAA;EAEA,iBAAA;EAEA,oBAAA;EACA,qBAAA;Ef22CL;Ae31CG;EACE,aAAA;Ef61CL;Aet1CC;EACE,aAAA;Efw1CH;Aez1CC;EACE,qBAAA;Ef21CH;Ae51CC;EACE,qBAAA;Ef81CH;Ae/1CC;EACE,YAAA;Efi2CH;Ael2CC;EACE,qBAAA;Efo2CH;Aer2CC;EACE,qBAAA;Efu2CH;Aex2CC;EACE,YAAA;Ef02CH;Ae32CC;EACE,qBAAA;Ef62CH;Ae92CC;EACE,qBAAA;Efg3CH;Aej3CC;EACE,YAAA;Efm3CH;Aep3CC;EACE,qBAAA;Efs3CH;Aev3CC;EACE,oBAAA;Efy3CH;Ae32CC;EACE,aAAA;Ef62CH;Ae92CC;EACE,qBAAA;Efg3CH;Aej3CC;EACE,qBAAA;Efm3CH;Aep3CC;EACE,YAAA;Efs3CH;Aev3CC;EACE,qBAAA;Efy3CH;Ae13CC;EACE,qBAAA;Ef43CH;Ae73CC;EACE,YAAA;Ef+3CH;Aeh4CC;EACE,qBAAA;Efk4CH;Aen4CC;EACE,qBAAA;Efq4CH;Aet4CC;EACE,YAAA;Efw4CH;Aez4CC;EACE,qBAAA;Ef24CH;Ae54CC;EACE,oBAAA;Ef84CH;Ae14CC;EACE,aAAA;Ef44CH;Ae55CC;EACE,YAAA;Ef85CH;Ae/5CC;EACE,oBAAA;Efi6CH;Ael6CC;EACE,oBAAA;Efo6CH;Aer6CC;EACE,WAAA;Efu6CH;Aex6CC;EACE,oBAAA;Ef06CH;Ae36CC;EACE,oBAAA;Ef66CH;Ae96CC;EACE,WAAA;Efg7CH;Aej7CC;EACE,oBAAA;Efm7CH;Aep7CC;EACE,oBAAA;Efs7CH;Aev7CC;EACE,WAAA;Efy7CH;Ae17CC;EACE,oBAAA;Ef47CH;Ae77CC;EACE,mBAAA;Ef+7CH;Ae37CC;EACE,YAAA;Ef67CH;Ae/6CC;EACE,mBAAA;Efi7CH;Ael7CC;EACE,2BAAA;Efo7CH;Aer7CC;EACE,2BAAA;Efu7CH;Aex7CC;EACE,kBAAA;Ef07CH;Ae37CC;EACE,2BAAA;Ef67CH;Ae97CC;EACE,2BAAA;Efg8CH;Aej8CC;EACE,kBAAA;Efm8CH;Aep8CC;EACE,2BAAA;Efs8CH;Aev8CC;EACE,2BAAA;Efy8CH;Ae18CC;EACE,kBAAA;Ef48CH;Ae78CC;EACE,2BAAA;Ef+8CH;Aeh9CC;EACE,0BAAA;Efk9CH;Aen9CC;EACE,iBAAA;Efq9CH;Aaz9CD;EE9BI;IACE,aAAA;If0/CH;Een/CD;IACE,aAAA;Ifq/CD;Eet/CD;IACE,qBAAA;Ifw/CD;Eez/CD;IACE,qBAAA;If2/CD;Ee5/CD;IACE,YAAA;If8/CD;Ee//CD;IACE,qBAAA;IfigDD;EelgDD;IACE,qBAAA;IfogDD;EergDD;IACE,YAAA;IfugDD;EexgDD;IACE,qBAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,YAAA;IfghDD;EejhDD;IACE,qBAAA;IfmhDD;EephDD;IACE,oBAAA;IfshDD;EexgDD;IACE,aAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,qBAAA;IfghDD;EejhDD;IACE,YAAA;IfmhDD;EephDD;IACE,qBAAA;IfshDD;EevhDD;IACE,qBAAA;IfyhDD;Ee1hDD;IACE,YAAA;If4hDD;Ee7hDD;IACE,qBAAA;If+hDD;EehiDD;IACE,qBAAA;IfkiDD;EeniDD;IACE,YAAA;IfqiDD;EetiDD;IACE,qBAAA;IfwiDD;EeziDD;IACE,oBAAA;If2iDD;EeviDD;IACE,aAAA;IfyiDD;EezjDD;IACE,YAAA;If2jDD;Ee5jDD;IACE,oBAAA;If8jDD;Ee/jDD;IACE,oBAAA;IfikDD;EelkDD;IACE,WAAA;IfokDD;EerkDD;IACE,oBAAA;IfukDD;EexkDD;IACE,oBAAA;If0kDD;Ee3kDD;IACE,WAAA;If6kDD;Ee9kDD;IACE,oBAAA;IfglDD;EejlDD;IACE,oBAAA;IfmlDD;EeplDD;IACE,WAAA;IfslDD;EevlDD;IACE,oBAAA;IfylDD;Ee1lDD;IACE,mBAAA;If4lDD;EexlDD;IACE,YAAA;If0lDD;Ee5kDD;IACE,mBAAA;If8kDD;Ee/kDD;IACE,2BAAA;IfilDD;EellDD;IACE,2BAAA;IfolDD;EerlDD;IACE,kBAAA;IfulDD;EexlDD;IACE,2BAAA;If0lDD;Ee3lDD;IACE,2BAAA;If6lDD;Ee9lDD;IACE,kBAAA;IfgmDD;EejmDD;IACE,2BAAA;IfmmDD;EepmDD;IACE,2BAAA;IfsmDD;EevmDD;IACE,kBAAA;IfymDD;Ee1mDD;IACE,2BAAA;If4mDD;Ee7mDD;IACE,0BAAA;If+mDD;EehnDD;IACE,iBAAA;IfknDD;EACF;Aa9mDD;EEvCI;IACE,aAAA;IfwpDH;EejpDD;IACE,aAAA;IfmpDD;EeppDD;IACE,qBAAA;IfspDD;EevpDD;IACE,qBAAA;IfypDD;Ee1pDD;IACE,YAAA;If4pDD;Ee7pDD;IACE,qBAAA;If+pDD;EehqDD;IACE,qBAAA;IfkqDD;EenqDD;IACE,YAAA;IfqqDD;EetqDD;IACE,qBAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,YAAA;If8qDD;Ee/qDD;IACE,qBAAA;IfirDD;EelrDD;IACE,oBAAA;IforDD;EetqDD;IACE,aAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,qBAAA;If8qDD;Ee/qDD;IACE,YAAA;IfirDD;EelrDD;IACE,qBAAA;IforDD;EerrDD;IACE,qBAAA;IfurDD;EexrDD;IACE,YAAA;If0rDD;Ee3rDD;IACE,qBAAA;If6rDD;Ee9rDD;IACE,qBAAA;IfgsDD;EejsDD;IACE,YAAA;IfmsDD;EepsDD;IACE,qBAAA;IfssDD;EevsDD;IACE,oBAAA;IfysDD;EersDD;IACE,aAAA;IfusDD;EevtDD;IACE,YAAA;IfytDD;Ee1tDD;IACE,oBAAA;If4tDD;Ee7tDD;IACE,oBAAA;If+tDD;EehuDD;IACE,WAAA;IfkuDD;EenuDD;IACE,oBAAA;IfquDD;EetuDD;IACE,oBAAA;IfwuDD;EezuDD;IACE,WAAA;If2uDD;Ee5uDD;IACE,oBAAA;If8uDD;Ee/uDD;IACE,oBAAA;IfivDD;EelvDD;IACE,WAAA;IfovDD;EervDD;IACE,oBAAA;IfuvDD;EexvDD;IACE,mBAAA;If0vDD;EetvDD;IACE,YAAA;IfwvDD;Ee1uDD;IACE,mBAAA;If4uDD;Ee7uDD;IACE,2BAAA;If+uDD;EehvDD;IACE,2BAAA;IfkvDD;EenvDD;IACE,kBAAA;IfqvDD;EetvDD;IACE,2BAAA;IfwvDD;EezvDD;IACE,2BAAA;If2vDD;Ee5vDD;IACE,kBAAA;If8vDD;Ee/vDD;IACE,2BAAA;IfiwDD;EelwDD;IACE,2BAAA;IfowDD;EerwDD;IACE,kBAAA;IfuwDD;EexwDD;IACE,2BAAA;If0wDD;Ee3wDD;IACE,0BAAA;If6wDD;Ee9wDD;IACE,iBAAA;IfgxDD;EACF;AarwDD;EE9CI;IACE,aAAA;IfszDH;Ee/yDD;IACE,aAAA;IfizDD;EelzDD;IACE,qBAAA;IfozDD;EerzDD;IACE,qBAAA;IfuzDD;EexzDD;IACE,YAAA;If0zDD;Ee3zDD;IACE,qBAAA;If6zDD;Ee9zDD;IACE,qBAAA;Ifg0DD;Eej0DD;IACE,YAAA;Ifm0DD;Eep0DD;IACE,qBAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,YAAA;If40DD;Ee70DD;IACE,qBAAA;If+0DD;Eeh1DD;IACE,oBAAA;Ifk1DD;Eep0DD;IACE,aAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,qBAAA;If40DD;Ee70DD;IACE,YAAA;If+0DD;Eeh1DD;IACE,qBAAA;Ifk1DD;Een1DD;IACE,qBAAA;Ifq1DD;Eet1DD;IACE,YAAA;Ifw1DD;Eez1DD;IACE,qBAAA;If21DD;Ee51DD;IACE,qBAAA;If81DD;Ee/1DD;IACE,YAAA;Ifi2DD;Eel2DD;IACE,qBAAA;Ifo2DD;Eer2DD;IACE,oBAAA;Ifu2DD;Een2DD;IACE,aAAA;Ifq2DD;Eer3DD;IACE,YAAA;Ifu3DD;Eex3DD;IACE,oBAAA;If03DD;Ee33DD;IACE,oBAAA;If63DD;Ee93DD;IACE,WAAA;Ifg4DD;Eej4DD;IACE,oBAAA;Ifm4DD;Eep4DD;IACE,oBAAA;Ifs4DD;Eev4DD;IACE,WAAA;Ify4DD;Ee14DD;IACE,oBAAA;If44DD;Ee74DD;IACE,oBAAA;If+4DD;Eeh5DD;IACE,WAAA;Ifk5DD;Een5DD;IACE,oBAAA;Ifq5DD;Eet5DD;IACE,mBAAA;Ifw5DD;Eep5DD;IACE,YAAA;Ifs5DD;Eex4DD;IACE,mBAAA;If04DD;Ee34DD;IACE,2BAAA;If64DD;Ee94DD;IACE,2BAAA;Ifg5DD;Eej5DD;IACE,kBAAA;Ifm5DD;Eep5DD;IACE,2BAAA;Ifs5DD;Eev5DD;IACE,2BAAA;Ify5DD;Ee15DD;IACE,kBAAA;If45DD;Ee75DD;IACE,2BAAA;If+5DD;Eeh6DD;IACE,2BAAA;Ifk6DD;Een6DD;IACE,kBAAA;Ifq6DD;Eet6DD;IACE,2BAAA;Ifw6DD;Eez6DD;IACE,0BAAA;If26DD;Ee56DD;IACE,iBAAA;If86DD;EACF;AgBl/DD;EACE,+BAAA;EhBo/DD;AgBl/DD;EACE,kBAAA;EACA,qBAAA;EACA,gBAAA;EACA,kBAAA;EhBo/DD;AgBl/DD;EACE,kBAAA;EhBo/DD;AgB9+DD;EACE,aAAA;EACA,iBAAA;EACA,qBAAA;EhBg/DD;AgBn/DD;;;;;;EAWQ,cAAA;EACA,yBAAA;EACA,qBAAA;EACA,+BAAA;EhBg/DP;AgB9/DD;EAoBI,wBAAA;EACA,kCAAA;EhB6+DH;AgBlgED;;;;;;EA8BQ,eAAA;EhB4+DP;AgB1gED;EAoCI,+BAAA;EhBy+DH;AgB7gED;EAyCI,2BAAA;EhBu+DH;AgBh+DD;;;;;;EAOQ,cAAA;EhBi+DP;AgBt9DD;EACE,2BAAA;EhBw9DD;AgBz9DD;;;;;;EAQQ,2BAAA;EhBy9DP;AgBj+DD;;EAeM,0BAAA;EhBs9DL;AgB58DD;EAEI,2BAAA;EhB68DH;AgBp8DD;EAEI,2BAAA;EhBq8DH;AgB57DD;EACE,kBAAA;EACA,aAAA;EACA,uBAAA;EhB87DD;AgBz7DG;;EACE,kBAAA;EACA,aAAA;EACA,qBAAA;EhB47DL;AiBxkEC;;;;;;;;;;;;EAOI,2BAAA;EjB+kEL;AiBzkEC;;;;;EAMI,2BAAA;EjB0kEL;AiB7lEC;;;;;;;;;;;;EAOI,2BAAA;EjBomEL;AiB9lEC;;;;;EAMI,2BAAA;EjB+lEL;AiBlnEC;;;;;;;;;;;;EAOI,2BAAA;EjBynEL;AiBnnEC;;;;;EAMI,2BAAA;EjBonEL;AiBvoEC;;;;;;;;;;;;EAOI,2BAAA;EjB8oEL;AiBxoEC;;;;;EAMI,2BAAA;EjByoEL;AiB5pEC;;;;;;;;;;;;EAOI,2BAAA;EjBmqEL;AiB7pEC;;;;;EAMI,2BAAA;EjB8pEL;AgB5gED;EACE,kBAAA;EACA,mBAAA;EhB8gED;AgBj9DD;EAAA;IA1DI,aAAA;IACA,qBAAA;IACA,oBAAA;IACA,8CAAA;IACA,2BAAA;IhB+gED;EgBz9DH;IAlDM,kBAAA;IhB8gEH;EgB59DH;;;;;;IAzCY,qBAAA;IhB6gET;EgBp+DH;IAjCM,WAAA;IhBwgEH;EgBv+DH;;;;;;IAxBY,gBAAA;IhBugET;EgB/+DH;;;;;;IApBY,iBAAA;IhB2gET;EgBv/DH;;;;IAPY,kBAAA;IhBogET;EACF;AkB9tED;EACE,YAAA;EACA,WAAA;EACA,WAAA;EAIA,cAAA;ElB6tED;AkB1tED;EACE,gBAAA;EACA,aAAA;EACA,YAAA;EACA,qBAAA;EACA,iBAAA;EACA,sBAAA;EACA,gBAAA;EACA,WAAA;EACA,kCAAA;ElB4tED;AkBztED;EACE,uBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;ElB2tED;AkBhtED;Eb4BE,gCAAA;EACG,6BAAA;EACK,wBAAA;ELurET;AkBhtED;;EAEE,iBAAA;EACA,oBAAA;EACA,qBAAA;ElBktED;AkB9sED;EACE,gBAAA;ElBgtED;AkB5sED;EACE,gBAAA;EACA,aAAA;ElB8sED;AkB1sED;;EAEE,cAAA;ElB4sED;AkBxsED;;;EZxEE,sBAAA;EAEA,4CAAA;EACA,sBAAA;ENoxED;AkBxsED;EACE,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;ElB0sED;AkBhrED;EACE,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,2BAAA;EACA,wBAAA;EACA,2BAAA;EACA,oBAAA;EbzDA,0DAAA;EACQ,kDAAA;EAyHR,wFAAA;EACK,2EAAA;EACG,wEAAA;ELonET;AmB5vEC;EACE,uBAAA;EACA,YAAA;EdUF,wFAAA;EACQ,gFAAA;ELqvET;AKptEC;EACE,gBAAA;EACA,YAAA;ELstEH;AKptEC;EAA0B,gBAAA;ELutE3B;AKttEC;EAAgC,gBAAA;ELytEjC;AkBxrEC;;;EAGE,qBAAA;EACA,2BAAA;EACA,YAAA;ElB0rEH;AkBtrEC;EACE,cAAA;ElBwrEH;AkB5qED;EACE,0BAAA;ElB8qED;AkB7oED;EArBE;;;;IAIE,mBAAA;IlBqqED;EkBnqED;;;;IAIE,mBAAA;IlBqqED;EkBnqED;;;;IAIE,mBAAA;IlBqqED;EACF;AkB5pED;EACE,qBAAA;ElB8pED;AkBtpED;;EAEE,oBAAA;EACA,gBAAA;EACA,kBAAA;EACA,qBAAA;ElBwpED;AkB7pED;;EAQI,kBAAA;EACA,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,iBAAA;ElBypEH;AkBtpED;;;;EAIE,oBAAA;EACA,oBAAA;EACA,oBAAA;ElBwpED;AkBrpED;;EAEE,kBAAA;ElBupED;AkBnpED;;EAEE,uBAAA;EACA,oBAAA;EACA,kBAAA;EACA,wBAAA;EACA,qBAAA;EACA,iBAAA;ElBqpED;AkBnpED;;EAEE,eAAA;EACA,mBAAA;ElBqpED;AkB5oEC;;;;;;EAGE,qBAAA;ElBipEH;AkB3oEC;;;;EAEE,qBAAA;ElB+oEH;AkBzoEC;;;;EAGI,qBAAA;ElB4oEL;AkBjoED;EAEE,kBAAA;EACA,qBAAA;EAEA,kBAAA;ElBioED;AkB/nEC;;EAEE,iBAAA;EACA,kBAAA;ElBioEH;AkBvnED;;ECnPE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnB82ED;AmB52EC;;EACE,cAAA;EACA,mBAAA;EnB+2EH;AmB52EC;;;;EAEE,cAAA;EnBg3EH;AkBroED;;ECxPE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;EnBi4ED;AmB/3EC;;EACE,cAAA;EACA,mBAAA;EnBk4EH;AmB/3EC;;;;EAEE,cAAA;EnBm4EH;AkB9oED;EAEE,oBAAA;ElB+oED;AkBjpED;EAMI,uBAAA;ElB8oEH;AkB1oED;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,YAAA;EACA,gBAAA;EACA,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oBAAA;EACA,sBAAA;ElB4oED;AkB1oED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB4oED;AkB1oED;EACE,aAAA;EACA,cAAA;EACA,mBAAA;ElB4oED;AkBxoED;;;;;;;;;;ECxVI,gBAAA;EnB4+EH;AkBppED;ECpVI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;EL67ET;AmB3+EG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELk8ET;AkB9pED;EC1UI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnB2+EH;AkBnqED;ECpUI,gBAAA;EnB0+EH;AkBnqED;;;;;;;;;;EC3VI,gBAAA;EnB0gFH;AkB/qED;ECvVI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;EL29ET;AmBzgFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;ELg+ET;AkBzrED;EC7UI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBygFH;AkB9rED;ECvUI,gBAAA;EnBwgFH;AkB9rED;;;;;;;;;;EC9VI,gBAAA;EnBwiFH;AkB1sED;EC1VI,uBAAA;Ed+CF,0DAAA;EACQ,kDAAA;ELy/ET;AmBviFG;EACE,uBAAA;Ed4CJ,2EAAA;EACQ,mEAAA;EL8/ET;AkBptED;EChVI,gBAAA;EACA,uBAAA;EACA,2BAAA;EnBuiFH;AkBztED;EC1UI,gBAAA;EnBsiFH;AkBrtEC;EACG,WAAA;ElButEJ;AkBrtEC;EACG,QAAA;ElButEJ;AkB7sED;EACE,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;ElB+sED;AkB3nED;EAAA;IA/DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlB8rEH;EkBjoEH;IAxDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB4rEH;EkBtoEH;IAjDM,uBAAA;IlB0rEH;EkBzoEH;IA7CM,uBAAA;IACA,wBAAA;IlByrEH;EkB7oEH;;;IAvCQ,aAAA;IlByrEL;EkBlpEH;IAjCM,aAAA;IlBsrEH;EkBrpEH;IA7BM,kBAAA;IACA,wBAAA;IlBqrEH;EkBzpEH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlBirEH;EkBhqEH;;IAdQ,iBAAA;IlBkrEL;EkBpqEH;;IATM,oBAAA;IACA,gBAAA;IlBirEH;EkBzqEH;IAHM,QAAA;IlB+qEH;EACF;AkBrqED;;;;EASI,eAAA;EACA,kBAAA;EACA,kBAAA;ElBkqEH;AkB7qED;;EAiBI,kBAAA;ElBgqEH;AkBjrED;EJrdE,oBAAA;EACA,qBAAA;EdyoFD;AkBlpEC;EAAA;IANI,mBAAA;IACA,kBAAA;IACA,kBAAA;IlB4pEH;EACF;AkB5rED;EAwCI,aAAA;ElBupEH;AkB1oEC;EAAA;IAHM,qBAAA;IlBipEL;EACF;AkBxoEC;EAAA;IAHM,kBAAA;IlB+oEL;EACF;AoBrqFD;EACE,uBAAA;EACA,kBAAA;EACA,qBAAA;EACA,oBAAA;EACA,wBAAA;EACA,gCAAA;MAAA,4BAAA;EACA,iBAAA;EACA,wBAAA;EACA,+BAAA;EACA,qBAAA;EC6BA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,oBAAA;EhB4KA,2BAAA;EACG,wBAAA;EACC,uBAAA;EACI,mBAAA;ELg+ET;AoBxqFG;;;;;;EdrBF,sBAAA;EAEA,4CAAA;EACA,sBAAA;ENosFD;AoB5qFC;;;EAGE,gBAAA;EACA,uBAAA;EpB8qFH;AoB3qFC;;EAEE,YAAA;EACA,wBAAA;Ef2BF,0DAAA;EACQ,kDAAA;ELmpFT;AoB3qFC;;;EAGE,qBAAA;EACA,sBAAA;EE9CF,eAAA;EAGA,2BAAA;EjB8DA,0BAAA;EACQ,kBAAA;EL6pFT;AoBvqFD;ECrDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB+tFD;AqB7tFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB+tFP;AqB7tFC;;;EAGE,wBAAA;ErB+tFH;AqB1tFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBwuFT;AoBhtFD;ECnBI,gBAAA;EACA,2BAAA;ErBsuFH;AoBjtFD;ECxDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB4wFD;AqB1wFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB4wFP;AqB1wFC;;;EAGE,wBAAA;ErB4wFH;AqBvwFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBqxFT;AoB1vFD;ECtBI,gBAAA;EACA,2BAAA;ErBmxFH;AoB1vFD;EC5DE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErByzFD;AqBvzFC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErByzFP;AqBvzFC;;;EAGE,wBAAA;ErByzFH;AqBpzFG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBk0FT;AoBnyFD;EC1BI,gBAAA;EACA,2BAAA;ErBg0FH;AoBnyFD;EChEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBs2FD;AqBp2FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBs2FP;AqBp2FC;;;EAGE,wBAAA;ErBs2FH;AqBj2FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB+2FT;AoB50FD;EC9BI,gBAAA;EACA,2BAAA;ErB62FH;AoB50FD;ECpEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBm5FD;AqBj5FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBm5FP;AqBj5FC;;;EAGE,wBAAA;ErBm5FH;AqB94FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErB45FT;AoBr3FD;EClCI,gBAAA;EACA,2BAAA;ErB05FH;AoBr3FD;ECxEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBg8FD;AqB97FC;;;;;;EAME,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBg8FP;AqB97FC;;;EAGE,wBAAA;ErBg8FH;AqB37FG;;;;;;;;;;;;;;;;;;EAME,2BAAA;EACI,uBAAA;ErBy8FT;AoB95FD;ECtCI,gBAAA;EACA,2BAAA;ErBu8FH;AoBz5FD;EACE,gBAAA;EACA,qBAAA;EACA,kBAAA;EpB25FD;AoBz5FC;;;;;EAKE,+BAAA;Ef7BF,0BAAA;EACQ,kBAAA;ELy7FT;AoB15FC;;;;EAIE,2BAAA;EpB45FH;AoB15FC;;EAEE,gBAAA;EACA,4BAAA;EACA,+BAAA;EpB45FH;AoBx5FG;;;;EAEE,gBAAA;EACA,uBAAA;EpB45FL;AoBn5FD;;EC/EE,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;ErBs+FD;AoBt5FD;;ECnFE,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErB6+FD;AoBz5FD;;ECvFE,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;ErBo/FD;AoBx5FD;EACE,gBAAA;EACA,aAAA;EpB05FD;AoBt5FD;EACE,iBAAA;EpBw5FD;AoBj5FC;;;EACE,aAAA;EpBq5FH;AuBziGD;EACE,YAAA;ElBoLA,0CAAA;EACK,qCAAA;EACG,kCAAA;ELw3FT;AuB5iGC;EACE,YAAA;EvB8iGH;AuB1iGD;EACE,eAAA;EACA,oBAAA;EvB4iGD;AuB1iGC;EAAY,gBAAA;EAAgB,qBAAA;EvB8iG7B;AuB7iGC;EAAY,oBAAA;EvBgjGb;AuB/iGC;EAAY,0BAAA;EvBkjGb;AuB/iGD;EACE,oBAAA;EACA,WAAA;EACA,kBAAA;ElBsKA,iDAAA;EACQ,4CAAA;KAAA,yCAAA;EAOR,oCAAA;EACQ,+BAAA;KAAA,4BAAA;EAGR,0CAAA;EACQ,qCAAA;KAAA,kCAAA;ELo4FT;AwB9kGD;EACE,uBAAA;EACA,UAAA;EACA,WAAA;EACA,kBAAA;EACA,wBAAA;EACA,uBAAA;EACA,qCAAA;EACA,oCAAA;ExBglGD;AwB5kGD;EACE,oBAAA;ExB8kGD;AwB1kGD;EACE,YAAA;ExB4kGD;AwBxkGD;EACE,oBAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,aAAA;EACA,kBAAA;EACA,gBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,kBAAA;EACA,2BAAA;EACA,2BAAA;EACA,uCAAA;EACA,oBAAA;EnBwBA,qDAAA;EACQ,6CAAA;EmBvBR,sCAAA;UAAA,8BAAA;ExB2kGD;AwBtkGC;EACE,UAAA;EACA,YAAA;ExBwkGH;AwBjmGD;ECvBE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzB2nGD;AwBvmGD;EAmCI,gBAAA;EACA,mBAAA;EACA,aAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExBukGH;AwBjkGC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;ExBmkGH;AwB7jGC;;;EAGE,gBAAA;EACA,uBAAA;EACA,YAAA;EACA,2BAAA;ExB+jGH;AwBtjGC;;;EAGE,gBAAA;ExBwjGH;AwBpjGC;;EAEE,uBAAA;EACA,+BAAA;EACA,wBAAA;EEzGF,qEAAA;EF2GE,qBAAA;ExBsjGH;AwBjjGD;EAGI,gBAAA;ExBijGH;AwBpjGD;EAQI,YAAA;ExB+iGH;AwBviGD;EACE,YAAA;EACA,UAAA;ExByiGD;AwBjiGD;EACE,SAAA;EACA,aAAA;ExBmiGD;AwB/hGD;EACE,gBAAA;EACA,mBAAA;EACA,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,qBAAA;ExBiiGD;AwB7hGD;EACE,iBAAA;EACA,SAAA;EACA,UAAA;EACA,WAAA;EACA,QAAA;EACA,cAAA;ExB+hGD;AwB3hGD;EACE,UAAA;EACA,YAAA;ExB6hGD;AwBrhGD;;EAII,eAAA;EACA,0BAAA;EACA,aAAA;ExBqhGH;AwB3hGD;;EAUI,WAAA;EACA,cAAA;EACA,oBAAA;ExBqhGH;AwBhgGD;EAXE;IAnEA,YAAA;IACA,UAAA;IxBklGC;EwBhhGD;IAzDA,SAAA;IACA,aAAA;IxB4kGC;EACF;A2B1tGD;;EAEE,oBAAA;EACA,uBAAA;EACA,wBAAA;E3B4tGD;A2BhuGD;;EAMI,oBAAA;EACA,aAAA;E3B8tGH;A2B5tGG;;;;;;;;EAIE,YAAA;E3BkuGL;A2B5tGD;;;;EAKI,mBAAA;E3B6tGH;A2BxtGD;EACE,mBAAA;E3B0tGD;A2B3tGD;;EAMI,aAAA;E3BytGH;A2B/tGD;;;EAWI,kBAAA;E3BytGH;A2BrtGD;EACE,kBAAA;E3ButGD;A2BntGD;EACE,gBAAA;E3BqtGD;A2BptGC;ECjDA,+BAAA;EACG,4BAAA;E5BwwGJ;A2BntGD;;EC9CE,8BAAA;EACG,2BAAA;E5BqwGJ;A2BltGD;EACE,aAAA;E3BotGD;A2BltGD;EACE,kBAAA;E3BotGD;A2BltGD;;EClEE,+BAAA;EACG,4BAAA;E5BwxGJ;A2BjtGD;EChEE,8BAAA;EACG,2BAAA;E5BoxGJ;A2BhtGD;;EAEE,YAAA;E3BktGD;A2BjsGD;EACE,mBAAA;EACA,oBAAA;E3BmsGD;A2BjsGD;EACE,oBAAA;EACA,qBAAA;E3BmsGD;A2B9rGD;EtB9CE,0DAAA;EACQ,kDAAA;EL+uGT;A2B9rGC;EtBlDA,0BAAA;EACQ,kBAAA;ELmvGT;A2B3rGD;EACE,gBAAA;E3B6rGD;A2B1rGD;EACE,yBAAA;EACA,wBAAA;E3B4rGD;A2BzrGD;EACE,yBAAA;E3B2rGD;A2BprGD;;;EAII,gBAAA;EACA,aAAA;EACA,aAAA;EACA,iBAAA;E3BqrGH;A2B5rGD;EAcM,aAAA;E3BirGL;A2B/rGD;;;;EAsBI,kBAAA;EACA,gBAAA;E3B+qGH;A2B1qGC;EACE,kBAAA;E3B4qGH;A2B1qGC;EACE,8BAAA;ECnKF,+BAAA;EACC,8BAAA;E5Bg1GF;A2B3qGC;EACE,gCAAA;EC/KF,4BAAA;EACC,2BAAA;E5B61GF;A2B3qGD;EACE,kBAAA;E3B6qGD;A2B3qGD;;EC9KE,+BAAA;EACC,8BAAA;E5B61GF;A2B1qGD;EC5LE,4BAAA;EACC,2BAAA;E5By2GF;A2BtqGD;EACE,gBAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;E3BwqGD;A2B5qGD;;EAOI,aAAA;EACA,qBAAA;EACA,WAAA;E3ByqGH;A2BlrGD;EAYI,aAAA;E3ByqGH;A2BrrGD;EAgBI,YAAA;E3BwqGH;A2BvpGD;;;;EAKM,oBAAA;EACA,wBAAA;EACA,sBAAA;E3BwpGL;A6Bj4GD;EACE,oBAAA;EACA,gBAAA;EACA,2BAAA;E7Bm4GD;A6Bh4GC;EACE,aAAA;EACA,iBAAA;EACA,kBAAA;E7Bk4GH;A6B34GD;EAeI,oBAAA;EACA,YAAA;EAKA,aAAA;EAEA,aAAA;EACA,kBAAA;E7B03GH;A6Bj3GD;;;EV8BE,cAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,oBAAA;EnBw1GD;AmBt1GC;;;EACE,cAAA;EACA,mBAAA;EnB01GH;AmBv1GC;;;;;;EAEE,cAAA;EnB61GH;A6Bn4GD;;;EVyBE,cAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;EnB+2GD;AmB72GC;;;EACE,cAAA;EACA,mBAAA;EnBi3GH;AmB92GC;;;;;;EAEE,cAAA;EnBo3GH;A6Bj5GD;;;EAGE,qBAAA;E7Bm5GD;A6Bj5GC;;;EACE,kBAAA;E7Bq5GH;A6Bj5GD;;EAEE,WAAA;EACA,qBAAA;EACA,wBAAA;E7Bm5GD;A6B94GD;EACE,mBAAA;EACA,iBAAA;EACA,qBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;E7Bg5GD;A6B74GC;EACE,mBAAA;EACA,iBAAA;EACA,oBAAA;E7B+4GH;A6B74GC;EACE,oBAAA;EACA,iBAAA;EACA,oBAAA;E7B+4GH;A6Bn6GD;;EA0BI,eAAA;E7B64GH;A6Bx4GD;;;;;;;EDhGE,+BAAA;EACG,4BAAA;E5Bi/GJ;A6Bz4GD;EACE,iBAAA;E7B24GD;A6Bz4GD;;;;;;;EDpGE,8BAAA;EACG,2BAAA;E5Bs/GJ;A6B14GD;EACE,gBAAA;E7B44GD;A6Bv4GD;EACE,oBAAA;EAGA,cAAA;EACA,qBAAA;E7Bu4GD;A6B54GD;EAUI,oBAAA;E7Bq4GH;A6B/4GD;EAYM,mBAAA;E7Bs4GL;A6Bn4GG;;;EAGE,YAAA;E7Bq4GL;A6Bh4GC;;EAGI,oBAAA;E7Bi4GL;A6B93GC;;EAGI,mBAAA;E7B+3GL;A8BzhHD;EACE,kBAAA;EACA,iBAAA;EACA,kBAAA;E9B2hHD;A8B9hHD;EAOI,oBAAA;EACA,gBAAA;E9B0hHH;A8BliHD;EAWM,oBAAA;EACA,gBAAA;EACA,oBAAA;E9B0hHL;A8BzhHK;;EAEE,uBAAA;EACA,2BAAA;E9B2hHP;A8BthHG;EACE,gBAAA;E9BwhHL;A8BthHK;;EAEE,gBAAA;EACA,uBAAA;EACA,+BAAA;EACA,qBAAA;E9BwhHP;A8BjhHG;;;EAGE,2BAAA;EACA,uBAAA;E9BmhHL;A8B5jHD;ELHE,aAAA;EACA,eAAA;EACA,kBAAA;EACA,2BAAA;EzBkkHD;A8BlkHD;EA0DI,iBAAA;E9B2gHH;A8BlgHD;EACE,kCAAA;E9BogHD;A8BrgHD;EAGI,aAAA;EAEA,qBAAA;E9BogHH;A8BzgHD;EASM,mBAAA;EACA,yBAAA;EACA,+BAAA;EACA,4BAAA;E9BmgHL;A8BlgHK;EACE,uCAAA;E9BogHP;A8B9/GK;;;EAGE,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,kCAAA;EACA,iBAAA;E9BggHP;A8B3/GC;EAqDA,aAAA;EA8BA,kBAAA;E9B46GD;A8B//GC;EAwDE,aAAA;E9B08GH;A8BlgHC;EA0DI,oBAAA;EACA,oBAAA;E9B28GL;A8BtgHC;EAgEE,WAAA;EACA,YAAA;E9By8GH;A8B77GD;EAAA;IAPM,qBAAA;IACA,WAAA;I9Bw8GH;E8Bl8GH;IAJQ,kBAAA;I9By8GL;EACF;A8BnhHC;EAuFE,iBAAA;EACA,oBAAA;E9B+7GH;A8BvhHC;;;EA8FE,2BAAA;E9B87GH;A8Bh7GD;EAAA;IATM,kCAAA;IACA,4BAAA;I9B67GH;E8Br7GH;;;IAHM,8BAAA;I9B67GH;EACF;A8B9hHD;EAEI,aAAA;E9B+hHH;A8BjiHD;EAMM,oBAAA;E9B8hHL;A8BpiHD;EASM,kBAAA;E9B8hHL;A8BzhHK;;;EAGE,gBAAA;EACA,2BAAA;E9B2hHP;A8BnhHD;EAEI,aAAA;E9BohHH;A8BthHD;EAIM,iBAAA;EACA,gBAAA;E9BqhHL;A8BzgHD;EACE,aAAA;E9B2gHD;A8B5gHD;EAII,aAAA;E9B2gHH;A8B/gHD;EAMM,oBAAA;EACA,oBAAA;E9B4gHL;A8BnhHD;EAYI,WAAA;EACA,YAAA;E9B0gHH;A8B9/GD;EAAA;IAPM,qBAAA;IACA,WAAA;I9BygHH;E8BngHH;IAJQ,kBAAA;I9B0gHL;EACF;A8BlgHD;EACE,kBAAA;E9BogHD;A8BrgHD;EAKI,iBAAA;EACA,oBAAA;E9BmgHH;A8BzgHD;;;EAYI,2BAAA;E9BkgHH;A8Bp/GD;EAAA;IATM,kCAAA;IACA,4BAAA;I9BigHH;E8Bz/GH;;;IAHM,8BAAA;I9BigHH;EACF;A8Bx/GD;EAEI,eAAA;EACA,oBAAA;E9By/GH;A8B5/GD;EAMI,gBAAA;EACA,qBAAA;E9By/GH;A8Bh/GD;EAEE,kBAAA;EF7OA,4BAAA;EACC,2BAAA;E5B+tHF;A+BztHD;EACE,oBAAA;EACA,kBAAA;EACA,qBAAA;EACA,+BAAA;E/B2tHD;A+BntHD;EAAA;IAFI,oBAAA;I/BytHD;EACF;A+B1sHD;EAAA;IAFI,aAAA;I/BgtHD;EACF;A+BlsHD;EACE,qBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,4DAAA;UAAA,oDAAA;EAEA,mCAAA;E/BmsHD;A+BjsHC;EACE,kBAAA;E/BmsHH;A+BtqHD;EAAA;IAzBI,aAAA;IACA,eAAA;IACA,0BAAA;YAAA,kBAAA;I/BmsHD;E+BjsHC;IACE,2BAAA;IACA,gCAAA;IACA,yBAAA;IACA,mBAAA;IACA,8BAAA;I/BmsHH;E+BhsHC;IACE,qBAAA;I/BksHH;E+B7rHC;;;IAGE,iBAAA;IACA,kBAAA;I/B+rHH;EACF;A+B3rHD;;EAGI,mBAAA;E/B4rHH;A+BvrHC;EAAA;;IAFI,mBAAA;I/B8rHH;EACF;A+BrrHD;;;;EAII,qBAAA;EACA,oBAAA;E/BurHH;A+BjrHC;EAAA;;;;IAHI,iBAAA;IACA,gBAAA;I/B2rHH;EACF;A+B/qHD;EACE,eAAA;EACA,uBAAA;E/BirHD;A+B5qHD;EAAA;IAFI,kBAAA;I/BkrHD;EACF;A+B9qHD;;EAEE,iBAAA;EACA,UAAA;EACA,SAAA;EACA,eAAA;E/BgrHD;A+B1qHD;EAAA;;IAFI,kBAAA;I/BirHD;EACF;A+B/qHD;EACE,QAAA;EACA,uBAAA;E/BirHD;A+B/qHD;EACE,WAAA;EACA,kBAAA;EACA,uBAAA;E/BirHD;A+B3qHD;EACE,aAAA;EACA,oBAAA;EACA,iBAAA;EACA,mBAAA;EACA,cAAA;E/B6qHD;A+B3qHC;;EAEE,uBAAA;E/B6qHH;A+BtrHD;EAaI,gBAAA;E/B4qHH;A+BnqHD;EALI;;IAEE,oBAAA;I/B2qHH;EACF;A+BjqHD;EACE,oBAAA;EACA,cAAA;EACA,oBAAA;EACA,mBAAA;EC/LA,iBAAA;EACA,oBAAA;EDgMA,+BAAA;EACA,wBAAA;EACA,+BAAA;EACA,oBAAA;E/BoqHD;A+BhqHC;EACE,YAAA;E/BkqHH;A+BhrHD;EAmBI,gBAAA;EACA,aAAA;EACA,aAAA;EACA,oBAAA;E/BgqHH;A+BtrHD;EAyBI,iBAAA;E/BgqHH;A+B1pHD;EAAA;IAFI,eAAA;I/BgqHD;EACF;A+BvpHD;EACE,qBAAA;E/BypHD;A+B1pHD;EAII,mBAAA;EACA,sBAAA;EACA,mBAAA;E/BypHH;A+B9nHC;EAAA;IArBI,kBAAA;IACA,aAAA;IACA,aAAA;IACA,eAAA;IACA,+BAAA;IACA,WAAA;IACA,0BAAA;YAAA,kBAAA;I/BupHH;E+BxoHD;;IAZM,4BAAA;I/BwpHL;E+B5oHD;IATM,mBAAA;I/BwpHL;E+BvpHK;;IAEE,wBAAA;I/BypHP;EACF;A+BvoHD;EAAA;IAXI,aAAA;IACA,WAAA;I/BspHD;E+B5oHH;IAPM,aAAA;I/BspHH;E+B/oHH;IALQ,mBAAA;IACA,sBAAA;I/BupHL;EACF;A+B5oHD;EACE,oBAAA;EACA,qBAAA;EACA,oBAAA;EACA,mCAAA;EACA,sCAAA;E1B/NA,8FAAA;EACQ,sFAAA;E2B/DR,iBAAA;EACA,oBAAA;EhC86HD;AkBz9GD;EAAA;IA/DM,uBAAA;IACA,kBAAA;IACA,wBAAA;IlB4hHH;EkB/9GH;IAxDM,uBAAA;IACA,aAAA;IACA,wBAAA;IlB0hHH;EkBp+GH;IAjDM,uBAAA;IlBwhHH;EkBv+GH;IA7CM,uBAAA;IACA,wBAAA;IlBuhHH;EkB3+GH;;;IAvCQ,aAAA;IlBuhHL;EkBh/GH;IAjCM,aAAA;IlBohHH;EkBn/GH;IA7BM,kBAAA;IACA,wBAAA;IlBmhHH;EkBv/GH;;IApBM,uBAAA;IACA,eAAA;IACA,kBAAA;IACA,wBAAA;IlB+gHH;EkB9/GH;;IAdQ,iBAAA;IlBghHL;EkBlgHH;;IATM,oBAAA;IACA,gBAAA;IlB+gHH;EkBvgHH;IAHM,QAAA;IlB6gHH;EACF;A+BrrHC;EAAA;IANI,oBAAA;I/B+rHH;E+B7rHG;IACE,kBAAA;I/B+rHL;EACF;A+B9qHD;EAAA;IARI,aAAA;IACA,WAAA;IACA,gBAAA;IACA,iBAAA;IACA,gBAAA;IACA,mBAAA;I1B1PF,0BAAA;IACQ,kBAAA;ILq7HP;EACF;A+BprHD;EACE,eAAA;EHrUA,4BAAA;EACC,2BAAA;E5B4/HF;A+BprHD;EHzUE,8BAAA;EACC,6BAAA;EAOD,+BAAA;EACC,8BAAA;E5B0/HF;A+BhrHD;EChVE,iBAAA;EACA,oBAAA;EhCmgID;A+BjrHC;ECnVA,kBAAA;EACA,qBAAA;EhCugID;A+BlrHC;ECtVA,kBAAA;EACA,qBAAA;EhC2gID;A+B5qHD;EChWE,kBAAA;EACA,qBAAA;EhC+gID;A+BxqHD;EAAA;IAJI,aAAA;IACA,mBAAA;IACA,oBAAA;I/BgrHD;EACF;A+BvpHD;EAZE;IExWA,wBAAA;IjC+gIC;E+BtqHD;IE5WA,yBAAA;IF8WE,qBAAA;I/BwqHD;E+B1qHD;IAKI,iBAAA;I/BwqHH;EACF;A+B/pHD;EACE,2BAAA;EACA,uBAAA;E/BiqHD;A+BnqHD;EAKI,gBAAA;E/BiqHH;A+BhqHG;;EAEE,gBAAA;EACA,+BAAA;E/BkqHL;A+B3qHD;EAcI,gBAAA;E/BgqHH;A+B9qHD;EAmBM,gBAAA;E/B8pHL;A+B5pHK;;EAEE,gBAAA;EACA,+BAAA;E/B8pHP;A+B1pHK;;;EAGE,gBAAA;EACA,2BAAA;E/B4pHP;A+BxpHK;;;EAGE,gBAAA;EACA,+BAAA;E/B0pHP;A+BlsHD;EA8CI,uBAAA;E/BupHH;A+BtpHG;;EAEE,2BAAA;E/BwpHL;A+BzsHD;EAoDM,2BAAA;E/BwpHL;A+B5sHD;;EA0DI,uBAAA;E/BspHH;A+B/oHK;;;EAGE,2BAAA;EACA,gBAAA;E/BipHP;A+BhnHC;EAAA;IAzBQ,gBAAA;I/B6oHP;E+B5oHO;;IAEE,gBAAA;IACA,+BAAA;I/B8oHT;E+B1oHO;;;IAGE,gBAAA;IACA,2BAAA;I/B4oHT;E+BxoHO;;;IAGE,gBAAA;IACA,+BAAA;I/B0oHT;EACF;A+B5uHD;EA8GI,gBAAA;E/BioHH;A+BhoHG;EACE,gBAAA;E/BkoHL;A+BlvHD;EAqHI,gBAAA;E/BgoHH;A+B/nHG;;EAEE,gBAAA;E/BioHL;A+B7nHK;;;;EAEE,gBAAA;E/BioHP;A+BznHD;EACE,2BAAA;EACA,uBAAA;E/B2nHD;A+B7nHD;EAKI,gBAAA;E/B2nHH;A+B1nHG;;EAEE,gBAAA;EACA,+BAAA;E/B4nHL;A+BroHD;EAcI,gBAAA;E/B0nHH;A+BxoHD;EAmBM,gBAAA;E/BwnHL;A+BtnHK;;EAEE,gBAAA;EACA,+BAAA;E/BwnHP;A+BpnHK;;;EAGE,gBAAA;EACA,2BAAA;E/BsnHP;A+BlnHK;;;EAGE,gBAAA;EACA,+BAAA;E/BonHP;A+B5pHD;EA+CI,uBAAA;E/BgnHH;A+B/mHG;;EAEE,2BAAA;E/BinHL;A+BnqHD;EAqDM,2BAAA;E/BinHL;A+BtqHD;;EA2DI,uBAAA;E/B+mHH;A+BzmHK;;;EAGE,2BAAA;EACA,gBAAA;E/B2mHP;A+BpkHC;EAAA;IA/BQ,uBAAA;I/BumHP;E+BxkHD;IA5BQ,2BAAA;I/BumHP;E+B3kHD;IAzBQ,gBAAA;I/BumHP;E+BtmHO;;IAEE,gBAAA;IACA,+BAAA;I/BwmHT;E+BpmHO;;;IAGE,gBAAA;IACA,2BAAA;I/BsmHT;E+BlmHO;;;IAGE,gBAAA;IACA,+BAAA;I/BomHT;EACF;A+B5sHD;EA+GI,gBAAA;E/BgmHH;A+B/lHG;EACE,gBAAA;E/BimHL;A+BltHD;EAsHI,gBAAA;E/B+lHH;A+B9lHG;;EAEE,gBAAA;E/BgmHL;A+B5lHK;;;;EAEE,gBAAA;E/BgmHP;AkC1uID;EACE,mBAAA;EACA,qBAAA;EACA,kBAAA;EACA,2BAAA;EACA,oBAAA;ElC4uID;AkCjvID;EAQI,uBAAA;ElC4uIH;AkCpvID;EAWM,mBAAA;EACA,gBAAA;EACA,gBAAA;ElC4uIL;AkCzvID;EAkBI,gBAAA;ElC0uIH;AmC9vID;EACE,uBAAA;EACA,iBAAA;EACA,gBAAA;EACA,oBAAA;EnCgwID;AmCpwID;EAOI,iBAAA;EnCgwIH;AmCvwID;;EAUM,oBAAA;EACA,aAAA;EACA,mBAAA;EACA,yBAAA;EACA,uBAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;EACA,mBAAA;EnCiwIL;AmC/vIG;;EAGI,gBAAA;EPXN,gCAAA;EACG,6BAAA;E5B4wIJ;AmC9vIG;;EPvBF,iCAAA;EACG,8BAAA;E5ByxIJ;AmCzvIG;;;;EAEE,gBAAA;EACA,2BAAA;EACA,uBAAA;EnC6vIL;AmCvvIG;;;;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,iBAAA;EnC4vIL;AmClzID;;;;;;EAiEM,gBAAA;EACA,2BAAA;EACA,uBAAA;EACA,qBAAA;EnCyvIL;AmChvID;;EC1EM,oBAAA;EACA,iBAAA;EpC8zIL;AoC5zIG;;ERMF,gCAAA;EACG,6BAAA;E5B0zIJ;AoC3zIG;;ERRF,iCAAA;EACG,8BAAA;E5Bu0IJ;AmC1vID;;EC/EM,mBAAA;EACA,iBAAA;EpC60IL;AoC30IG;;ERMF,gCAAA;EACG,6BAAA;E5By0IJ;AoC10IG;;ERRF,iCAAA;EACG,8BAAA;E5Bs1IJ;AqCz1ID;EACE,iBAAA;EACA,gBAAA;EACA,kBAAA;EACA,oBAAA;ErC21ID;AqC/1ID;EAOI,iBAAA;ErC21IH;AqCl2ID;;EAUM,uBAAA;EACA,mBAAA;EACA,2BAAA;EACA,2BAAA;EACA,qBAAA;ErC41IL;AqC12ID;;EAmBM,uBAAA;EACA,2BAAA;ErC21IL;AqC/2ID;;EA2BM,cAAA;ErCw1IL;AqCn3ID;;EAkCM,aAAA;ErCq1IL;AqCv3ID;;;;EA2CM,gBAAA;EACA,2BAAA;EACA,qBAAA;ErCk1IL;AsCh4ID;EACE,iBAAA;EACA,yBAAA;EACA,gBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,oBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sBAAA;EtCk4ID;AsC93IG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EtCg4IL;AsC33IC;EACE,eAAA;EtC63IH;AsCz3IC;EACE,oBAAA;EACA,WAAA;EtC23IH;AsCp3ID;ECtCE,2BAAA;EvC65ID;AuC15IG;;EAEE,2BAAA;EvC45IL;AsCv3ID;EC1CE,2BAAA;EvCo6ID;AuCj6IG;;EAEE,2BAAA;EvCm6IL;AsC13ID;EC9CE,2BAAA;EvC26ID;AuCx6IG;;EAEE,2BAAA;EvC06IL;AsC73ID;EClDE,2BAAA;EvCk7ID;AuC/6IG;;EAEE,2BAAA;EvCi7IL;AsCh4ID;ECtDE,2BAAA;EvCy7ID;AuCt7IG;;EAEE,2BAAA;EvCw7IL;AsCn4ID;EC1DE,2BAAA;EvCg8ID;AuC77IG;;EAEE,2BAAA;EvC+7IL;AwCj8ID;EACE,uBAAA;EACA,iBAAA;EACA,kBAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,0BAAA;EACA,qBAAA;EACA,oBAAA;EACA,2BAAA;EACA,qBAAA;ExCm8ID;AwCh8IC;EACE,eAAA;ExCk8IH;AwC97IC;EACE,oBAAA;EACA,WAAA;ExCg8IH;AwC97IC;EACE,QAAA;EACA,kBAAA;ExCg8IH;AwC37IG;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;ExC67IL;AwCx7IC;;EAEE,gBAAA;EACA,2BAAA;ExC07IH;AwCx7IC;EACE,cAAA;ExC07IH;AwCx7IC;EACE,mBAAA;ExC07IH;AwCx7IC;EACE,kBAAA;ExC07IH;AyC/+ID;EACE,oBAAA;EACA,qBAAA;EACA,gBAAA;EACA,2BAAA;EzCi/ID;AyCr/ID;;EAQI,gBAAA;EzCi/IH;AyCz/ID;EAWI,qBAAA;EACA,iBAAA;EACA,kBAAA;EzCi/IH;AyC9/ID;EAiBI,2BAAA;EzCg/IH;AyC7+IC;;EAEE,oBAAA;EzC++IH;AyCrgJD;EA0BI,iBAAA;EzC8+IH;AyC79ID;EAAA;IAbI,iBAAA;IzC8+ID;EyC5+IC;;IAEE,oBAAA;IACA,qBAAA;IzC8+IH;EyCt+IH;;IAHM,iBAAA;IzC6+IH;EACF;A0CrhJD;EACE,gBAAA;EACA,cAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;ErCiLA,6CAAA;EACK,wCAAA;EACG,qCAAA;ELu2IT;A0CjiJD;;EAaI,mBAAA;EACA,oBAAA;E1CwhJH;A0CphJC;;;EAGE,uBAAA;E1CshJH;A0C3iJD;EA0BI,cAAA;EACA,gBAAA;E1CohJH;A2C7iJD;EACE,eAAA;EACA,qBAAA;EACA,+BAAA;EACA,oBAAA;E3C+iJD;A2CnjJD;EAQI,eAAA;EAEA,gBAAA;E3C6iJH;A2CvjJD;EAcI,mBAAA;E3C4iJH;A2C1jJD;;EAoBI,kBAAA;E3C0iJH;A2C9jJD;EAuBI,iBAAA;E3C0iJH;A2CliJD;;EAEE,qBAAA;E3CoiJD;A2CtiJD;;EAMI,oBAAA;EACA,WAAA;EACA,cAAA;EACA,gBAAA;E3CoiJH;A2C5hJD;ECrDE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5ColJD;A2CjiJD;EChDI,2BAAA;E5ColJH;A2CpiJD;EC7CI,gBAAA;E5ColJH;A2CpiJD;ECxDE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C+lJD;A2CziJD;ECnDI,2BAAA;E5C+lJH;A2C5iJD;EChDI,gBAAA;E5C+lJH;A2C5iJD;EC3DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5C0mJD;A2CjjJD;ECtDI,2BAAA;E5C0mJH;A2CpjJD;ECnDI,gBAAA;E5C0mJH;A2CpjJD;EC9DE,2BAAA;EACA,uBAAA;EACA,gBAAA;E5CqnJD;A2CzjJD;ECzDI,2BAAA;E5CqnJH;A2C5jJD;ECtDI,gBAAA;E5CqnJH;A6CvnJD;EACE;IAAQ,6BAAA;I7C0nJP;E6CznJD;IAAQ,0BAAA;I7C4nJP;EACF;A6CznJD;EACE;IAAQ,6BAAA;I7C4nJP;E6C3nJD;IAAQ,0BAAA;I7C8nJP;EACF;A6CjoJD;EACE;IAAQ,6BAAA;I7C4nJP;E6C3nJD;IAAQ,0BAAA;I7C8nJP;EACF;A6CvnJD;EACE,kBAAA;EACA,cAAA;EACA,qBAAA;EACA,2BAAA;EACA,oBAAA;ExCsCA,wDAAA;EACQ,gDAAA;ELolJT;A6CtnJD;EACE,aAAA;EACA,WAAA;EACA,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2BAAA;ExCyBA,wDAAA;EACQ,gDAAA;EAyHR,qCAAA;EACK,gCAAA;EACG,6BAAA;ELw+IT;A6CnnJD;;ECCI,+MAAA;EACA,0MAAA;EACA,uMAAA;EDAF,oCAAA;UAAA,4BAAA;E7CunJD;A6ChnJD;;ExC5CE,4DAAA;EACK,uDAAA;EACG,oDAAA;ELgqJT;A6C7mJD;EErEE,2BAAA;E/CqrJD;A+ClrJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9CqoJH;A6CjnJD;EEzEE,2BAAA;E/C6rJD;A+C1rJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C6oJH;A6CrnJD;EE7EE,2BAAA;E/CqsJD;A+ClsJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9CqpJH;A6CznJD;EEjFE,2BAAA;E/C6sJD;A+C1sJC;EDgDE,+MAAA;EACA,0MAAA;EACA,uMAAA;E9C6pJH;AgDrtJD;EAEE,kBAAA;EhDstJD;AgDptJC;EACE,eAAA;EhDstJH;AgDltJD;;EAEE,oBAAA;EhDotJD;AgDjtJD;;EAEE,qBAAA;EhDmtJD;AgDhtJD;;;EAGE,qBAAA;EACA,qBAAA;EhDktJD;AgD/sJD;EACE,wBAAA;EhDitJD;AgD9sJD;EACE,wBAAA;EhDgtJD;AgD5sJD;EACE,eAAA;EACA,oBAAA;EhD8sJD;AgDxsJD;EACE,iBAAA;EACA,kBAAA;EhD0sJD;AiD9uJD;EAEE,qBAAA;EACA,iBAAA;EjD+uJD;AiDvuJD;EACE,oBAAA;EACA,gBAAA;EACA,oBAAA;EAEA,qBAAA;EACA,2BAAA;EACA,2BAAA;EjDwuJD;AiDruJC;ErB3BA,8BAAA;EACC,6BAAA;E5BmwJF;AiDtuJC;EACE,kBAAA;ErBvBF,iCAAA;EACC,gCAAA;E5BgwJF;AiD/tJD;EACE,gBAAA;EjDiuJD;AiDluJD;EAII,gBAAA;EjDiuJH;AiD7tJC;;EAEE,uBAAA;EACA,gBAAA;EACA,2BAAA;EjD+tJH;AiDztJC;;;EAGE,2BAAA;EACA,gBAAA;EACA,qBAAA;EjD2tJH;AiDhuJC;;;EASI,gBAAA;EjD4tJL;AiDruJC;;;EAYI,gBAAA;EjD8tJL;AiDztJC;;;EAGE,YAAA;EACA,gBAAA;EACA,2BAAA;EACA,uBAAA;EjD2tJH;AiDjuJC;;;;;;;;;EAYI,gBAAA;EjDguJL;AiD5uJC;;;EAeI,gBAAA;EjDkuJL;AkD9zJC;EACE,gBAAA;EACA,2BAAA;ElDg0JH;AkD9zJG;EACE,gBAAA;ElDg0JL;AkDj0JG;EAII,gBAAA;ElDg0JP;AkD7zJK;;EAEE,gBAAA;EACA,2BAAA;ElD+zJP;AkD7zJK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElD+zJP;AkDp1JC;EACE,gBAAA;EACA,2BAAA;ElDs1JH;AkDp1JG;EACE,gBAAA;ElDs1JL;AkDv1JG;EAII,gBAAA;ElDs1JP;AkDn1JK;;EAEE,gBAAA;EACA,2BAAA;ElDq1JP;AkDn1JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDq1JP;AkD12JC;EACE,gBAAA;EACA,2BAAA;ElD42JH;AkD12JG;EACE,gBAAA;ElD42JL;AkD72JG;EAII,gBAAA;ElD42JP;AkDz2JK;;EAEE,gBAAA;EACA,2BAAA;ElD22JP;AkDz2JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElD22JP;AkDh4JC;EACE,gBAAA;EACA,2BAAA;ElDk4JH;AkDh4JG;EACE,gBAAA;ElDk4JL;AkDn4JG;EAII,gBAAA;ElDk4JP;AkD/3JK;;EAEE,gBAAA;EACA,2BAAA;ElDi4JP;AkD/3JK;;;EAGE,aAAA;EACA,2BAAA;EACA,uBAAA;ElDi4JP;AiDryJD;EACE,eAAA;EACA,oBAAA;EjDuyJD;AiDryJD;EACE,kBAAA;EACA,kBAAA;EjDuyJD;AmD35JD;EACE,qBAAA;EACA,2BAAA;EACA,+BAAA;EACA,oBAAA;E9C0DA,mDAAA;EACQ,2CAAA;ELo2JT;AmD15JD;EACE,eAAA;EnD45JD;AmDv5JD;EACE,oBAAA;EACA,sCAAA;EvBpBA,8BAAA;EACC,6BAAA;E5B86JF;AmD75JD;EAMI,gBAAA;EnD05JH;AmDr5JD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,gBAAA;EnDu5JD;AmD35JD;EAOI,gBAAA;EnDu5JH;AmDl5JD;EACE,oBAAA;EACA,2BAAA;EACA,+BAAA;EvBpCA,iCAAA;EACC,gCAAA;E5By7JF;AmD54JD;;EAGI,kBAAA;EnD64JH;AmDh5JD;;EAMM,qBAAA;EACA,kBAAA;EnD84JL;AmD14JG;;EAEI,eAAA;EvBnEN,8BAAA;EACC,6BAAA;E5Bg9JF;AmDz4JG;;EAEI,kBAAA;EvBlEN,iCAAA;EACC,gCAAA;E5B88JF;AmDt4JD;EAEI,qBAAA;EnDu4JH;AmDp4JD;EACE,qBAAA;EnDs4JD;AmD93JD;;;EAII,kBAAA;EnD+3JH;AmDn4JD;;;EAOM,oBAAA;EACA,qBAAA;EnDi4JL;AmDz4JD;;EvB/FE,8BAAA;EACC,6BAAA;E5B4+JF;AmD94JD;;;;EAmBQ,6BAAA;EACA,8BAAA;EnDi4JP;AmDr5JD;;;;;;;;EAwBU,6BAAA;EnDu4JT;AmD/5JD;;;;;;;;EA4BU,8BAAA;EnD64JT;AmDz6JD;;EvBvFE,iCAAA;EACC,gCAAA;E5BogKF;AmD96JD;;;;EAyCQ,gCAAA;EACA,iCAAA;EnD24JP;AmDr7JD;;;;;;;;EA8CU,gCAAA;EnDi5JT;AmD/7JD;;;;;;;;EAkDU,iCAAA;EnDu5JT;AmDz8JD;;;;EA2DI,+BAAA;EnDo5JH;AmD/8JD;;EA+DI,eAAA;EnDo5JH;AmDn9JD;;EAmEI,WAAA;EnDo5JH;AmDv9JD;;;;;;;;;;;;EA0EU,gBAAA;EnD25JT;AmDr+JD;;;;;;;;;;;;EA8EU,iBAAA;EnDq6JT;AmDn/JD;;;;;;;;EAuFU,kBAAA;EnDs6JT;AmD7/JD;;;;;;;;EAgGU,kBAAA;EnDu6JT;AmDvgKD;EAsGI,WAAA;EACA,kBAAA;EnDo6JH;AmD15JD;EACE,qBAAA;EnD45JD;AmD75JD;EAKI,kBAAA;EACA,oBAAA;EnD25JH;AmDj6JD;EASM,iBAAA;EnD25JL;AmDp6JD;EAcI,kBAAA;EnDy5JH;AmDv6JD;;EAkBM,+BAAA;EnDy5JL;AmD36JD;EAuBI,eAAA;EnDu5JH;AmD96JD;EAyBM,kCAAA;EnDw5JL;AmDj5JD;EChPE,uBAAA;EpDooKD;AoDloKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDooKH;AoDvoKC;EAMI,2BAAA;EpDooKL;AoD1oKC;EASI,gBAAA;EACA,2BAAA;EpDooKL;AoDjoKC;EAEI,8BAAA;EpDkoKL;AmDh6JD;ECnPE,uBAAA;EpDspKD;AoDppKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDspKH;AoDzpKC;EAMI,2BAAA;EpDspKL;AoD5pKC;EASI,gBAAA;EACA,2BAAA;EpDspKL;AoDnpKC;EAEI,8BAAA;EpDopKL;AmD/6JD;ECtPE,uBAAA;EpDwqKD;AoDtqKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpDwqKH;AoD3qKC;EAMI,2BAAA;EpDwqKL;AoD9qKC;EASI,gBAAA;EACA,2BAAA;EpDwqKL;AoDrqKC;EAEI,8BAAA;EpDsqKL;AmD97JD;ECzPE,uBAAA;EpD0rKD;AoDxrKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD0rKH;AoD7rKC;EAMI,2BAAA;EpD0rKL;AoDhsKC;EASI,gBAAA;EACA,2BAAA;EpD0rKL;AoDvrKC;EAEI,8BAAA;EpDwrKL;AmD78JD;EC5PE,uBAAA;EpD4sKD;AoD1sKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD4sKH;AoD/sKC;EAMI,2BAAA;EpD4sKL;AoDltKC;EASI,gBAAA;EACA,2BAAA;EpD4sKL;AoDzsKC;EAEI,8BAAA;EpD0sKL;AmD59JD;EC/PE,uBAAA;EpD8tKD;AoD5tKC;EACE,gBAAA;EACA,2BAAA;EACA,uBAAA;EpD8tKH;AoDjuKC;EAMI,2BAAA;EpD8tKL;AoDpuKC;EASI,gBAAA;EACA,2BAAA;EpD8tKL;AoD3tKC;EAEI,8BAAA;EpD4tKL;AqD5uKD;EACE,oBAAA;EACA,gBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;ErD8uKD;AqDnvKD;;;;;EAYI,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,cAAA;EACA,aAAA;EACA,WAAA;ErD8uKH;AqD1uKC;EACE,wBAAA;ErD4uKH;AqDxuKC;EACE,qBAAA;ErD0uKH;AsDpwKD;EACE,kBAAA;EACA,eAAA;EACA,qBAAA;EACA,2BAAA;EACA,2BAAA;EACA,oBAAA;EjDwDA,yDAAA;EACQ,iDAAA;EL+sKT;AsD9wKD;EASI,oBAAA;EACA,mCAAA;EtDwwKH;AsDnwKD;EACE,eAAA;EACA,oBAAA;EtDqwKD;AsDnwKD;EACE,cAAA;EACA,oBAAA;EtDqwKD;AuD3xKD;EACE,cAAA;EACA,iBAAA;EACA,mBAAA;EACA,gBAAA;EACA,gBAAA;EACA,8BAAA;EjCRA,cAAA;EAGA,2BAAA;EtBoyKD;AuD5xKC;;EAEE,gBAAA;EACA,uBAAA;EACA,iBAAA;EjCfF,cAAA;EAGA,2BAAA;EtB4yKD;AuDzxKC;EACE,YAAA;EACA,iBAAA;EACA,yBAAA;EACA,WAAA;EACA,0BAAA;EvD2xKH;AwD/yKD;EACE,kBAAA;ExDizKD;AwD7yKD;EACE,eAAA;EACA,kBAAA;EACA,iBAAA;EACA,QAAA;EACA,UAAA;EACA,WAAA;EACA,SAAA;EACA,eAAA;EACA,mCAAA;EAIA,YAAA;ExD4yKD;AwDzyKC;EnD+GA,uCAAA;EACI,mCAAA;EACC,kCAAA;EACG,+BAAA;EAkER,qDAAA;EAEK,2CAAA;EACG,qCAAA;EL4nKT;AwD/yKC;EnD2GA,oCAAA;EACI,gCAAA;EACC,+BAAA;EACG,4BAAA;ELusKT;AwDnzKD;EACE,oBAAA;EACA,kBAAA;ExDqzKD;AwDjzKD;EACE,oBAAA;EACA,aAAA;EACA,cAAA;ExDmzKD;AwD/yKD;EACE,oBAAA;EACA,2BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;EnDaA,kDAAA;EACQ,0CAAA;EmDZR,sCAAA;UAAA,8BAAA;EAEA,YAAA;ExDizKD;AwD7yKD;EACE,oBAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,2BAAA;ExD+yKD;AwD7yKC;ElCnEA,YAAA;EAGA,0BAAA;EtBi3KD;AwDhzKC;ElCpEA,cAAA;EAGA,2BAAA;EtBq3KD;AwD/yKD;EACE,eAAA;EACA,kCAAA;EACA,2BAAA;ExDizKD;AwD9yKD;EACE,kBAAA;ExDgzKD;AwD5yKD;EACE,WAAA;EACA,yBAAA;ExD8yKD;AwDzyKD;EACE,oBAAA;EACA,eAAA;ExD2yKD;AwDvyKD;EACE,eAAA;EACA,mBAAA;EACA,+BAAA;ExDyyKD;AwD5yKD;EAQI,kBAAA;EACA,kBAAA;ExDuyKH;AwDhzKD;EAaI,mBAAA;ExDsyKH;AwDnzKD;EAiBI,gBAAA;ExDqyKH;AwDhyKD;EACE,oBAAA;EACA,cAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAA;ExDkyKD;AwDhxKD;EAZE;IACE,cAAA;IACA,mBAAA;IxD+xKD;EwD7xKD;InDrEA,mDAAA;IACQ,2CAAA;ILq2KP;EwD5xKD;IAAY,cAAA;IxD+xKX;EACF;AwD1xKD;EAFE;IAAY,cAAA;IxDgyKX;EACF;AyD76KD;EACE,oBAAA;EACA,eAAA;EACA,gBAAA;EACA,qBAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,kBAAA;EnCZA,YAAA;EAGA,0BAAA;EtBy7KD;AyD76KC;EnCfA,cAAA;EAGA,2BAAA;EtB67KD;AyDh7KC;EAAW,kBAAA;EAAmB,gBAAA;EzDo7K/B;AyDn7KC;EAAW,kBAAA;EAAmB,gBAAA;EzDu7K/B;AyDt7KC;EAAW,iBAAA;EAAmB,gBAAA;EzD07K/B;AyDz7KC;EAAW,mBAAA;EAAmB,gBAAA;EzD67K/B;AyDz7KD;EACE,kBAAA;EACA,kBAAA;EACA,gBAAA;EACA,oBAAA;EACA,uBAAA;EACA,2BAAA;EACA,oBAAA;EzD27KD;AyDv7KD;EACE,oBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;EzDy7KD;AyDr7KC;EACE,WAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,WAAA;EACA,YAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,WAAA;EACA,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,2BAAA;EzDu7KH;AyDr7KC;EACE,UAAA;EACA,SAAA;EACA,kBAAA;EACA,6BAAA;EACA,6BAAA;EzDu7KH;AyDr7KC;EACE,UAAA;EACA,UAAA;EACA,kBAAA;EACA,6BAAA;EACA,4BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,WAAA;EACA,mBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,YAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;AyDr7KC;EACE,QAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;EACA,8BAAA;EzDu7KH;A0DthLD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,eAAA;EACA,eAAA;EACA,kBAAA;EACA,cAAA;EAEA,6DAAA;EACA,iBAAA;EACA,qBAAA;EACA,yBAAA;EACA,kBAAA;EACA,2BAAA;EACA,sCAAA;UAAA,8BAAA;EACA,2BAAA;EACA,sCAAA;EACA,oBAAA;ErD6CA,mDAAA;EACQ,2CAAA;EqD1CR,qBAAA;E1DshLD;A0DnhLC;EAAY,mBAAA;E1DshLb;A0DrhLC;EAAY,mBAAA;E1DwhLb;A0DvhLC;EAAY,kBAAA;E1D0hLb;A0DzhLC;EAAY,oBAAA;E1D4hLb;A0DzhLD;EACE,WAAA;EACA,mBAAA;EACA,iBAAA;EACA,2BAAA;EACA,kCAAA;EACA,4BAAA;E1D2hLD;A0DxhLD;EACE,mBAAA;E1D0hLD;A0DlhLC;;EAEE,oBAAA;EACA,gBAAA;EACA,UAAA;EACA,WAAA;EACA,2BAAA;EACA,qBAAA;E1DohLH;A0DjhLD;EACE,oBAAA;E1DmhLD;A0DjhLD;EACE,oBAAA;EACA,aAAA;E1DmhLD;A0D/gLC;EACE,WAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;EACA,uCAAA;EACA,eAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,aAAA;EACA,oBAAA;EACA,wBAAA;EACA,2BAAA;E1DkhLL;A0D/gLC;EACE,UAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,6BAAA;EACA,yCAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,WAAA;EACA,eAAA;EACA,sBAAA;EACA,6BAAA;E1DkhLL;A0D/gLC;EACE,WAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;EACA,0CAAA;EACA,YAAA;E1DihLH;A0DhhLG;EACE,cAAA;EACA,UAAA;EACA,oBAAA;EACA,qBAAA;EACA,8BAAA;E1DkhLL;A0D9gLC;EACE,UAAA;EACA,cAAA;EACA,mBAAA;EACA,uBAAA;EACA,4BAAA;EACA,wCAAA;E1DghLH;A0D/gLG;EACE,cAAA;EACA,YAAA;EACA,uBAAA;EACA,4BAAA;EACA,eAAA;E1DihLL;A2D9oLD;EACE,oBAAA;E3DgpLD;A2D7oLD;EACE,oBAAA;EACA,kBAAA;EACA,aAAA;E3D+oLD;A2DlpLD;EAMI,eAAA;EACA,oBAAA;EtD6KF,2CAAA;EACK,sCAAA;EACG,mCAAA;ELm+KT;A2DzpLD;;EAcM,gBAAA;E3D+oLL;A2DrnLC;EAAA;IArBI,wDAAA;SAAA,8CAAA;YAAA,wCAAA;IACA,qCAAA;YAAA,6BAAA;IACA,2BAAA;YAAA,mBAAA;I3D8oLH;E2D5oLG;;IAEE,4CAAA;YAAA,oCAAA;IACA,SAAA;I3D8oLL;E2D5oLG;;IAEE,6CAAA;YAAA,qCAAA;IACA,SAAA;I3D8oLL;E2D5oLG;;;IAGE,yCAAA;YAAA,iCAAA;IACA,SAAA;I3D8oLL;EACF;A2DprLD;;;EA6CI,gBAAA;E3D4oLH;A2DzrLD;EAiDI,SAAA;E3D2oLH;A2D5rLD;;EAsDI,oBAAA;EACA,QAAA;EACA,aAAA;E3D0oLH;A2DlsLD;EA4DI,YAAA;E3DyoLH;A2DrsLD;EA+DI,aAAA;E3DyoLH;A2DxsLD;;EAmEI,SAAA;E3DyoLH;A2D5sLD;EAuEI,aAAA;E3DwoLH;A2D/sLD;EA0EI,YAAA;E3DwoLH;A2DhoLD;EACE,oBAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;ErC9FA,cAAA;EAGA,2BAAA;EqC6FA,iBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3DmoLD;A2D9nLC;EblGE,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9CmuLH;A2DloLC;EACE,YAAA;EACA,UAAA;EbvGA,oGAAA;EACA,+FAAA;EACA,sHAAA;EAAA,gGAAA;EACA,6BAAA;EACA,wHAAA;E9C4uLH;A2DpoLC;;EAEE,YAAA;EACA,gBAAA;EACA,uBAAA;ErCtHF,cAAA;EAGA,2BAAA;EtB2vLD;A2DrqLD;;;;EAsCI,oBAAA;EACA,UAAA;EACA,YAAA;EACA,uBAAA;E3DqoLH;A2D9qLD;;EA6CI,WAAA;EACA,oBAAA;E3DqoLH;A2DnrLD;;EAkDI,YAAA;EACA,qBAAA;E3DqoLH;A2DxrLD;;EAuDI,aAAA;EACA,cAAA;EACA,mBAAA;EACA,oBAAA;E3DqoLH;A2DhoLG;EACE,kBAAA;E3DkoLL;A2D9nLG;EACE,kBAAA;E3DgoLL;A2DtnLD;EACE,oBAAA;EACA,cAAA;EACA,WAAA;EACA,aAAA;EACA,YAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,oBAAA;E3DwnLD;A2DjoLD;EAYI,uBAAA;EACA,aAAA;EACA,cAAA;EACA,aAAA;EACA,qBAAA;EACA,2BAAA;EACA,qBAAA;EACA,iBAAA;EAUA,2BAAA;EACA,oCAAA;E3D+mLH;A2D7oLD;EAiCI,WAAA;EACA,aAAA;EACA,cAAA;EACA,2BAAA;E3D+mLH;A2DxmLD;EACE,oBAAA;EACA,WAAA;EACA,YAAA;EACA,cAAA;EACA,aAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,oBAAA;EACA,2CAAA;E3D0mLD;A2DzmLC;EACE,mBAAA;E3D2mLH;A2DlkLD;EAhCE;;;;IAKI,aAAA;IACA,cAAA;IACA,mBAAA;IACA,iBAAA;I3DomLH;E2D5mLD;;IAYI,oBAAA;I3DomLH;E2DhnLD;;IAgBI,qBAAA;I3DomLH;E2D/lLD;IACE,WAAA;IACA,YAAA;IACA,sBAAA;I3DimLD;E2D7lLD;IACE,cAAA;I3D+lLD;EACF;A4D31LC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEE,cAAA;EACA,gBAAA;E5Dy3LH;A4Dv3LC;;;;;;;;;;;;;;;EACE,aAAA;E5Du4LH;AiC/4LD;E4BRE,gBAAA;EACA,mBAAA;EACA,oBAAA;E7D05LD;AiCj5LD;EACE,yBAAA;EjCm5LD;AiCj5LD;EACE,wBAAA;EjCm5LD;AiC34LD;EACE,0BAAA;EjC64LD;AiC34LD;EACE,2BAAA;EjC64LD;AiC34LD;EACE,oBAAA;EjC64LD;AiC34LD;E6BzBE,aAAA;EACA,oBAAA;EACA,mBAAA;EACA,+BAAA;EACA,WAAA;E9Du6LD;AiCz4LD;EACE,0BAAA;EACA,+BAAA;EjC24LD;AiCp4LD;EACE,iBAAA;EjCs4LD;A+Dx6LD;EACE,qBAAA;E/D06LD;A+Dp6LD;;;;ECdE,0BAAA;EhEw7LD;A+Dn6LD;;;;;;;;;;;;EAYE,0BAAA;E/Dq6LD;A+D95LD;EAAA;IChDE,2BAAA;IhEk9LC;EgEj9LD;IAAU,gBAAA;IhEo9LT;EgEn9LD;IAAU,+BAAA;IhEs9LT;EgEr9LD;;IACU,gCAAA;IhEw9LT;EACF;A+Dx6LD;EAAA;IAFI,2BAAA;I/D86LD;EACF;A+Dx6LD;EAAA;IAFI,4BAAA;I/D86LD;EACF;A+Dx6LD;EAAA;IAFI,kCAAA;I/D86LD;EACF;A+Dv6LD;EAAA;ICrEE,2BAAA;IhEg/LC;EgE/+LD;IAAU,gBAAA;IhEk/LT;EgEj/LD;IAAU,+BAAA;IhEo/LT;EgEn/LD;;IACU,gCAAA;IhEs/LT;EACF;A+Dj7LD;EAAA;IAFI,2BAAA;I/Du7LD;EACF;A+Dj7LD;EAAA;IAFI,4BAAA;I/Du7LD;EACF;A+Dj7LD;EAAA;IAFI,kCAAA;I/Du7LD;EACF;A+Dh7LD;EAAA;IC1FE,2BAAA;IhE8gMC;EgE7gMD;IAAU,gBAAA;IhEghMT;EgE/gMD;IAAU,+BAAA;IhEkhMT;EgEjhMD;;IACU,gCAAA;IhEohMT;EACF;A+D17LD;EAAA;IAFI,2BAAA;I/Dg8LD;EACF;A+D17LD;EAAA;IAFI,4BAAA;I/Dg8LD;EACF;A+D17LD;EAAA;IAFI,kCAAA;I/Dg8LD;EACF;A+Dz7LD;EAAA;IC/GE,2BAAA;IhE4iMC;EgE3iMD;IAAU,gBAAA;IhE8iMT;EgE7iMD;IAAU,+BAAA;IhEgjMT;EgE/iMD;;IACU,gCAAA;IhEkjMT;EACF;A+Dn8LD;EAAA;IAFI,2BAAA;I/Dy8LD;EACF;A+Dn8LD;EAAA;IAFI,4BAAA;I/Dy8LD;EACF;A+Dn8LD;EAAA;IAFI,kCAAA;I/Dy8LD;EACF;A+Dl8LD;EAAA;IC5HE,0BAAA;IhEkkMC;EACF;A+Dl8LD;EAAA;ICjIE,0BAAA;IhEukMC;EACF;A+Dl8LD;EAAA;ICtIE,0BAAA;IhE4kMC;EACF;A+Dl8LD;EAAA;IC3IE,0BAAA;IhEilMC;EACF;A+D/7LD;ECnJE,0BAAA;EhEqlMD;A+D57LD;EAAA;ICjKE,2BAAA;IhEimMC;EgEhmMD;IAAU,gBAAA;IhEmmMT;EgElmMD;IAAU,+BAAA;IhEqmMT;EgEpmMD;;IACU,gCAAA;IhEumMT;EACF;A+D18LD;EACE,0BAAA;E/D48LD;A+Dv8LD;EAAA;IAFI,2BAAA;I/D68LD;EACF;A+D38LD;EACE,0BAAA;E/D68LD;A+Dx8LD;EAAA;IAFI,4BAAA;I/D88LD;EACF;A+D58LD;EACE,0BAAA;E/D88LD;A+Dz8LD;EAAA;IAFI,kCAAA;I/D+8LD;EACF;A+Dx8LD;EAAA;ICpLE,0BAAA;IhEgoMC;EACF","file":"bootstrap.css","sourcesContent":["/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: 1px dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important;\n box-shadow: none !important;\n text-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n select {\n background: #fff !important;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('../fonts/glyphicons-halflings-regular.eot');\n src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\2a\";\n}\n.glyphicon-plus:before {\n content: \"\\2b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #ffffff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: normal;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n background-color: #fcf8e3;\n padding: .2em;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted #777777;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n text-align: right;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: '\\00A0 \\2014';\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #ffffff;\n background-color: #333333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n word-break: break-all;\n word-wrap: break-word;\n color: #333333;\n background-color: #f5f5f5;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n margin-right: auto;\n margin-left: auto;\n padding-left: 15px;\n padding-right: 15px;\n}\n.row {\n margin-left: -15px;\n margin-right: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-left: 15px;\n padding-right: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #dddddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #dddddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #dddddd;\n}\n.table .table {\n background-color: #ffffff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #dddddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-child(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-column;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n float: none;\n display: table-cell;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #dddddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n min-width: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: bold;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #ffffff;\n background-image: none;\n border: 1px solid #cccccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999999;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n background-color: #eeeeee;\n opacity: 1;\n}\ntextarea.form-control {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.form-control-static {\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-left: 0;\n padding-right: 0;\n}\n.input-sm,\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm,\nselect.form-group-sm .form-control {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\ntextarea.form-group-sm .form-control,\nselect[multiple].input-sm,\nselect[multiple].form-group-sm .form-control {\n height: auto;\n}\n.input-lg,\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\nselect.input-lg,\nselect.form-group-lg .form-control {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\ntextarea.form-group-lg .form-control,\nselect[multiple].input-lg,\nselect[multiple].form-group-lg .form-control {\n height: auto;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n border-color: #3c763d;\n background-color: #dff0d8;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n border-color: #8a6d3b;\n background-color: #fcf8e3;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n border-color: #a94442;\n background-color: #f2dede;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: 7px;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-left: -15px;\n margin-right: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: 7px;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 14.3px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n white-space: nowrap;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: thin dotted;\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n outline: 0;\n background-image: none;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n pointer-events: none;\n opacity: 0.65;\n filter: alpha(opacity=65);\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-default {\n color: #333333;\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default:hover,\n.btn-default:focus,\n.btn-default.focus,\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n background-image: none;\n}\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n background-color: #ffffff;\n border-color: #cccccc;\n}\n.btn-default .badge {\n color: #ffffff;\n background-color: #333333;\n}\n.btn-primary {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary.focus,\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #ffffff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n background-image: none;\n}\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.btn-success {\n color: #ffffff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:hover,\n.btn-success:focus,\n.btn-success.focus,\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #ffffff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n background-image: none;\n}\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #ffffff;\n}\n.btn-info {\n color: #ffffff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:hover,\n.btn-info:focus,\n.btn-info.focus,\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #ffffff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n background-image: none;\n}\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #ffffff;\n}\n.btn-warning {\n color: #ffffff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning.focus,\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #ffffff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n background-image: none;\n}\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #ffffff;\n}\n.btn-danger {\n color: #ffffff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger.focus,\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #ffffff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n background-image: none;\n}\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #ffffff;\n}\n.btn-link {\n color: #337ab7;\n font-weight: normal;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n visibility: hidden;\n}\n.collapse.in {\n display: block;\n visibility: visible;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n text-align: left;\n background-color: #ffffff;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n text-decoration: none;\n color: #262626;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #ffffff;\n text-decoration: none;\n outline: 0;\n background-color: #337ab7;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n cursor: not-allowed;\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n left: auto;\n right: 0;\n}\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n border-top: 0;\n border-bottom: 4px solid;\n content: \"\";\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n left: auto;\n right: 0;\n }\n .navbar-right .dropdown-menu-left {\n left: 0;\n right: auto;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child > .btn:last-child,\n.btn-group > .btn-group:first-child > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-bottom-left-radius: 4px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.33;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: normal;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #cccccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n margin-left: -1px;\n}\n.nav {\n margin-bottom: 0;\n padding-left: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #dddddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #dddddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-bottom-color: transparent;\n cursor: default;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #ffffff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n text-align: center;\n margin-bottom: 5px;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #dddddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #dddddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #ffffff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n visibility: hidden;\n}\n.tab-content > .active {\n display: block;\n visibility: visible;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n overflow-x: visible;\n padding-right: 15px;\n padding-left: 15px;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n visibility: visible !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-left: 0;\n padding-right: 0;\n }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.navbar-brand {\n float: left;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n height: 50px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: 15px;\n padding: 9px 10px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n margin-left: -15px;\n margin-right: -15px;\n padding: 10px 15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-right-radius: 0;\n border-top-left-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-left: 15px;\n margin-right: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n border-color: #dddddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #dddddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n background-color: #e7e7e7;\n color: #555555;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #cccccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-link {\n color: #777777;\n}\n.navbar-default .navbar-link:hover {\n color: #333333;\n}\n.navbar-default .btn-link {\n color: #777777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #cccccc;\n}\n.navbar-inverse {\n background-color: #222222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #ffffff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n background-color: #080808;\n color: #ffffff;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #ffffff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #ffffff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #ffffff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #ffffff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n content: \"/\\00a0\";\n padding: 0 5px;\n color: #cccccc;\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n line-height: 1.42857143;\n text-decoration: none;\n color: #337ab7;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n margin-left: -1px;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-bottom-left-radius: 4px;\n border-top-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-bottom-right-radius: 4px;\n border-top-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n color: #23527c;\n background-color: #eeeeee;\n border-color: #dddddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n cursor: default;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n background-color: #ffffff;\n border-color: #dddddd;\n cursor: not-allowed;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-bottom-left-radius: 3px;\n border-top-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-bottom-right-radius: 3px;\n border-top-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n list-style: none;\n text-align: center;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n background-color: #ffffff;\n cursor: not-allowed;\n}\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: #ffffff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n color: #ffffff;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #ffffff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding: 30px 15px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding: 48px 0;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-left: 60px;\n padding-right: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-left: auto;\n margin-right: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n background-color: #dff0d8;\n border-color: #d6e9c6;\n color: #3c763d;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n background-color: #d9edf7;\n border-color: #bce8f1;\n color: #31708f;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n background-color: #fcf8e3;\n border-color: #faebcc;\n color: #8a6d3b;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n background-color: #f2dede;\n border-color: #ebccd1;\n color: #a94442;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n overflow: hidden;\n height: 20px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #ffffff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n 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);\n 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);\n 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);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n 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);\n 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);\n 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);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n 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);\n 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);\n 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);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n 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);\n 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);\n 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);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n 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);\n 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);\n 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);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n margin-bottom: 20px;\n padding-left: 0;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #ffffff;\n border: 1px solid #dddddd;\n}\n.list-group-item:first-child {\n border-top-right-radius: 4px;\n border-top-left-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\na.list-group-item {\n color: #555555;\n}\na.list-group-item .list-group-item-heading {\n color: #333333;\n}\na.list-group-item:hover,\na.list-group-item:focus {\n text-decoration: none;\n color: #555555;\n background-color: #f5f5f5;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n background-color: #eeeeee;\n color: #777777;\n cursor: not-allowed;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\na.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\na.list-group-item-success.active:hover,\na.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\na.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\na.list-group-item-info.active:hover,\na.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\na.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\na.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #ffffff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #dddddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-left: 15px;\n padding-right: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-right-radius: 3px;\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-left-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #dddddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n border: 0;\n margin-bottom: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #dddddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #dddddd;\n}\n.panel-default {\n border-color: #dddddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #dddddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #dddddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #dddddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #ffffff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #ffffff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n}\n.embed-responsive.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: 0;\n}\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n visibility: visible;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 12px;\n font-weight: normal;\n line-height: 1.4;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.tooltip.in {\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.tooltip.top {\n margin-top: -3px;\n padding: 5px 0;\n}\n.tooltip.right {\n margin-left: 3px;\n padding: 0 5px;\n}\n.tooltip.bottom {\n margin-top: 3px;\n padding: 5px 0;\n}\n.tooltip.left {\n margin-left: -3px;\n padding: 0 5px;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #ffffff;\n text-align: center;\n text-decoration: none;\n background-color: #000000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-left .tooltip-arrow {\n bottom: 0;\n right: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000000;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n font-weight: normal;\n line-height: 1.42857143;\n text-align: left;\n background-color: #ffffff;\n background-clip: padding-box;\n border: 1px solid #cccccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n white-space: normal;\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover-title {\n margin: 0;\n padding: 8px 14px;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow:after {\n border-width: 10px;\n content: \"\";\n}\n.popover.top > .arrow {\n left: 50%;\n margin-left: -11px;\n border-bottom-width: 0;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n bottom: -11px;\n}\n.popover.top > .arrow:after {\n content: \" \";\n bottom: 1px;\n margin-left: -10px;\n border-bottom-width: 0;\n border-top-color: #ffffff;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-left-width: 0;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n}\n.popover.right > .arrow:after {\n content: \" \";\n left: 1px;\n bottom: -10px;\n border-left-width: 0;\n border-right-color: #ffffff;\n}\n.popover.bottom > .arrow {\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n top: -11px;\n}\n.popover.bottom > .arrow:after {\n content: \" \";\n top: 1px;\n margin-left: -10px;\n border-top-width: 0;\n border-bottom-color: #ffffff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: #ffffff;\n bottom: -10px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n}\n.carousel-inner > .item {\n display: none;\n position: relative;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n transition: transform 0.6s ease-in-out;\n backface-visibility: hidden;\n perspective: 1000;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 15%;\n opacity: 0.5;\n filter: alpha(opacity=50);\n font-size: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n.carousel-control.right {\n left: auto;\n right: 0;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-repeat: repeat-x;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n.carousel-control:hover,\n.carousel-control:focus {\n outline: 0;\n color: #ffffff;\n text-decoration: none;\n opacity: 0.9;\n filter: alpha(opacity=90);\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n font-family: serif;\n}\n.carousel-control .icon-prev:before {\n content: '\\2039';\n}\n.carousel-control .icon-next:before {\n content: '\\203a';\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid #ffffff;\n border-radius: 10px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n}\n.carousel-indicators .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: #ffffff;\n}\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #ffffff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -15px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -15px;\n }\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-footer:before,\n.modal-footer:after {\n content: \" \";\n display: table;\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */","/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n// user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n// (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box; // 2\n box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n background: transparent !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n box-shadow: none !important;\n text-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n //\n // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n // Once fixed, we can just straight up remove this.\n select {\n background: #fff !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n // Bootstrap specific changes end\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // See https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: bold;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-child(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n overflow-x: auto;\n min-height: 0.01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned. As a workaround, we\n// set a pixel line-height that matches the given height of the input, but only\n// for Safari.\n\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"],\n input[type=\"time\"],\n input[type=\"datetime-local\"],\n input[type=\"month\"] {\n line-height: @input-height-base;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm {\n line-height: @input-height-small;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg {\n line-height: @input-height-large;\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because <label>s don't inherit their parent's `cursor`.\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n &[disabled],\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used directly on <label>s\n.radio-inline,\n.checkbox-inline {\n &.disabled,\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n }\n}\n// These classes are used on elements with <label> descendants\n.radio,\n.checkbox {\n &.disabled,\n fieldset[disabled] & {\n label {\n cursor: @cursor-disabled;\n }\n }\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n // Size it appropriately next to real form controls\n padding-top: (@padding-base-vertical + 1);\n padding-bottom: (@padding-base-vertical + 1);\n // Remove default margin from `p`\n margin-bottom: 0;\n\n &.input-lg,\n &.input-sm {\n padding-left: 0;\n padding-right: 0;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm,\n.form-group-sm .form-control {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);\n}\n\n.input-lg,\n.form-group-lg .form-control {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n}\n// Feedback icon (requires .glyphicon classes)\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2; // Ensure icon is above input groups\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback {\n width: @input-height-large;\n height: @input-height-large;\n line-height: @input-height-large;\n}\n.input-sm + .form-control-feedback {\n width: @input-height-small;\n height: @input-height-small;\n line-height: @input-height-small;\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n// Reposition feedback icon if input has visible label above\n.has-feedback label {\n\n & ~ .form-control-feedback {\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n }\n &.sr-only ~ .form-control-feedback {\n top: 0;\n }\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n\n // Make static controls behave like regular ones\n .form-control-static {\n display: inline-block;\n }\n\n .input-group {\n display: inline-table;\n vertical-align: middle;\n\n .input-group-addon,\n .input-group-btn,\n .form-control {\n width: auto;\n }\n }\n\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match (which also avoids\n // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n\n label {\n padding-left: 0;\n }\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n\n // Re-override the feedback icon.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of radios and checkboxes\n //\n // Labels also get some reset styles, but that is scoped to a media query below.\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n // Reset spacing and right align labels, but scope to media queries so that\n // labels on narrow viewports stack the same as a default form example.\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n right: (@grid-gutter-width / 2);\n }\n\n // Form group sizes\n //\n // Quick utility class for applying `.input-lg` and `.input-sm` styles to the\n // inputs and labels within a `.form-group`.\n .form-group-lg {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: ((@padding-large-vertical * @line-height-large) + 1);\n }\n }\n }\n .form-group-sm {\n @media (min-width: @screen-sm-min) {\n .control-label {\n padding-top: (@padding-small-vertical + 1);\n }\n }\n }\n}\n","// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline,\n &.radio label,\n &.checkbox label,\n &.radio-inline label,\n &.checkbox-inline label {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-border-focus` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus,\n &.focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus,\n &.focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: @cursor-disabled;\n pointer-events: none; // Future-proof disabling of clicks\n .opacity(.65);\n .box-shadow(none);\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n border-radius: 0;\n\n &,\n &:active,\n &.active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: underline;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","// Button variants\n//\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 10%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open > .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &.focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n","// Opacity\n\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n visibility: hidden;\n\n &.in { display: block; visibility: visible; }\n tr&.in { display: table-row; }\n tbody&.in { display: table-row-group; }\n}\n\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition-property(~\"height, visibility\");\n .transition-duration(.35s);\n .transition-timing-function(ease);\n}\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base solid;\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n\n // Nuke hover/focus effects\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: @cursor-disabled;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n white-space: nowrap; // as with > li > a\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base solid;\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n","// Horizontal dividers\n//\n// Dividers (basically an hr) within dropdowns and nav lists\n\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n border-top-right-radius: @border-radius-base;\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n border-bottom-left-radius: @border-radius-base;\n .border-top-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n\n > .btn-group .dropdown-menu {\n left: auto;\n }\n}\n\n\n// Checkbox and radio options\n//\n// In order to support the browser's form validation feedback, powered by the\n// `required` attribute, we have to \"hide\" the inputs via `clip`. We cannot use\n// `display: none;` or `visibility: hidden;` as that also hides the popover.\n// Simply visually hiding the inputs via `opacity` would leave them clickable in\n// certain cases which is prevented by using `clip` and `pointer-events`.\n// This way, we ensure a DOM element is visible to position the popover from.\n//\n// See https://github.com/twbs/bootstrap/pull/12794 and\n// https://github.com/twbs/bootstrap/pull/14559 for more information.\n\n[data-toggle=\"buttons\"] {\n > .btn,\n > .btn-group > .btn {\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0,0,0,0);\n pointer-events: none;\n }\n }\n}\n","// Single side border-radius\n\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n .input-lg();\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n .input-sm();\n}\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @border-radius-base;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: @cursor-disabled;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n visibility: hidden;\n }\n > .active {\n display: block;\n visibility: visible;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n visibility: visible !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n .navbar-collapse {\n max-height: @navbar-collapse-max-height;\n\n @media (max-device-width: @screen-xs-min) and (orientation: landscape) {\n max-height: 200px;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n > img {\n display: block;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: 0;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n .border-top-radius(@navbar-border-radius);\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n//\n// Declared after the navbar components to ensure more specificity on the margins.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right {\n .pull-right();\n margin-right: -@navbar-padding-horizontal;\n\n ~ .navbar-right {\n margin-right: 0;\n }\n }\n}\n\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n }\n }\n }\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n .btn-link {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n }\n }\n }\n}\n","// Navbar vertical align\n//\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: @cursor-disabled;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","// Pagination\n\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: @cursor-disabled;\n }\n }\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n a& {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","// Labels\n\n.label-variant(@color) {\n background-color: @color;\n\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base class\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n .btn-xs & {\n top: 0;\n padding: 1px 5px;\n }\n\n // Hover state, but only for links\n a& {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Account for badges in navs\n .list-group-item.active > &,\n .nav-pills > .active > a > & {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n }\n .list-group-item > & {\n float: right;\n }\n .list-group-item > & + & {\n margin-right: 5px;\n }\n .nav-pills > li > a > & {\n margin-left: 3px;\n }\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding: @jumbotron-padding (@jumbotron-padding / 2);\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n > hr {\n border-top-color: darken(@jumbotron-bg, 10%);\n }\n\n .container &,\n .container-fluid & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding: (@jumbotron-padding * 1.6) 0;\n\n .container &,\n .container-fluid & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: (@font-size-base * 4.5);\n }\n }\n}\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(border .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissible alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0.\n.alert-dismissible {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","// Alerts\n\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @progress-border-radius;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n//\n// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar-striped` class, which you just add to an existing\n// `.progress-bar`.\n.progress-striped .progress-bar,\n.progress-bar-striped {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n//\n// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the\n// `.progress-bar.active` approach.\n.progress.active .progress-bar,\n.progress-bar.active {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Progress bars\n\n.progress-bar-variant(@color) {\n background-color: @color;\n\n // Deprecated parent class requirement as of v3.2.0\n .progress-striped & {\n #gradient > .striped();\n }\n}\n",".media {\n // Proper spacing between instances of .media\n margin-top: 15px;\n\n &:first-child {\n margin-top: 0;\n }\n}\n\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n\n.media-middle {\n vertical-align: middle;\n}\n\n.media-bottom {\n vertical-align: bottom;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n\n// Media list variation\n//\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n\n // Modifier class for 16:9 aspect ratio\n &.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n }\n\n // Modifier class for 4:3 aspect ratio\n &.embed-responsive-4by3 {\n padding-bottom: 75%;\n }\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n // Reset font and text propertes given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-small;\n font-weight: normal;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Reset font and text propertes given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: @line-height-base;\n text-align: left;\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n transition: transform .6s ease-in-out;\n backface-visibility: hidden;\n perspective: 1000;\n\n &.next,\n &.active.right {\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: -15px;\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: -15px;\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]}
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.min.css b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.min.css new file mode 100644 index 00000000..b6fe4e0f --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.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}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.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{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.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:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.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}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.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:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.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;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";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,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-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{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.eot b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.eot Binary files differnew file mode 100644 index 00000000..4a4ca865 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.eot diff --git a/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.svg b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..25691af8 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata></metadata> +<defs> +<font id="glyphicons_halflingsregular" horiz-adv-x="1200" > +<font-face units-per-em="1200" ascent="960" descent="-240" /> +<missing-glyph horiz-adv-x="500" /> +<glyph /> +<glyph /> +<glyph unicode="
" /> +<glyph unicode=" " /> +<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" /> +<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" /> +<glyph unicode=" " /> +<glyph unicode=" " horiz-adv-x="652" /> +<glyph unicode=" " horiz-adv-x="1304" /> +<glyph unicode=" " horiz-adv-x="652" /> +<glyph unicode=" " horiz-adv-x="1304" /> +<glyph unicode=" " horiz-adv-x="434" /> +<glyph unicode=" " horiz-adv-x="326" /> +<glyph unicode=" " horiz-adv-x="217" /> +<glyph unicode=" " horiz-adv-x="217" /> +<glyph unicode=" " horiz-adv-x="163" /> +<glyph unicode=" " horiz-adv-x="260" /> +<glyph unicode=" " horiz-adv-x="72" /> +<glyph unicode=" " horiz-adv-x="260" /> +<glyph unicode=" " horiz-adv-x="326" /> +<glyph unicode="€" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" /> +<glyph unicode="−" d="M200 400h900v300h-900v-300z" /> +<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" /> +<glyph unicode="☁" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" /> +<glyph unicode="✉" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" /> +<glyph unicode="✏" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" /> +<glyph unicode="" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" /> +<glyph unicode="" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q18 -55 86 -75.5t147 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" /> +<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" /> +<glyph unicode="" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" /> +<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" /> +<glyph unicode="" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" /> +<glyph unicode="" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" /> +<glyph unicode="" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" /> +<glyph unicode="" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" /> +<glyph unicode="" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" /> +<glyph unicode="" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" /> +<glyph unicode="" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" /> +<glyph unicode="" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" /> +<glyph unicode="" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" /> +<glyph unicode="" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" /> +<glyph unicode="" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" /> +<glyph unicode="" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" /> +<glyph unicode="" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" /> +<glyph unicode="" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" /> +<glyph unicode="" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" /> +<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" /> +<glyph unicode="" d="M0 25v475l200 700h800l199 -700l1 -475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" /> +<glyph unicode="" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" /> +<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" /> +<glyph unicode="" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" /> +<glyph unicode="" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" /> +<glyph unicode="" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" /> +<glyph unicode="" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" /> +<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" /> +<glyph unicode="" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" /> +<glyph unicode="" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" /> +<glyph unicode="" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" /> +<glyph unicode="" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" /> +<glyph unicode="" d="M0 700l1 475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" /> +<glyph unicode="" d="M1 700l1 475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" /> +<glyph unicode="" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" /> +<glyph unicode="" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" /> +<glyph unicode="" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" /> +<glyph unicode="" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" /> +<glyph unicode="" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" /> +<glyph unicode="" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v71l471 -1q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" /> +<glyph unicode="" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" /> +<glyph unicode="" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " /> +<glyph unicode="" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" /> +<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" /> +<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" /> +<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" /> +<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" /> +<glyph unicode="" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" /> +<glyph unicode="" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" /> +<glyph unicode="" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" /> +<glyph unicode="" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" /> +<glyph unicode="" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " /> +<glyph unicode="" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" /> +<glyph unicode="" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" /> +<glyph unicode="" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 139t-64 210zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" /> +<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" /> +<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" /> +<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q61 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l567 567l-137 137l-430 -431l-146 147z" /> +<glyph unicode="" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" /> +<glyph unicode="" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" /> +<glyph unicode="" d="M200 0l900 550l-900 550v-1100z" /> +<glyph unicode="" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" /> +<glyph unicode="" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" /> +<glyph unicode="" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" /> +<glyph unicode="" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" /> +<glyph unicode="" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" /> +<glyph unicode="" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" /> +<glyph unicode="" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" /> +<glyph unicode="" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM300 500h600v200h-600v-200z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141 z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM364 700h143q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5 q19 0 30 -10t11 -26q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-50 0 -90.5 -12t-75 -38.5t-53.5 -74.5t-19 -114zM500 300h200v100h-200 v-100z" /> +<glyph unicode="" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" /> +<glyph unicode="" d="M0 500v200h195q31 125 98.5 199.5t206.5 100.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200v-206 q149 48 201 206h-201v200h200q-25 74 -75.5 127t-124.5 77v-204h-200v203q-75 -23 -130 -77t-79 -126h209v-200h-210z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" /> +<glyph unicode="" d="M0 547l600 453v-300h600v-300h-600v-301z" /> +<glyph unicode="" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" /> +<glyph unicode="" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" /> +<glyph unicode="" d="M104 600h296v600h300v-600h298l-449 -600z" /> +<glyph unicode="" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" /> +<glyph unicode="" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" /> +<glyph unicode="" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" /> +<glyph unicode="" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5h-207q-21 0 -33 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" /> +<glyph unicode="" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111q1 1 1 6.5t-1.5 15t-3.5 17.5l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6 h-111v-100zM100 0h400v400h-400v-400zM200 900q-3 0 14 48t36 96l18 47l213 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" /> +<glyph unicode="" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" /> +<glyph unicode="" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" /> +<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" /> +<glyph unicode="" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" /> +<glyph unicode="" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 34 -48 36.5t-48 -29.5l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" /> +<glyph unicode="" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -20 -13 -28.5t-32 0.5l-94 78h-222l-94 -78q-19 -9 -32 -0.5t-13 28.5 v64q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" /> +<glyph unicode="" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" /> +<glyph unicode="" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" /> +<glyph unicode="" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" /> +<glyph unicode="" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" /> +<glyph unicode="" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" /> +<glyph unicode="" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" /> +<glyph unicode="" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" /> +<glyph unicode="" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" /> +<glyph unicode="" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" /> +<glyph unicode="" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" /> +<glyph unicode="" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" /> +<glyph unicode="" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" /> +<glyph unicode="" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" /> +<glyph unicode="" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM100 500v250v8v8v7t0.5 7t1.5 5.5t2 5t3 4t4.5 3.5t6 1.5t7.5 0.5h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35 q-55 337 -55 351zM1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" /> +<glyph unicode="" d="M74 350q0 21 13.5 35.5t33.5 14.5h18l117 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5q-18 -36 -18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-8 -3 -23 -8.5 t-65 -20t-103 -25t-132.5 -19.5t-158.5 -9q-125 0 -245.5 20.5t-178.5 40.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" /> +<glyph unicode="" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" /> +<glyph unicode="" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q124 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 213l100 212h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" /> +<glyph unicode="" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q124 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" /> +<glyph unicode="" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" /> +<glyph unicode="" d="M-101 651q0 72 54 110t139 38l302 -1l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 17 -10.5t26.5 -26t16.5 -36.5v-526q0 -13 -86 -93.5t-94 -80.5h-341q-16 0 -29.5 20t-19.5 41l-130 339h-107q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l107 89v502l-343 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM1000 201v600h200v-600h-200z" /> +<glyph unicode="" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6.5v7.5v6.5v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" /> +<glyph unicode="" d="M2 585q-16 -31 6 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85q0 -51 -0.5 -153.5t-0.5 -148.5q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM77 565l236 339h503 l89 -100v-294l-340 -130q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" /> +<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM298 701l2 -201h300l-2 -194l402 294l-402 298v-197h-300z" /> +<glyph unicode="" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l402 -294l-2 194h300l2 201h-300v197z" /> +<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" /> +<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" /> +<glyph unicode="" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -33 5.5 -92.5t7.5 -87.5q0 -9 17 -44t16 -60 q12 0 23 -5.5t23 -15t20 -13.5q24 -12 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55t-20 -57q42 -71 87 -80q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q104 -3 221 112q30 29 47 47t34.5 49t20.5 62q-14 9 -37 9.5t-36 7.5q-14 7 -49 15t-52 19q-9 0 -39.5 -0.5 t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5t5.5 57.5 q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 39 2 44q31 -13 58 -14.5t39 3.5l11 4q7 36 -16.5 53.5t-64.5 28.5t-56 23q-19 -3 -37 0 q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -45.5 0.5t-45.5 -2.5q-21 -7 -52 -26.5t-34 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -90.5t-29.5 -79.5zM518 916q3 12 16 30t16 25q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -24 17 -66.5t17 -43.5 q-9 2 -31 5t-36 5t-32 8t-30 14zM692 1003h1h-1z" /> +<glyph unicode="" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" /> +<glyph unicode="" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" /> +<glyph unicode="" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" /> +<glyph unicode="" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" /> +<glyph unicode="" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" /> +<glyph unicode="" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM514 609q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-14 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" /> +<glyph unicode="" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -78.5 -16.5t-67.5 -51.5l-389 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23 q38 0 53 -36q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60 l517 511q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" /> +<glyph unicode="" d="M80 784q0 131 98.5 229.5t230.5 98.5q143 0 241 -129q103 129 246 129q129 0 226 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100q-71 70 -104.5 105.5t-77 89.5t-61 99 t-17.5 91zM250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-105 48.5q-74 0 -132 -83l-118 -171l-114 174q-51 80 -123 80q-60 0 -109.5 -49.5t-49.5 -118.5z" /> +<glyph unicode="" d="M57 353q0 -95 66 -159l141 -142q68 -66 159 -66q93 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-8 9 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141q7 -7 19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -17q47 -49 77 -100l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" /> +<glyph unicode="" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" /> +<glyph unicode="" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" /> +<glyph unicode="" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335q-6 1 -15.5 4t-11.5 3q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5 v-307l64 -14q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5 zM700 237q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" /> +<glyph unicode="" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -28 16.5 -69.5t28 -62.5t41.5 -72h241v-100h-197q8 -50 -2.5 -115 t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q33 1 103 -16t103 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221z" /> +<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" /> +<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" /> +<glyph unicode="" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" /> +<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" /> +<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" /> +<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" /> +<glyph unicode="" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" /> +<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" /> +<glyph unicode="" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" /> +<glyph unicode="" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" /> +<glyph unicode="" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" /> +<glyph unicode="" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" /> +<glyph unicode="" d="M217 519q8 -19 31 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8h9q14 0 26 15q11 13 274.5 321.5t264.5 308.5q14 19 5 36q-8 17 -31 17l-301 -1q1 4 78 219.5t79 227.5q2 15 -5 27l-9 9h-9q-15 0 -25 -16q-4 -6 -98 -111.5t-228.5 -257t-209.5 -237.5q-16 -19 -6 -41 z" /> +<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " /> +<glyph unicode="" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" /> +<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" /> +<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" /> +<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" /> +<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 400l697 1l3 699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" /> +<glyph unicode="" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l249 -237l-1 697zM900 150h100v50h-100v-50z" /> +<glyph unicode="" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" /> +<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" /> +<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" /> +<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" /> +<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" /> +<glyph unicode="" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" /> +<glyph unicode="" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" /> +<glyph unicode="" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" /> +<glyph unicode="" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -116q-25 -17 -43.5 -51.5t-18.5 -65.5v-359z" /> +<glyph unicode="" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" /> +<glyph unicode="" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" /> +<glyph unicode="" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q17 18 13.5 41t-22.5 37l-192 136q-19 14 -45 12t-42 -19l-118 -118q-142 101 -268 227t-227 268l118 118q17 17 20 41.5t-11 44.5 l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" /> +<glyph unicode="" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-20 0 -35 14.5t-15 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" /> +<glyph unicode="" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" /> +<glyph unicode="" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" /> +<glyph unicode="" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" /> +<glyph unicode="" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" /> +<glyph unicode="" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" /> +<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86.5t85 207.5t-85 207t-205 86q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300h200 l-300 -300z" /> +<glyph unicode="" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104.5t60.5 178.5q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" /> +<glyph unicode="" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" /> +<glyph unicode="" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -11.5t1 -11.5q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" /> +</font> +</defs></svg>
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.ttf b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.ttf Binary files differnew file mode 100644 index 00000000..67fa00bf --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.ttf diff --git a/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.woff b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.woff Binary files differnew file mode 100644 index 00000000..8c54182a --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/fonts/glyphicons-halflings-regular.woff diff --git a/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.js b/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.js new file mode 100644 index 00000000..b6ac8d99 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.js @@ -0,0 +1,2320 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.1 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: alert.js v3.3.1 + * http://getbootstrap.com/javascript/#alerts + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.3.1' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = $(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: button.js v3.3.1 + * http://getbootstrap.com/javascript/#buttons + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.3.1' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state = state + 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked') && this.$element.hasClass('active')) changed = false + else $parent.find('.active').removeClass('active') + } + if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') + } else { + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + } + + if (changed) this.$element.toggleClass('active') + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + Plugin.call($btn, 'toggle') + e.preventDefault() + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: carousel.js v3.3.1 + * http://getbootstrap.com/javascript/#carousel + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = + this.sliding = + this.interval = + this.$active = + this.$items = null + + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.3.1' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var delta = direction == 'prev' ? -1 : 1 + var activeIndex = this.getItemIndex(active) + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var fallback = type == 'next' ? 'first' : 'last' + var that = this + + if (!$next.length) { + if (!this.options.wrap) return + $next = this.$element.find('.item')[fallback]() + } + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.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() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var href + var $this = $(this) + var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.1 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.1' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true, + trigger: '[data-toggle="collapse"]' + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && option == 'show') options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.3.1 + * http://getbootstrap.com/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.3.1' + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger('shown.bs.dropdown', relatedTarget) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.divider):visible a' + var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) + }) + } + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector && $(selector) + + return $parent && $parent.length ? $parent : $this.parent() + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.3.1 + * http://getbootstrap.com/javascript/#modals + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$backdrop = + this.isShown = null + this.scrollbarWidth = 0 + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.3.1' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + if (that.options.backdrop) that.adjustBackdrop() + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element + .addClass('in') + .attr('aria-hidden', false) + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$element.find('.modal-dialog') // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + .off('click.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') + .prependTo(this.$element) + .on('click.dismiss.bs.modal', $.proxy(function (e) { + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus.call(this.$element[0]) + : this.hide.call(this) + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + if (this.options.backdrop) this.adjustBackdrop() + this.adjustDialog() + } + + Modal.prototype.adjustBackdrop = function () { + this.$backdrop + .css('height', 0) + .css('height', this.$element[0].scrollHeight) + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', '') + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.3.1 + * http://getbootstrap.com/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== + + var Tooltip = function (element, options) { + this.type = + this.options = + this.enabled = + this.timeout = + this.hoverState = + this.$element = null + + this.init('tooltip', element, options) + } + + Tooltip.VERSION = '3.3.1' + + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { + animation: true, + placement: 'top', + selector: false, + template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (self && self.$tip && self.$tip.is(':visible')) { + self.hoverState = 'in' + return + } + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var $container = this.options.container ? $(this.options.container) : this.$element.parent() + var containerDim = this.getPosition($container) + + placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top = offset.top + marginTop + offset.left = offset.left + marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { + this.arrow() + .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isHorizontal ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = this.tip() + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + return (this.$tip = this.$tip || $(this.options.template)) + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + var selector = options && options.selector + + if (!data && option == 'destroy') return + if (selector) { + if (!data) $this.data('bs.tooltip', (data = {})) + if (!data[selector]) data[selector] = new Tooltip(this, options) + } else { + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + } + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.1 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.1' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + Popover.prototype.tip = function () { + if (!this.$tip) this.$tip = $(this.options.template) + return this.$tip + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + var selector = options && options.selector + + if (!data && option == 'destroy') return + if (selector) { + if (!data) $this.data('bs.popover', (data = {})) + if (!data[selector]) data[selector] = new Popover(this, options) + } else { + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + } + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.1 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + var process = $.proxy(this.process, this) + + this.$body = $('body') + this.$scrollElement = $(element).is('body') ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', process) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.1' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var offsetMethod = 'offset' + var offsetBase = 0 + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + var self = this + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + self.offsets.push(this[0]) + self.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.1 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + this.element = $(element) + } + + Tab.VERSION = '3.3.1' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu')) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.1 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = + this.unpin = + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.1' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && colliderTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = $('body').height() + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.min.js b/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.min.js new file mode 100644 index 00000000..d8398659 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$backdrop=this.isShown=null,this.scrollbarWidth=0,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.options.backdrop&&d.adjustBackdrop(),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$element.find(".modal-dialog").one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=this.tip(),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.1",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]}) +})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/bootstrap/js/npm.js b/longbow/documentation/doxygen-extras/bootstrap/js/npm.js new file mode 100644 index 00000000..bf6aa806 --- /dev/null +++ b/longbow/documentation/doxygen-extras/bootstrap/js/npm.js @@ -0,0 +1,13 @@ +// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. +require('../../js/transition.js') +require('../../js/alert.js') +require('../../js/button.js') +require('../../js/carousel.js') +require('../../js/collapse.js') +require('../../js/dropdown.js') +require('../../js/modal.js') +require('../../js/tooltip.js') +require('../../js/popover.js') +require('../../js/scrollspy.js') +require('../../js/tab.js') +require('../../js/affix.js')
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/customdoxygen.css b/longbow/documentation/doxygen-extras/customdoxygen.css new file mode 100644 index 00000000..8560f848 --- /dev/null +++ b/longbow/documentation/doxygen-extras/customdoxygen.css @@ -0,0 +1,1705 @@ +/* The standard CSS for doxygen 1.8.9.1 */ + +body, table, div, p, dl { + font: 400 14px/22px Helvetica,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: bold; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + border-top-left-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #205469; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +dl +{ + padding: 0 0 0 10px; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ +dl.section +{ + margin-left: 0px; + padding-left: 0px; +} + +dl.note +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00D000; +} + +dl.deprecated +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #505050; +} + +dl.todo +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #00C0E0; +} + +dl.test +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #3030E0; +} + +dl.bug +{ + margin-left:-7px; + padding-left: 3px; + border-left:4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 20px 10px 10px; + width: 200px; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #ffffff; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #ffffff; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + + +h1, .h1, h2, .h2, h3, .h3{ + font-weight: 200 !important; + font-family: Helvetica-Light; +} + +#navrow1, #navrow2, #navrow3, #navrow4, #navrow5 { + border-bottom: 1px solid #EEEEEE; +} + +.adjust-right { + margin-left: 30px !important; + font-size: 1.15em !important; +} +.navbar{ + border: 0px solid #222 !important; +} + + +/* Sticky footer styles +-------------------------------------------------- */ +html, +body { + height: 100%; + /* The html and body elements cannot have any padding or margin. */ +} + +/* Wrapper for page content to push down footer */ +#wrap { + min-height: 100%; + height: auto; + /* Negative indent footer by its height */ + margin: 0 auto -60px; + /* Pad bottom by footer height */ + padding: 0 0 60px; +} + +/* Set the fixed height of the footer here */ +#footer { + font-size: 0.9em; + padding: 8px 0px; + background-color: #f5f5f5; +} + +.footer-row { + line-height: 44px; +} + +#footer > .container { + padding-left: 15px; + padding-right: 15px; +} + +.footer-follow-icon { + margin-left: 3px; + text-decoration: none !important; +} + +.footer-follow-icon img { + width: 20px; +} + +.footer-link { + padding-top: 5px; + display: inline-block; + color: #999999; + text-decoration: none; +} + +.footer-copyright { + text-align: center; +} + + +@media (min-width: 992px) { + .footer-row { + text-align: left; + } + + .footer-icons { + text-align: right; + } +} +@media (max-width: 991px) { + .footer-row { + text-align: center; + } + + .footer-icons { + text-align: center; + } +} + +/* DOXYGEN Code Styles +----------------------------------- */ + + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px 6px; + margin: 4px 8px 4px 2px; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} diff --git a/longbow/documentation/doxygen-extras/doxy-boot.js b/longbow/documentation/doxygen-extras/doxy-boot.js new file mode 100644 index 00000000..5ee5fa37 --- /dev/null +++ b/longbow/documentation/doxygen-extras/doxy-boot.js @@ -0,0 +1,120 @@ +$( document ).ready(function() { + + $("div.headertitle").addClass("page-header"); + $("div.title").addClass("h1"); + + $('li > a[href="index.html"] > span').before("<i class='fa fa-cog'></i> "); + $('li > a[href="modules.html"] > span').before("<i class='fa fa-square'></i> "); + $('li > a[href="namespaces.html"] > span').before("<i class='fa fa-bars'></i> "); + $('li > a[href="annotated.html"] > span').before("<i class='fa fa-list-ul'></i> "); + $('li > a[href="classes.html"] > span').before("<i class='fa fa-book'></i> "); + $('li > a[href="inherits.html"] > span').before("<i class='fa fa-sitemap'></i> "); + $('li > a[href="functions.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_func.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_vars.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_enum.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_eval.html"] > span').before("<i class='fa fa-list'></i> "); + $('img[src="ftv2ns.png"]').replaceWith('<span class="label label-danger">N</span> '); + $('img[src="ftv2cl.png"]').replaceWith('<span class="label label-danger">C</span> '); + + $("ul.tablist").addClass("nav nav-pills nav-justified"); + $("ul.tablist").css("margin-top", "0.5em"); + $("ul.tablist").css("margin-bottom", "0.5em"); + $("li.current").addClass("active"); + $("iframe").attr("scrolling", "yes"); + + $("#nav-path > ul").addClass("breadcrumb"); + + $("table.params").addClass("table"); + $("div.ingroups").wrapInner("<small></small>"); + $("div.levels").css("margin", "0.5em"); + $("div.levels > span").addClass("btn btn-default btn-xs"); + $("div.levels > span").css("margin-right", "0.25em"); + + $("table.directory").addClass("table table-striped"); + $("div.summary > a").addClass("btn btn-default btn-xs"); + $("table.fieldtable").addClass("table"); + $(".fragment").addClass("well"); + $(".memitem").addClass("panel panel-default"); + $(".memproto").addClass("panel-heading"); + $(".memdoc").addClass("panel-body"); + $("span.mlabel").addClass("label label-info"); + + $("table.memberdecls").addClass("table"); + $("[class^=memitem]").addClass("active"); + + $("div.ah").addClass("btn btn-default"); + $("span.mlabels").addClass("pull-right"); + $("table.mlabels").css("width", "100%") + $("td.mlabels-right").addClass("pull-right"); + + $("div.ttc").addClass("panel panel-primary"); + $("div.ttname").addClass("panel-heading"); + $("div.ttname a").css("color", 'white'); + $("div.ttdef,div.ttdoc,div.ttdeci").addClass("panel-body"); + + $('#MSearchBox').parent().remove(); + + $('div.fragment.well div.line:first').css('margin-top', '15px'); + $('div.fragment.well div.line:last').css('margin-bottom', '15px'); + + $('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered').each(function(){ + $(this).prepend('<thead></thead>'); + $(this).find('tbody > tr:first').prependTo($(this).find('thead')); + + $(this).find('td > span.success').parent().addClass('success'); + $(this).find('td > span.warning').parent().addClass('warning'); + $(this).find('td > span.danger').parent().addClass('danger'); + }); + + + + if($('div.fragment.well div.ttc').length > 0) + { + $('div.fragment.well div.line:first').parent().removeClass('fragment well'); + } + + $('table.memberdecls').find('.memItemRight').each(function(){ + $(this).contents().appendTo($(this).siblings('.memItemLeft')); + $(this).siblings('.memItemLeft').attr('align', 'left'); + }); + + function getOriginalWidthOfImg(img_element) { + var t = new Image(); + t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src; + return t.width; + } + + $('div.dyncontent').find('img').each(function(){ + if(getOriginalWidthOfImg($(this)[0]) > $('#content>div.container').width()) + $(this).css('width', '100%'); + }); + + $(".memitem").removeClass('memitem'); + $(".memproto").removeClass('memproto'); + $(".memdoc").removeClass('memdoc'); + $("span.mlabel").removeClass('mlabel'); + $("table.memberdecls").removeClass('memberdecls'); + $("[class^=memitem]").removeClass('memitem'); + $("span.mlabels").removeClass('mlabels'); + $("table.mlabels").removeClass('mlabels'); + $("td.mlabels-right").removeClass('mlabels-right'); + $(".navpath").removeClass('navpath'); + $("li.navelem").removeClass('navelem'); + $("a.el").removeClass('el'); + $("div.ah").removeClass('ah'); + $("div.header").removeClass("header"); + + $('.mdescLeft').each(function(){ + if($(this).html()==" ") { + $(this).siblings('.mdescRight').attr('colspan', 2); + $(this).remove(); + } + }); + $('td.memItemLeft').each(function(){ + if($(this).siblings('.memItemRight').html()=="") { + $(this).attr('colspan', 2); + $(this).siblings('.memItemRight').remove(); + } + }); +});
\ No newline at end of file diff --git a/longbow/documentation/doxygen-extras/doxygen-bootstrap.js b/longbow/documentation/doxygen-extras/doxygen-bootstrap.js new file mode 100755 index 00000000..2ddb6474 --- /dev/null +++ b/longbow/documentation/doxygen-extras/doxygen-bootstrap.js @@ -0,0 +1,119 @@ +/* Annotate the html output from doxygen with the necessary classes + * for the twitter bootstrap. + */ +$(document).ready(function() { + $("div.headertitle").addClass("page-header"); + $("div.title").addClass("h1"); + + $('li > a[href="index.html"] > span').before("<i class='fa fa-cog'></i> "); + $('li > a[href="modules.html"] > span').before("<i class='fa fa-square'></i> "); + $('li > a[href="namespaces.html"] > span').before("<i class='fa fa-bars'></i> "); + $('li > a[href="annotated.html"] > span').before("<i class='fa fa-list-ul'></i> "); + $('li > a[href="classes.html"] > span').before("<i class='fa fa-book'></i> "); + $('li > a[href="inherits.html"] > span').before("<i class='fa fa-sitemap'></i> "); + $('li > a[href="functions.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_func.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_vars.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_enum.html"] > span').before("<i class='fa fa-list'></i> "); + $('li > a[href="functions_eval.html"] > span').before("<i class='fa fa-list'></i> "); + $('img[src="ftv2ns.png"]').replaceWith('<span class="label label-danger">N</span> '); + $('img[src="ftv2cl.png"]').replaceWith('<span class="label label-danger">C</span> '); + + $("ul.tablist").addClass("nav nav-pills nav-justified"); + $("ul.tablist").css("margin-top", "0.5em"); + $("ul.tablist").css("margin-bottom", "0.5em"); + $("li.current").addClass("active"); + $("iframe").attr("scrolling", "yes"); + + $("#nav-path > ul").addClass("breadcrumb"); + + $("table.params").addClass("table"); + $("div.ingroups").wrapInner("<small></small>"); + $("div.levels").css("margin", "0.5em"); + $("div.levels > span").addClass("btn btn-default btn-xs"); + $("div.levels > span").css("margin-right", "0.25em"); + + $("table.directory").addClass("table table-striped"); + $("div.summary > a").addClass("btn btn-default btn-xs"); + $("table.fieldtable").addClass("table"); + $(".fragment").addClass("well"); + $(".memitem").addClass("panel panel-default"); + $(".memproto").addClass("panel-heading"); + $(".memdoc").addClass("panel-body"); + $("span.mlabel").addClass("label label-info"); + + $("table.memberdecls").addClass("table"); + $("[class^=memitem]").addClass("active"); + + $("div.ah").addClass("btn btn-default"); + $("span.mlabels").addClass("pull-right"); + $("table.mlabels").css("width", "100%") + $("td.mlabels-right").addClass("pull-right"); + + $("div.ttc").addClass("panel panel-primary"); + $("div.ttname").addClass("panel-heading"); + $("div.ttname a").css("color", 'white'); + $("div.ttdef,div.ttdoc,div.ttdeci").addClass("panel-body"); + + $('#MSearchBox').parent().remove(); + + $('div.fragment.well div.line:first').css('margin-top', '15px'); + $('div.fragment.well div.line:last').css('margin-bottom', '15px'); + + $('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered').each(function(){ + $(this).prepend('<thead></thead>'); + $(this).find('tbody > tr:first').prependTo($(this).find('thead')); + + $(this).find('td > span.success').parent().addClass('success'); + $(this).find('td > span.warning').parent().addClass('warning'); + $(this).find('td > span.danger').parent().addClass('danger'); + }); + + if($('div.fragment.well div.ttc').length > 0) { + $('div.fragment.well div.line:first').parent().removeClass('fragment well'); + } + + $('table.memberdecls').find('.memItemRight').each(function(){ + $(this).contents().appendTo($(this).siblings('.memItemLeft')); + $(this).siblings('.memItemLeft').attr('align', 'left'); + }); + + function getOriginalWidthOfImg(img_element) { + var t = new Image(); + t.src = (img_element.getAttribute ? img_element.getAttribute("src") : false) || img_element.src; + return t.width; + } + + $('div.dyncontent').find('img').each(function(){ + if(getOriginalWidthOfImg($(this)[0]) > $('#content>div.container').width()) + $(this).css('width', '100%'); + }); + + $(".memitem").removeClass('memitem'); + $(".memproto").removeClass('memproto'); + $(".memdoc").removeClass('memdoc'); + $("span.mlabel").removeClass('mlabel'); + $("table.memberdecls").removeClass('memberdecls'); + $("[class^=memitem]").removeClass('memitem'); + $("span.mlabels").removeClass('mlabels'); + $("table.mlabels").removeClass('mlabels'); + $("td.mlabels-right").removeClass('mlabels-right'); + $(".navpath").removeClass('navpath'); + $("li.navelem").removeClass('navelem'); + $("a.el").removeClass('el'); + $("div.ah").removeClass('ah'); + $("div.header").removeClass("header"); + + $('.mdescLeft').each(function(){ + if($(this).html()==" ") { + $(this).siblings('.mdescRight').attr('colspan', 2); + $(this).remove(); + } + }); + $('td.memItemLeft').each(function(){ + if($(this).siblings('.memItemRight').html()=="") { + $(this).attr('colspan', 2); + $(this).siblings('.memItemRight').remove(); + } + }); +}); diff --git a/longbow/documentation/doxygen-extras/footer.html b/longbow/documentation/doxygen-extras/footer.html new file mode 100755 index 00000000..9ed5f12a --- /dev/null +++ b/longbow/documentation/doxygen-extras/footer.html @@ -0,0 +1,31 @@ +<div id="nav-path" class="navpath"><!-- id is needed for treeview function! --> +</div> +<!--END GENERATE_TREEVIEW--> +</div> +</div> +</div> +</div> +</div> +<hr class="footer"/> + <div class="container footer"> +Copyright (c) 2017 Cisco and/or its affiliates.<br/> +$datetime +<!-- Start of StatCounter Code for Default Guide --> +<script type="text/javascript"> +//<![CDATA[ +var sc_project=11081165; +var sc_invisible=0; +var sc_security="5698c63a"; +var scJsHost = (("https:" == document.location.protocol) ? "https://secure." : "http://www."); +document.write("<sc"+"ript type='text/javascript' src='" + scJsHost+ "statcounter.com/counter/counter_xhtml.js'></"+"script>"); +//]]> +</script> +<noscript> +<div class="statcounter"> +<a title="shopify site analytics" href="http://statcounter.com/shopify/" class="statcounter"> +<img class="statcounter" src="http://c.statcounter.com/11081165/0/5698c63a/0/" alt="shopify site analytics" /> +</a></div></noscript> + </div> +<!-- End of StatCounter Code for Default Guide --> +</body> +</html> diff --git a/longbow/documentation/doxygen-extras/header.html b/longbow/documentation/doxygen-extras/header.html new file mode 100755 index 00000000..9be163ba --- /dev/null +++ b/longbow/documentation/doxygen-extras/header.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <!-- For Mobile Devices --> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> + <meta name="generator" content="Doxygen $doxygenversion"/> + + <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script> + + <!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> + <!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME--> + <!--<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>--> + <script type="text/javascript" src="$relpath^dynsections.js"></script> + $treeview + $search + $mathjax + <link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" /> + <link href="masthead.css" rel="stylesheet" type="text/css" /> + $extrastylesheet + + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> + <script type="text/javascript" src="$relpath^doxygen-bootstrap.js"></script> + </head> + <body> + <div class="container masthead"> + <div class="navbar-header"> + <img src="parc_black_solid.png" \> + </div> + </div> + <nav class="navbar navbar-default" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <a class="navbar-brand">$projectname $projectnumber</a> + </div> + </div> + </nav> + <div id="top"><!-- do not remove this div, it is closed by doxygen! --> + <div class="content" id="content"> + <div class="container"> + <div class="row"> + <div class="col-sm-12 panel panel-default" style="padding-bottom: 15px;"> + <div style="margin-bottom: 15px;"> +<!-- end header part --> diff --git a/longbow/documentation/doxygen-extras/masthead.css b/longbow/documentation/doxygen-extras/masthead.css new file mode 100644 index 00000000..7827e079 --- /dev/null +++ b/longbow/documentation/doxygen-extras/masthead.css @@ -0,0 +1,9 @@ +.masthead { + border-bottom: 1px dotted black; + margin-top: 20.5px; +} + +.masthead img { + height: 50px; + margin-bottom: 20px; +} diff --git a/longbow/documentation/examples/testAssertion.c b/longbow/documentation/examples/testAssertion.c new file mode 100755 index 00000000..eb60db91 --- /dev/null +++ b/longbow/documentation/examples/testAssertion.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../runtime.h" + +int +main(int argc, char *argv[]) +{ + assertTrue(0, "Force this assertion."); +} diff --git a/longbow/documentation/images/noise_gradient.jpg b/longbow/documentation/images/noise_gradient.jpg Binary files differnew file mode 100644 index 00000000..30ecc02c --- /dev/null +++ b/longbow/documentation/images/noise_gradient.jpg diff --git a/longbow/documentation/images/parc_black_solid.png b/longbow/documentation/images/parc_black_solid.png Binary files differnew file mode 100644 index 00000000..6abcf2f4 --- /dev/null +++ b/longbow/documentation/images/parc_black_solid.png diff --git a/longbow/documentation/imported-stylesheet.css b/longbow/documentation/imported-stylesheet.css new file mode 100644 index 00000000..97541013 --- /dev/null +++ b/longbow/documentation/imported-stylesheet.css @@ -0,0 +1 @@ +@import "../assets/css/longbow-doxygen.css"; diff --git a/longbow/documentation/longbow-logo.gif b/longbow/documentation/longbow-logo.gif Binary files differnew file mode 100644 index 00000000..ae4cd838 --- /dev/null +++ b/longbow/documentation/longbow-logo.gif diff --git a/longbow/documentation/longbow.conf b/longbow/documentation/longbow.conf new file mode 100644 index 00000000..0366e5a5 --- /dev/null +++ b/longbow/documentation/longbow.conf @@ -0,0 +1,2382 @@ +# Doxyfile 1.8.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = LongBow + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "LongBow: Write Better C Programs" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = longbow-documentation + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = longbow.log + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = ../src/LongBow ../src/python + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.as \ + *.js + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = doxygen-extras/header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = doxygen-extras/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra stylesheet files is of importance (e.g. the last +# stylesheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = doxygen-extras/customdoxygen.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = doxygen-extras/doxygen-bootstrap.js + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = YES + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. To get the times font for +# instance you can specify +# EXTRA_PACKAGES=times +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, +# for the replacement values of the other commands the user is refered to +# HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen +# Definitions (see http://autogen.sf.net) file that captures the structure of +# the code including all documentation. Note that this feature is still +# experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names +# in the source code. If set to NO only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = longbow.doctags + +# If the ALLEXTERNALS tag is set to YES all external class will be listed in the +# class index. If set to NO only the inherited external classes will be listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in +# the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif and svg. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. +# This tag requires that the tag HAVE_DOT is set to YES. + +PLANTUML_JAR_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/longbow/documentation/longbow.doxygen.in b/longbow/documentation/longbow.doxygen.in new file mode 100644 index 00000000..9f39ca96 --- /dev/null +++ b/longbow/documentation/longbow.doxygen.in @@ -0,0 +1,2385 @@ +# Doxyfile 1.8.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = LongBow + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "LongBow: Write Better C Programs" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is included in +# the documentation. The maximum height of the logo should not exceed 55 pixels +# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo +# to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = generated-documentation + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a +# new page for each member. If set to NO, the documentation of a member will be +# part of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = YES + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO these classes will be included in the various overviews. This option has +# no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the +# todo list. This list is created by putting \todo commands in the +# documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the +# test list. This list is created by putting \test commands in the +# documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES the list +# will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO doxygen will only warn about wrong or incomplete parameter +# documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = longbow.log + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. +# Note: If this tag is empty the current directory is searched. + +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../src/LongBow +# ../src/python + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank the +# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, +# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, +# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, +# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, +# *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.as \ + *.js + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = ../src/LongBow/test + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = */examples/* \ + */tests/* \ + *private* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER ) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = @CMAKE_CURRENT_SOURCE_DIR@/doxygen-extras/header.html + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/doxygen-extras/footer.html + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefor more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra stylesheet files is of importance (e.g. the last +# stylesheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/doxygen-extras/customdoxygen.css @CMAKE_CURRENT_SOURCE_DIR@/doxygen-extras/masthead.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = @CMAKE_CURRENT_SOURCE_DIR@/doxygen-extras/doxygen-bootstrap.js @CMAKE_CURRENT_SOURCE_DIR@/images/parc_black_solid.png + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the stylesheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = com.parc.csl.LongBow + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = com.parc.csl + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = PARC + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated ( +# YES) or that it should be included in the master .chm file ( NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated ( +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer ( doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: http://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when enabling USE_PDFLATEX this option is only used for generating +# bitmaps for formulas in the HTML output, but not in the Makefile that is +# written to the output directory. +# The default file is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. To get the times font for +# instance you can specify +# EXTRA_PACKAGES=times +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, +# for the replacement values of the other commands the user is refered to +# HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's config +# file, i.e. a series of assignments. You only have to provide replacements, +# missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's config file. A template extensions file can be generated +# using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen +# Definitions (see http://autogen.sf.net) file that captures the structure of +# the code including all documentation. Note that this feature is still +# experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names +# in the source code. If set to NO only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = longbow.doctags + +# If the ALLEXTERNALS tag is set to YES all external class will be listed in the +# class index. If set to NO only the inherited external classes will be listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in +# the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif and svg. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. +# This tag requires that the tag HAVE_DOT is set to YES. + +PLANTUML_JAR_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/longbow/documentation/longbow.gif b/longbow/documentation/longbow.gif Binary files differnew file mode 100644 index 00000000..140bd01c --- /dev/null +++ b/longbow/documentation/longbow.gif diff --git a/longbow/documentation/stylesheet.css b/longbow/documentation/stylesheet.css new file mode 100644 index 00000000..fb5cda7c --- /dev/null +++ b/longbow/documentation/stylesheet.css @@ -0,0 +1,47 @@ +body { + xbackground-color: #111111; + xcolor: white; + margin: 0; + padding: 11% 11% 0 11%; +} + +xdiv#top { + margin: 0 11% 0 11%; + padding: 4em 3% 4em 3%; + background-color: white; + color: black; + border-radius: 8px; +} + +xdiv.header { + margin: 0 11% 0 11%; + padding: 4em 3% 4em 3%; + background-color: grey; + color: black; + border-radius: 8px; +} + +div.contents { + xbackground-image: url(noise_gradient.jpg); + xbackground-repeat: no-repeat; + /*margin: 0 11% 0 11%;*/ + /*padding: 4em 3% 4em 3%;*/ +/* background-color: white;*/ + xcolor: white; + xborder-radius: 8px; +} + +x#titlearea { + border: 2px solid red; + background-color: white; + color: black; +} + +xhr.footer { + display: none; +} + +x.footer { + background-color: #AAA; + color: black; +} diff --git a/longbow/src/CMakeLists.txt b/longbow/src/CMakeLists.txt new file mode 100644 index 00000000..7ed5ddfe --- /dev/null +++ b/longbow/src/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(LongBow) +add_subdirectory(python) diff --git a/longbow/src/LongBow/.gitignore b/longbow/src/LongBow/.gitignore new file mode 100644 index 00000000..6d86de6e --- /dev/null +++ b/longbow/src/LongBow/.gitignore @@ -0,0 +1,2 @@ +*.gcda +*.gcno diff --git a/longbow/src/LongBow/CMakeLists.txt b/longbow/src/LongBow/CMakeLists.txt new file mode 100644 index 00000000..476cc8ab --- /dev/null +++ b/longbow/src/LongBow/CMakeLists.txt @@ -0,0 +1,171 @@ +# Define a few configuration variables that we want accessible in the software +configure_file( + config.h.in + config.h +) + +set(LONGBOW_REPORT_HEADER_FILES + Reporting/longBowReport_Testing.h + Reporting/longBowReport_Runtime.h + ) + +set(LONGBOW_REPORT_BASE_SOURCE_FILES + Reporting/longBowReport_Runtime.c + Reporting/longBowReport_Testing.c + ${LONGBOW_REPORT_HEADER_FILES}) + +source_group(report-base FILES ${LONGBOW_REPORT_BASE_SOURCE_FILES}) + +set(LONGBOW_REPORT_ANSI_SOURCE_FILES + Reporting/ANSITerm/longBowReport_Runtime.c + Reporting/ANSITerm/longBowReport_Runtime.h + Reporting/ANSITerm/longBowReport_Testing.c + Reporting/ANSITerm/longBowReportANSITerminal_About.c + Reporting/ANSITerm/longBowReportANSITerminal_About.h) + +source_group(report-ansiterm FILES ${LONGBOW_REPORT_ANSI_SOURCE_FILES}) + + +if (ANDROID_API) + set(LONGBOW_REPORT_TEXT_RUNTIME_SOURCE_FILE Reporting/Android/longBowReport_Runtime.c) +else() + set(LONGBOW_REPORT_TEXT_RUNTIME_SOURCE_FILE Reporting/TextPlain/longBowReport_Runtime.c) +endif() + + set(LONGBOW_REPORT_TEXT_SOURCE_FILES + ${LONGBOW_REPORT_TEXT_RUNTIME_SOURCE_FILE} + Reporting/TextPlain/longBowReport_Testing.c + Reporting/TextPlain/longBowReportTextPlain_About.c + Reporting/TextPlain/longBowReportTextPlain_About.h) + +source_group(report-textplain FILES ${LONGBOW_REPORT_TEXT_SOURCE_FILES}) + +set(LONGBOW_CONFIG_SOURCE_FILES + command-line/liblongbow-config.c) + +source_group(longbow-config FILES ${LONGBOW_CONFIG_SOURCE_FILES}) + +set(LIBLONGBOW_HEADER_FILES + stubs/execinfo.h + assertions.h + debugging.h + longBow_About.h + longBow_Backtrace.h + longBow_ClipBoard.h + longBow_Compiler.h + longBow_Config.h + longBow_Debug.h + longBow_Event.h + longBow_EventType.h + longBow_Location.h + longBow_Main.h + longBow_MeasureTime.h + longBow_Properties.h + longBow_Runtime.h + longBow_RuntimeResult.h + longBow_Status.h + longBow_SubProcess.h + longBow_TestCase.h + longBow_TestCaseClipBoard.h + longBow_TestCaseMetaData.h + longBow_TestFixture.h + longBow_TestFixtureConfig.h + longBow_TestRunner.h + longBow_UnitTest.h + longBow_UnitTesting.h + runtime.h + testing.h + tests.h + traps.h + unit-test.h + ) + +set(LIBLONGBOW_SOURCE_FILES + private/longBow_ArrayList.h + private/longBow_Memory.h + private/longBow_OpenFile.h + private/longBow_String.h + private/longBow_ArrayList.c + private/longBow_Memory.c + private/longBow_OpenFile.c + private/longBow_String.c + longBow_About.c + longBow_Backtrace.c + longBow_ClipBoard.c + longBow_Config.c + longBow_Debug.c + longBow_Event.c + longBow_EventType.c + longBow_Location.c + longBow_Main.c + longBow_MeasureTime.c + longBow_Properties.c + longBow_Runtime.c + longBow_RuntimeResult.c + longBow_Status.c + longBow_SubProcess.c + longBow_TestCase.c + longBow_TestCaseClipBoard.c + longBow_TestCaseMetaData.c + longBow_TestFixture.c + longBow_TestFixtureConfig.c + longBow_TestRunner.c + longBow_UnitTesting.c + ${LIBLONGBOW_HEADER_FILES}) + +source_group(longbow FILES ${LIBLONGBOW_SOURCE_FILES}) + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup") + message( "-- Set \"-undefined dynamic_lookup\" for shared libraries") +endif() + +add_library(longbow-ansiterm STATIC ${LONGBOW_REPORT_ANSI_SOURCE_FILES} ${LONGBOW_REPORT_BASE_SOURCE_FILES}) +add_library(longbow-ansiterm.shared SHARED ${LONGBOW_REPORT_ANSI_SOURCE_FILES} ${LONGBOW_REPORT_BASE_SOURCE_FILES}) + +set_target_properties(longbow-ansiterm.shared PROPERTIES + SOVERSION 1 + VERSION 1.0 + OUTPUT_NAME longbow-ansiterm) + +add_library(longbow-textplain STATIC ${LONGBOW_REPORT_TEXT_SOURCE_FILES} ${LONGBOW_REPORT_BASE_SOURCE_FILES}) +add_library(longbow-textplain.shared SHARED ${LONGBOW_REPORT_TEXT_SOURCE_FILES} ${LONGBOW_REPORT_BASE_SOURCE_FILES}) + +set_target_properties(longbow-textplain.shared PROPERTIES + SOVERSION 1 + VERSION 1.0 + OUTPUT_NAME longbow-textplain) + +add_library(longbow STATIC ${LIBLONGBOW_SOURCE_FILES}) +add_library(longbow.shared SHARED ${LIBLONGBOW_SOURCE_FILES}) + +set_target_properties(longbow.shared PROPERTIES + SOVERSION 1 + VERSION 1.0 + OUTPUT_NAME longbow) + +add_executable(longbow-config ${LONGBOW_CONFIG_SOURCE_FILES}) + + +set(longbowLibraries + longbow + longbow.shared + longbow-ansiterm + longbow-ansiterm.shared + longbow-textplain + longbow-textplain.shared + ) + +foreach(lib ${longbowLibraries}) + install(TARGETS ${lib} LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) +endforeach() + +install(FILES ${LIBLONGBOW_HEADER_FILES} DESTINATION include/LongBow ) +install(FILES ${LONGBOW_REPORT_HEADER_FILES} DESTINATION include/LongBow/Reporting ) + +if(ANDROID_API) + message("############ Detected cross compile for ${CMAKE_SYSTEM_NAME}") + message("############ This build will not include doxygen, tools, or tests") +else() + add_subdirectory(test) +endif() diff --git a/longbow/src/LongBow/Groups.dox b/longbow/src/LongBow/Groups.dox new file mode 100644 index 00000000..758f7abc --- /dev/null +++ b/longbow/src/LongBow/Groups.dox @@ -0,0 +1,47 @@ +/** +\mainpage LongBow + +Software testing, validation, and measurable quality metics are an important +element in modern software development. LongBow is a software framework and +facility for writing software using invariants, runtime validation, +unit testing, and code analysis for the C programming language. + +LongBow is software to help you write better C programs. It provides: + +* A run-time assertion facility to establish strict rules on the state of your program. +* A testing facility based on the xUnit testing model. +* Compile-time assistance for writing code meant to be compiled by compilers with different features. + +LongBow can help you find and manage problems early, establish and maintain + confidence in the correctness of your code, make collaboration easier, +facilitate future change, and improve overall design. + +LongBow allows you to take control and establish invariant pre- and +post-conditions that detect inconsistencies and unexpected results in your +programs in order to find bugs and design deficiencies in the code during +development rather than waiting for your users and customers to find your bugs for you. + + +@defgroup runtime Runtime +@brief LongBow functions and macros for runtime, consisting primarily of assertions and traps. + +@defgroup testing Testing +@brief LongBow functions and macros for writing tests. + +LongBow testing Macros and ancillary functions to implement an xUnit style of writing and running tests. +Test writers create a `LONGBOW_TEST_RUNNER` function which, in turn, +invokes one or more `LONGBOW_TEST_FIXTURE` functions, +each of which invoke a specific `LONGBOW_TEST_CASE`. + +@defgroup internals Internals +@brief LongBow functions and macros used internally. + +@defgroup reporting Reporting +@brief LongBow functions and definitions for writing report libraries. + +@defgroup performance Performance testing +@brief LongBow functions and definitions for writing performance tests. + +@example testAssertion.c +*/ + diff --git a/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.c b/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.c new file mode 100644 index 00000000..e12c7b37 --- /dev/null +++ b/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.c @@ -0,0 +1,44 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#include "longBowReportANSITerminal_About.h" + +const char *longBowReportANSITerminal_What = "@(#)" "LongBow ANSI Terminal Reporter " RELEASE_VERSION " 2017-02-14T21:39:44.348378" + "@(#)" "\tCopyright (c) 2017 Cisco and/or its affiliates."; + +const char * +longBowReportANSITerminalAbout_Name(void) +{ + return "LongBow ANSI Terminal Reporter"; +} + +const char * +longBowReportANSITerminalAbout_Version(void) +{ + return RELEASE_VERSION; +} + +const char * +longBowReportANSITerminalAbout_About(void) +{ + return "LongBow ANSI Terminal Reporter "RELEASE_VERSION " 2017-02-14T21:39:44.348378" "\nCopyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportANSITerminalAbout_MiniNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportANSITerminalAbout_ShortNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportANSITerminalAbout_LongNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n"; +} + diff --git a/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.h b/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.h new file mode 100755 index 00000000..8dd3230c --- /dev/null +++ b/longbow/src/LongBow/Reporting/ANSITerm/longBowReportANSITerminal_About.h @@ -0,0 +1,54 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#ifndef longBowReportANSITerminal_About_h +#define longBowReportANSITerminal_About_h +/** + * Embedded string containing information for the what(1) command. + * + */ +extern const char *longBowReportANSITerminal_What; + +/** + * Return the name as a C string. + * + * @return The name as a C string. + */ +const char *longBowReportANSITerminalAbout_Name(void); + +/** + * Return the version as a C string. + * + * @return The version as a C string. + */ +const char *longBowReportANSITerminalAbout_Version(void); + +/** + * Return the About text as a C string. + * + * @return The About text as a C string. + */ +const char *longBowReportANSITerminalAbout_About(void); + +/** + * Return the minimum copyright notice as a C string. + * + * @return The minimum copyright notice as a C string. + */ +const char *longBowReportANSITerminalAbout_MiniNotice(void); + +/** + * Return the short copyright notice as a C string. + * + * @return The short copyright notice as a C string. + */ +const char *longBowReportANSITerminalAbout_ShortNotice(void); + +/** + * Return the long copyright notice as a C string. + * + * @return The long copyright notice as a C string. + */ +const char *longBowReportANSITerminalAbout_LongNotice(void); + +#endif // longBowReportANSITerminal_About_h diff --git a/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.c b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.c new file mode 100644 index 00000000..60ca4d42 --- /dev/null +++ b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> + +#include <LongBow/Reporting/ANSITerm/longBowReport_Runtime.h> +#include <LongBow/private/longBow_Memory.h> + +static const char *ansiRed = "\x1b[31m"; +static const char *ansiGreen = "\x1b[32m"; +static const char *ansiYellow = "\x1b[33m"; +static const char *ansiMagenta = "\x1b[35m"; +static const char *ansiReset = "\x1b[0m"; + +static void +_printGreen(void) +{ + printf("%s", ansiGreen); +} + +static void +_printYellow(void) +{ + printf("%s", ansiYellow); +} + +static void +_printMagenta(void) +{ + printf("%s", ansiMagenta); +} + +static void +_printReset(void) +{ + printf("%s", ansiReset); + fflush(stdout); +} + +static void +_longBowReportRuntime_RedPrintf(const char *format, va_list args) +{ + longBowReportRuntime_PrintRed(); + vprintf(format, args); + _printReset(); +} + +static void +_longBowReportRuntime_YellowPrintf(const char *format, va_list args) +{ + _printYellow(); + vprintf(format, args); + _printReset(); +} + +void +longBowReportRuntime_PrintRed(void) +{ + printf("%s", ansiRed); +} + +void +longBowReportRuntime_RedPrintf(const char *format, ...) +{ + va_list args; + va_start(args, format); + _longBowReportRuntime_RedPrintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_GreenPrintf(const char *format, ...) +{ + _printGreen(); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + _printReset(); +} + +void +longBowReportRuntime_MagentaPrintf(const char *format, ...) +{ + _printMagenta(); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + _printReset(); +} + +void +longBowReportRuntime_YellowPrintf(const char *format, ...) +{ + va_list args; + va_start(args, format); + + _longBowReportRuntime_YellowPrintf(format, args); + + va_end(args); +} + +void +longBowReportRuntime_ParseSuppress(LongBowReportConfig *result, const char *key) +{ + for (size_t i = 0; i < strlen(key); i++) { + if (*key == 'X') { + result->suppress_report.untested = 1; + } else if (*key == '.') { + result->suppress_report.succeeded = 1; + } else if (*key == 'S') { + result->suppress_report.skipped = 1; + } else if (*key == 'W') { + result->suppress_report.warned = 1; + } else if (*key == 's') { + result->suppress_report.setup_failed = 1; + } else if (*key == 't') { + result->suppress_report.teardown_failed = 1; + } else if (*key == 'w') { + result->suppress_report.teardown_warned = 1; + } else if (*key == 'F') { + result->suppress_report.failed = 1; + } else if (*key == 'T') { + result->suppress_report.stopped = 1; + } else if (*key == 'U') { + result->suppress_report.unimplemented = 1; + } else { + printf("Unknown suppression key '%c'\n", *key); + } + } +} + +LongBowReportConfig * +longBowReportRuntime_Create(int argc, char *argv[]) +{ + static const char *prefix = "--report"; + size_t prefixLength = strlen(prefix); + + LongBowReportConfig *result = longBowMemory_Allocate(sizeof(LongBowReportConfig)); + + for (int i = 0; i < argc; i++) { + if (strncmp(prefix, argv[i], prefixLength) == 0) { + if (strcmp("--report-suppress", argv[i]) == 0) { + longBowReportRuntime_ParseSuppress(result, argv[i + 1]); + i++; + } + } else if (strcmp("--help", argv[i]) == 0) { + printf("Options for LongBow Report ANSI Terminal\n"); + printf(" --report-suppress [STFU.XWstw] Suppress the display of specific reports.\n"); + printf(" S - suppress the report of a skipped test.\n"); + printf(" T - suppress the report of a stopped test.\n"); + printf(" F - suppress the report of a failed test.\n"); + printf(" U - suppress the report of an unimplemented test.\n"); + printf(" . - suppress the report of a successful test.\n"); + printf(" X - suppress the report of an untested test.\n"); + printf(" W - suppress the report of a warned test.\n"); + printf(" s - suppress the report of a setup failure.\n"); + printf(" t - suppress the report of a tear-down failure.\n"); + printf(" w - suppress the report of a tear-down warning.\n"); + free(result); + return NULL; + } + } + + return result; +} + +void +longBowReportRuntime_Destroy(LongBowReportConfig **reportPtr) +{ + longBowMemory_Deallocate((void **) reportPtr); +} + +static void +_EventPrint(const LongBowEvent *event) +{ + if (longBowEventType_IsSuppressAlert(longBowEvent_GetEventType(event)) == false) { + char *location = longBowLocation_ToString(longBowEvent_GetLocation(event)); + printf("%s %s %s %s\r\n", + longBowEvent_GetName(event), location, longBowEvent_GetKind(event), longBowEvent_GetMessage(event)); + + if (longBowEventType_IsSuppressBacktrace(longBowEvent_GetEventType(event)) == false) { + char **strs = longBowEvent_CreateSymbolicCallstack(event); + if (strs != NULL) { + for (size_t i = 0; i < longBowEvent_GetCallStackLength(event); ++i) { + printf("%s\r\n", strs[i]); + } + free(strs); + } + } + fflush(stdout); + free(location); + } +} + +void +longBowReportRuntime_Event(const LongBowEvent *event) +{ + LongBowStatus status = longBowEventType_GetStatus(longBowEvent_GetEventType(event)); + switch (status) { + case LongBowStatus_DONTCARE: + case LongBowStatus_UNTESTED: + break; + + /* successful */ + case LONGBOW_STATUS_SUCCEEDED: + // If this happens, there is an error in the encoding of the LongBowEventType. + longBowReportRuntime_PrintRed(); + _EventPrint(event); + _printReset(); + break; + + case LongBowStatus_WARNED: + case LongBowStatus_TEARDOWN_WARNED: + case LONGBOW_STATUS_SKIPPED: + case LongBowStatus_UNIMPLEMENTED: + case LongBowStatus_IMPOTENT: + case LONGBOW_STATUS_MEMORYLEAK: + case LONGBOW_STATUS_SETUP_SKIPTESTS: + _printYellow(); + _EventPrint(event); + _printReset(); + break; + + /* failure */ + case LONGBOW_STATUS_FAILED: + case LongBowStatus_STOPPED: + case LONGBOW_STATUS_TEARDOWN_FAILED: + case LONGBOW_STATUS_SETUP_FAILED: + case LongBowStatus_SIGNALLED: + longBowReportRuntime_PrintRed(); + _EventPrint(event); + _printReset(); + break; + + case LongBowStatus_LIMIT: // fall through + default: + _printYellow(); + _EventPrint(event); + _printReset(); + break; + } +} + +void +longBowReportRuntime_Message(const char *format, ...) +{ + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Warning(const char *format, ...) +{ + va_list args; + va_start(args, format); + longBowReportRuntime_YellowPrintf("WARNING "); + _longBowReportRuntime_YellowPrintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Error(const char *format, ...) +{ + va_list args; + va_start(args, format); + longBowReportRuntime_RedPrintf("FAILURE "); + _longBowReportRuntime_RedPrintf(format, args); + va_end(args); +} diff --git a/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.h b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.h new file mode 100755 index 00000000..2e03f322 --- /dev/null +++ b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Runtime.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file ANSITerm/longBowReport_Runtime.h + * @ingroup reporting + * @brief ANSI Terminal Reporting + * + */ +#ifndef LongBow_longBowReport_ANSITerm_Runtime_h +#define LongBow_longBowReport_ANSITerm_Runtime_h + +#include <stdio.h> +#include <stdarg.h> + +#include <LongBow/Reporting/longBowReport_Runtime.h> + +/** + * Begin printing in red. + * + */ +void longBowReportRuntime_PrintRed(void); + +/** + * Print the formatted string in red. + * + */ +void longBowReportRuntime_RedPrintf(const char *format, ...); + +/** + * Print the formatted string in green. + * + */ +void longBowReportRuntime_GreenPrintf(const char *format, ...); + +/** + * Print the formatted string in yellow. + * + */ +void longBowReportRuntime_YellowPrintf(const char *format, ...); + +/** + * Print the formatted string in magenta. + * + */ +void longBowReportRuntime_MagentaPrintf(const char *format, ...); + +/** + * Parse the given key and set the corresponding LongBowReportConfig to suppress reports. + * + * @param [in] config A valid LongBowReportConfig instance. + * @param [in] key A nul-terminated C string consisting of one or more of the characters, X.SWstwFTU + */ +void longBowReportRuntime_ParseSuppress(LongBowReportConfig *config, const char *key); +#endif // LongBow_longBowReport_ANSITerm_Runtime_h diff --git a/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Testing.c b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Testing.c new file mode 100644 index 00000000..d1952210 --- /dev/null +++ b/longbow/src/LongBow/Reporting/ANSITerm/longBowReport_Testing.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> + +#include <LongBow/Reporting/ANSITerm/longBowReport_Runtime.h> +#include <LongBow/Reporting/longBowReport_Testing.h> +#include <LongBow/private/longBow_String.h> + +static const LongBowTestRunner * +_testRunnerSilent(const LongBowTestRunner *testRunner) +{ + LongBowStatus status = longBowTestRunner_GetStatus(testRunner); + if (longBowStatus_IsSuccessful(status)) { + longBowReportRuntime_GreenPrintf("%s %s\n", longBowTestRunner_GetName(testRunner), longBowStatus_ToString(status)); + } else if (longBowStatus_IsSuccessful(status)) { + longBowReportRuntime_YellowPrintf("%s %s\n", longBowTestRunner_GetName(testRunner), longBowStatus_ToString(status)); + } else { + longBowReportRuntime_RedPrintf("%s %s\n", longBowTestRunner_GetName(testRunner), longBowStatus_ToString(status)); + } + return testRunner; +} + +static const LongBowTestRunner * +_testRunnerDetail(const LongBowTestRunner *testRunner) +{ + size_t nFixtures = longBowTestRunner_GetFixtureCount(testRunner); + + printf("\n"); + printf("%s: %zd fixture%s\n", longBowTestRunner_GetName(testRunner), nFixtures, (nFixtures == 1 ? "" : "s")); + + for (size_t i = 0; i < nFixtures; i++) { + LongBowTestFixture *fixture = longBowTestRunner_GetFixture(testRunner, i); + longBowReportTesting_TestFixture(fixture); + } + return testRunner; +} + +const LongBowTestRunner * +longBowReportTesting_TestRunner(const LongBowTestRunner *testRunner) +{ + if (longBowConfig_GetBoolean(longBowTestRunner_GetConfiguration(testRunner), false, "silent")) { + return _testRunnerSilent(testRunner); + } else { + return _testRunnerDetail(testRunner); + } +} + +static unsigned int +_totalSucceeded(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSucceeded + summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalWarned(const LongBowTestFixtureSummary *summary) +{ + return summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalFailed(const LongBowTestFixtureSummary *summary) +{ + return summary->totalFailed + summary->totalSignalled + summary->totalStopped + summary->totalTearDownFailed; +} + +static unsigned int +_totalIncomplete(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSetupFailed + summary->totalSkipped + summary->totalUnimplemented; +} + +static void +_reportSummary(const LongBowTestFixture *testFixture) +{ + const LongBowTestFixtureSummary *summary = longBowTestFixture_GetSummary(testFixture); + + char *fixtureString = longBowTestFixture_ToString(testFixture); + + printf("%s: Ran %u test case%s.", fixtureString, summary->totalTested, summary->totalTested == 1 ? "" : "s"); + free(fixtureString); + + if (summary->totalTested > 0) { + printf(" %d%% (%d) succeeded", _totalSucceeded(summary) * 100 / summary->totalTested, _totalSucceeded(summary)); + + if (_totalWarned(summary) > 0) { + printf(" %d%% (%d) with warnings", _totalWarned(summary) * 100 / _totalSucceeded(summary), _totalWarned(summary)); + } + if (_totalFailed(summary) != 0) { + printf(", %d%% (%d) failed", _totalFailed(summary) * 100 / summary->totalTested, _totalFailed(summary)); + } + if (_totalIncomplete(summary) > 0) { + printf(", %d%% (%d) incomplete", _totalIncomplete(summary) * 100 / summary->totalTested, _totalIncomplete(summary)); + } + } + + printf("\n"); +} + +const LongBowTestFixture * +longBowReportTesting_TestFixture(const LongBowTestFixture *testFixture) +{ + size_t nTestCases = longBowTestFixture_GetTestCaseCount(testFixture); + + _reportSummary(testFixture); + + for (size_t i = 0; i < nTestCases; i++) { + LongBowTestCase *testCase = longBowTestFixture_GetTestCase(testFixture, i); + longBowReportTesting_TestCase(testCase); + } + return testFixture; +} + +const LongBowTestCase * +longBowReportTesting_TestCase(const LongBowTestCase *testCase) +{ + LongBowRuntimeResult *testCaseResult = longBowTestCase_GetActualResult(testCase); + + char *rusageString = longBowReportRuntime_RUsageToString(longBowRuntimeResult_GetRUsage(testCaseResult)); + char *elapsedTimeString = longBowReportRuntime_TimevalToString(longBowRuntimeResult_GetElapsedTime(testCaseResult)); + char *statusString = longBowStatus_ToString(longBowRuntimeResult_GetStatus(testCaseResult)); + char *testCaseString = longBowTestCase_ToString(testCase); + + LongBowString *str = longBowString_CreateFormat("%s %s %s %zd %s\n", + testCaseString, + elapsedTimeString, + rusageString, + longBowRuntimeResult_GetEventEvaluationCount(longBowTestCase_GetActualResult(testCase)), + statusString); + char *string = longBowString_ToString(str); + + if (longBowTestCase_IsFailed(testCase)) { + longBowReportRuntime_RedPrintf("%s", string); + } else if (longBowTestCase_IsWarning(testCase)) { + longBowReportRuntime_YellowPrintf("%s", string); + } else if (longBowTestCase_IsIncomplete(testCase)) { + longBowReportRuntime_YellowPrintf("%s", string); + } else if (longBowTestCase_IsSuccessful(testCase)) { + longBowReportRuntime_GreenPrintf("%s", string); + } else { + longBowReportRuntime_RedPrintf("%s", string); + } + + free(string); + free(testCaseString); + free(statusString); + free(elapsedTimeString); + free(rusageString); + + return testCase; +} + +void +longBowReportTesting_DisplayTestCaseResult(const LongBowTestCase *testCase __attribute__((unused))) +{ +} + +void +longBowReportTesting_Trace(const char *restrict format, ...) +{ + va_list ap; + va_start(ap, format); + char *message; + if (vasprintf(&message, format, ap) == -1) { + va_end(ap); + return; + } + va_end(ap); + + longBowReportRuntime_MagentaPrintf("%s\n", message); + fflush(stdout); + free(message); +} diff --git a/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.c b/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.c new file mode 100644 index 00000000..db31ce82 --- /dev/null +++ b/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.c @@ -0,0 +1,44 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#include "longBowReportAndroid_About.h" + +const char *longBowReportAndroid_What = "@(#)" "LongBow Android Reporter " RELEASE_VERSION " 2017-02-14T21:38:07.631504" + "@(#)" "\tCopyright (c) 2017 Cisco and/or its affiliates."; + +const char * +longBowReportAndroidAbout_Name(void) +{ + return "LongBow Android Reporter"; +} + +const char * +longBowReportAndroidAbout_Version(void) +{ + return RELEASE_VERSION; +} + +const char * +longBowReportAndroidAbout_About(void) +{ + return "LongBow Android Reporter "RELEASE_VERSION " 2017-02-14T21:38:07.631504" "\nCopyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportAndroidAbout_MiniNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportAndroidAbout_ShortNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportAndroidAbout_LongNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n"; +} + diff --git a/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.h b/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.h new file mode 100755 index 00000000..9a90f17e --- /dev/null +++ b/longbow/src/LongBow/Reporting/Android/longBowReportAndroid_About.h @@ -0,0 +1,54 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#ifndef longBowReportAndroid_About_h +#define longBowReportAndroid_About_h +/** + * Embedded string containing information for the what(1) command. + * + */ +extern const char *longBowReportAndroid_What; + +/** + * Return the name as a C string. + * + * @return The name as a C string. + */ +const char *longBowReportAndroidAbout_Name(void); + +/** + * Return the version as a C string. + * + * @return The version as a C string. + */ +const char *longBowReportAndroidAbout_Version(void); + +/** + * Return the About text as a C string. + * + * @return The About text as a C string. + */ +const char *longBowReportAndroidAbout_About(void); + +/** + * Return the minimum copyright notice as a C string. + * + * @return The minimum copyright notice as a C string. + */ +const char *longBowReportAndroidAbout_MiniNotice(void); + +/** + * Return the short copyright notice as a C string. + * + * @return The short copyright notice as a C string. + */ +const char *longBowReportAndroidAbout_ShortNotice(void); + +/** + * Return the long copyright notice as a C string. + * + * @return The long copyright notice as a C string. + */ +const char *longBowReportAndroidAbout_LongNotice(void); + +#endif // longBowReportAndroid_About_h diff --git a/longbow/src/LongBow/Reporting/Android/longBowReport_Runtime.c b/longbow/src/LongBow/Reporting/Android/longBowReport_Runtime.c new file mode 100644 index 00000000..4bf13482 --- /dev/null +++ b/longbow/src/LongBow/Reporting/Android/longBowReport_Runtime.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> + +#include <LongBow/Reporting/longBowReport_Runtime.h> +#include <LongBow/private/longBow_Memory.h> + +LongBowReportConfig * +longBowReportRuntime_Create(int argc, char *argv[argc]) +{ + LongBowReportConfig *result = longBowMemory_Allocate(sizeof(LongBowReportConfig)); + + return result; +} + +void +longBowReportRuntime_Destroy(LongBowReportConfig **reportPtr) +{ + longBowMemory_Deallocate((void **) reportPtr); +} + +void +longBowReportRuntime_Event(const LongBowEvent *event) +{ + if (longBowEventType_IsSuppressAlert(longBowEvent_GetEventType(event)) == false) { + char *location = longBowLocation_ToString(longBowEvent_GetLocation(event)); + printf("%s %s %s %s\r\n", + longBowEvent_GetName(event), location, longBowEvent_GetKind(event), longBowEvent_GetMessage(event)); + + if (longBowEventType_IsSuppressBacktrace(longBowEvent_GetEventType(event)) == false) { + char **strs = longBowEvent_CreateSymbolicCallstack(event); + if (strs != NULL) { + for (size_t i = 0; i < longBowEvent_GetCallStackLength(event); ++i) { + fputs(strs[i], stdout); + fputs("\r\n", stdout); + } + free(strs); + } + } + fflush(stdout); + + free(location); + } +} + +void +longBowReportRuntime_Message(const char *format, ...) +{ + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Warning(const char *format, ...) +{ + printf("WARNING"); + + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Error(const char *format, ...) +{ + printf("ERROR"); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} diff --git a/longbow/src/LongBow/Reporting/Android/longBowReport_Testing.c b/longbow/src/LongBow/Reporting/Android/longBowReport_Testing.c new file mode 100755 index 00000000..dd3835e8 --- /dev/null +++ b/longbow/src/LongBow/Reporting/Android/longBowReport_Testing.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> + +#ifdef __ANDROID__ +#include <android/log.h> +#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "CCNx", __VA_ARGS__); +#endif + +#include <LongBow/Reporting/longBowReport_Testing.h> +#include <LongBow/private/longBow_String.h> + +static const LongBowTestRunner * +_testRunnerSilent(const LongBowTestRunner *testRunner) +{ + LongBowStatus status = longBowTestRunner_GetStatus(testRunner); + + printf("%s %s\n", longBowTestRunner_GetName(testRunner), longBowStatus_ToString(status)); + return testRunner; +} + +static const LongBowTestRunner * +_testRunnerDetail(const LongBowTestRunner *testRunner) +{ + size_t nFixtures = longBowTestRunner_GetFixtureCount(testRunner); + + printf("\r\n"); + printf("%s: %zd fixture%s\r\n", longBowTestRunner_GetName(testRunner), nFixtures, (nFixtures == 1 ? "" : "s")); + + for (size_t i = 0; i < nFixtures; i++) { + LongBowTestFixture *fixture = longBowTestRunner_GetFixture(testRunner, i); + longBowReportTesting_TestFixture(fixture); + } + return testRunner; +} + +const LongBowTestRunner * +longBowReportTesting_TestRunner(const LongBowTestRunner *testRunner) +{ + if (longBowConfig_GetBoolean(longBowTestRunner_GetConfiguration(testRunner), false, "silent")) { + return _testRunnerSilent(testRunner); + } else { + return _testRunnerDetail(testRunner); + } +} + +static unsigned int +_totalSucceeded(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSucceeded + summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalWarned(const LongBowTestFixtureSummary *summary) +{ + return summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalFailed(const LongBowTestFixtureSummary *summary) +{ + return summary->totalFailed + summary->totalSignalled + summary->totalStopped + summary->totalTearDownFailed; +} + +static unsigned int +_totalIncomplete(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSetupFailed + summary->totalSkipped + summary->totalUnimplemented; +} + +static void +_reportSummary(const LongBowTestFixture *testFixture) +{ + const LongBowTestFixtureSummary *summary = longBowTestFixture_GetSummary(testFixture); + + char *fixtureString = longBowTestFixture_ToString(testFixture); + + printf("%s: Ran %u test case%s.", fixtureString, summary->totalTested, summary->totalTested == 1 ? "" : "s"); + free(fixtureString); + + if (summary->totalTested > 0) { + printf(" %d%% (%d) succeeded", _totalSucceeded(summary) * 100 / summary->totalTested, _totalSucceeded(summary)); + + if (_totalWarned(summary) > 0) { + printf(" %d%% (%d) with warnings", _totalWarned(summary) * 100 / _totalSucceeded(summary), _totalWarned(summary)); + } + if (_totalFailed(summary) != 0) { + printf(", %d%% (%d) failed", _totalFailed(summary) * 100 / summary->totalTested, _totalFailed(summary)); + } + if (_totalIncomplete(summary) > 0) { + printf(", %d%% (%d) incomplete", _totalIncomplete(summary) * 100 / summary->totalTested, _totalIncomplete(summary)); + } + } + printf("\n"); +} + +const LongBowTestFixture * +longBowReportTesting_TestFixture(const LongBowTestFixture *testFixture) +{ + size_t nTestCases = longBowTestFixture_GetTestCaseCount(testFixture); + + _reportSummary(testFixture); + + for (size_t i = 0; i < nTestCases; i++) { + LongBowTestCase *testCase = longBowTestFixture_GetTestCase(testFixture, i); + longBowReportTesting_TestCase(testCase); + } + return testFixture; +} + +const LongBowTestCase * +longBowReportTesting_TestCase(const LongBowTestCase *testCase) +{ + LongBowRuntimeResult *testCaseResult = longBowTestCase_GetActualResult(testCase); + + char *rusageString = longBowReportRuntime_RUsageToString(longBowRuntimeResult_GetRUsage(testCaseResult)); + + char *elapsedTimeString = longBowReportRuntime_TimevalToString(longBowRuntimeResult_GetElapsedTime(testCaseResult)); + + char *statusString = longBowStatus_ToString(longBowTestCase_GetActualResult(testCase)->status); + char *testCaseString = longBowTestCase_ToString(testCase); + + LongBowString *string = longBowString_CreateFormat("%10s %s %s %zd %s\n", + testCaseString, + elapsedTimeString, + rusageString, + longBowRuntimeResult_GetEventEvaluationCount(longBowTestCase_GetActualResult(testCase)), + statusString); + longBowString_Write(string, stdout); + longBowString_Destroy(&string); + + free(testCaseString); + free(statusString); + free(elapsedTimeString); + free(rusageString); + + return testCase; +} + +void +longBowReportTesting_DisplayTestCaseResult(const LongBowTestCase *testCase) +{ + const LongBowRuntimeResult *testCaseResult = longBowTestCase_GetActualResult(testCase); + + switch (testCaseResult->status) { + case LongBowStatus_UNTESTED: printf("X"); break; + case LONGBOW_STATUS_SUCCEEDED: printf("."); break; + case LONGBOW_STATUS_SKIPPED: printf("S"); break; + case LongBowStatus_WARNED: printf("W"); break; + case LONGBOW_STATUS_SETUP_FAILED: printf("s"); break; + case LONGBOW_STATUS_TEARDOWN_FAILED: printf("t"); break; + case LongBowStatus_TEARDOWN_WARNED: printf("w"); break; + case LONGBOW_STATUS_FAILED: printf("F"); break; + case LongBowStatus_STOPPED: printf("T"); break; + case LongBowStatus_UNIMPLEMENTED: printf("U"); break; + case LongBowStatus_IMPOTENT: printf("I"); break; + default: + if (testCaseResult->status >= LongBowStatus_SIGNALLED) { + printf("K"); + } else { + printf("?"); + } + } + fflush(stdout); +} + +void +longBowReportTesting_Trace(const char *restrict format, ...) +{ + va_list ap; + va_start(ap, format); + char *message; + if (vasprintf(&message, format, ap) == -1) { + return; + } + va_end(ap); + + printf("%s\n", message); + free(message); +} diff --git a/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.c b/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.c new file mode 100644 index 00000000..aa385033 --- /dev/null +++ b/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.c @@ -0,0 +1,44 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#include "longBowReportTextPlain_About.h" + +const char *longBowReportTextPlain_What = "@(#)" "LongBow Text Plain Reporter " RELEASE_VERSION " 2017-02-14T21:40:52.491677" + "@(#)" "\tCopyright (c) 2017 Cisco and/or its affiliates."; + +const char * +longBowReportTextPlainAbout_Name(void) +{ + return "LongBow Text Plain Reporter"; +} + +const char * +longBowReportTextPlainAbout_Version(void) +{ + return RELEASE_VERSION; +} + +const char * +longBowReportTextPlainAbout_About(void) +{ + return "LongBow Text Plain Reporter "RELEASE_VERSION " 2017-02-14T21:40:52.491677" "\nCopyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportTextPlainAbout_MiniNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportTextPlainAbout_ShortNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowReportTextPlainAbout_LongNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n"; +} + diff --git a/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.h b/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.h new file mode 100755 index 00000000..08f69eb2 --- /dev/null +++ b/longbow/src/LongBow/Reporting/TextPlain/longBowReportTextPlain_About.h @@ -0,0 +1,54 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#ifndef longBowReportTextPlain_About_h +#define longBowReportTextPlain_About_h +/** + * Embedded string containing information for the what(1) command. + * + */ +extern const char *longBowReportTextPlain_What; + +/** + * Return the name as a C string. + * + * @return The name as a C string. + */ +const char *longBowReportTextPlainAbout_Name(void); + +/** + * Return the version as a C string. + * + * @return The version as a C string. + */ +const char *longBowReportTextPlainAbout_Version(void); + +/** + * Return the About text as a C string. + * + * @return The About text as a C string. + */ +const char *longBowReportTextPlainAbout_About(void); + +/** + * Return the minimum copyright notice as a C string. + * + * @return The minimum copyright notice as a C string. + */ +const char *longBowReportTextPlainAbout_MiniNotice(void); + +/** + * Return the short copyright notice as a C string. + * + * @return The short copyright notice as a C string. + */ +const char *longBowReportTextPlainAbout_ShortNotice(void); + +/** + * Return the long copyright notice as a C string. + * + * @return The long copyright notice as a C string. + */ +const char *longBowReportTextPlainAbout_LongNotice(void); + +#endif // longBowReportTextPlain_About_h diff --git a/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Runtime.c b/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Runtime.c new file mode 100755 index 00000000..b5cb4dfc --- /dev/null +++ b/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Runtime.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> + +#include <LongBow/Reporting/longBowReport_Runtime.h> +#include <LongBow/private/longBow_Memory.h> + +LongBowReportConfig * +longBowReportRuntime_Create(int argc, char *argv[argc]) +{ + LongBowReportConfig *result = longBowMemory_Allocate(sizeof(LongBowReportConfig)); + + return result; +} + +void +longBowReportRuntime_Destroy(LongBowReportConfig **reportPtr) +{ + longBowMemory_Deallocate((void **) reportPtr); +} + +void +longBowReportRuntime_Event(const LongBowEvent *event) +{ + if (longBowEventType_IsSuppressAlert(longBowEvent_GetEventType(event)) == false) { + char *location = strdup(""); + if (longBowEvent_GetLocation(event) != NULL) { + free(location); + location = longBowLocation_ToString(longBowEvent_GetLocation(event)); + } + printf("%s %s %s %s\r\n", + longBowEvent_GetName(event), location, longBowEvent_GetKind(event), longBowEvent_GetMessage(event)); + + if (longBowEventType_IsSuppressBacktrace(longBowEvent_GetEventType(event)) == false) { + char **strs = longBowEvent_CreateSymbolicCallstack(event); + if (strs != NULL) { + for (size_t i = 0; i < longBowEvent_GetCallStackLength(event); ++i) { + fputs(strs[i], stdout); + fputs("\r\n", stdout); + } + free(strs); + } + } + fflush(stdout); + + free(location); + } +} + +void +longBowReportRuntime_Message(const char *format, ...) +{ + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Warning(const char *format, ...) +{ + va_list args; + va_start(args, format); + printf("WARNING "); + vprintf(format, args); + va_end(args); +} + +void +longBowReportRuntime_Error(const char *format, ...) +{ + va_list args; + va_start(args, format); + printf("ERROR "); + vprintf(format, args); + va_end(args); +} diff --git a/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Testing.c b/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Testing.c new file mode 100755 index 00000000..3bed5cac --- /dev/null +++ b/longbow/src/LongBow/Reporting/TextPlain/longBowReport_Testing.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> + +#include <LongBow/Reporting/longBowReport_Testing.h> +#include <LongBow/private/longBow_String.h> + +static const LongBowTestRunner * +_testRunnerSilent(const LongBowTestRunner *testRunner) +{ + LongBowStatus status = longBowTestRunner_GetStatus(testRunner); + + printf("%s %s\n", longBowTestRunner_GetName(testRunner), longBowStatus_ToString(status)); + return testRunner; +} + +static const LongBowTestRunner * +_testRunnerDetail(const LongBowTestRunner *testRunner) +{ + size_t nFixtures = longBowTestRunner_GetFixtureCount(testRunner); + + printf("\r\n"); + printf("%s: %zd fixture%s\r\n", longBowTestRunner_GetName(testRunner), nFixtures, (nFixtures == 1 ? "" : "s")); + + for (size_t i = 0; i < nFixtures; i++) { + LongBowTestFixture *fixture = longBowTestRunner_GetFixture(testRunner, i); + longBowReportTesting_TestFixture(fixture); + } + return testRunner; +} + +const LongBowTestRunner * +longBowReportTesting_TestRunner(const LongBowTestRunner *testRunner) +{ + if (longBowConfig_GetBoolean(longBowTestRunner_GetConfiguration(testRunner), false, "silent")) { + return _testRunnerSilent(testRunner); + } else { + return _testRunnerDetail(testRunner); + } +} + +static unsigned int +_totalSucceeded(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSucceeded + summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalWarned(const LongBowTestFixtureSummary *summary) +{ + return summary->totalWarned + summary->totalTearDownWarned; +} + +static unsigned int +_totalFailed(const LongBowTestFixtureSummary *summary) +{ + return summary->totalFailed + summary->totalSignalled + summary->totalStopped + summary->totalTearDownFailed; +} + +static unsigned int +_totalIncomplete(const LongBowTestFixtureSummary *summary) +{ + return summary->totalSetupFailed + summary->totalSkipped + summary->totalUnimplemented; +} + +static void +_reportSummary(const LongBowTestFixture *testFixture) +{ + const LongBowTestFixtureSummary *summary = longBowTestFixture_GetSummary(testFixture); + + char *fixtureString = longBowTestFixture_ToString(testFixture); + + printf("%s: Ran %u test case%s.", fixtureString, summary->totalTested, summary->totalTested == 1 ? "" : "s"); + free(fixtureString); + + if (summary->totalTested > 0) { + printf(" %d%% (%d) succeeded", _totalSucceeded(summary) * 100 / summary->totalTested, _totalSucceeded(summary)); + + if (_totalWarned(summary) > 0) { + printf(" %d%% (%d) with warnings", _totalWarned(summary) * 100 / _totalSucceeded(summary), _totalWarned(summary)); + } + if (_totalFailed(summary) != 0) { + printf(", %d%% (%d) failed", _totalFailed(summary) * 100 / summary->totalTested, _totalFailed(summary)); + } + if (_totalIncomplete(summary) > 0) { + printf(", %d%% (%d) incomplete", _totalIncomplete(summary) * 100 / summary->totalTested, _totalIncomplete(summary)); + } + } + printf("\n"); +} + +const LongBowTestFixture * +longBowReportTesting_TestFixture(const LongBowTestFixture *testFixture) +{ + size_t nTestCases = longBowTestFixture_GetTestCaseCount(testFixture); + + _reportSummary(testFixture); + + for (size_t i = 0; i < nTestCases; i++) { + LongBowTestCase *testCase = longBowTestFixture_GetTestCase(testFixture, i); + longBowReportTesting_TestCase(testCase); + } + return testFixture; +} + +const LongBowTestCase * +longBowReportTesting_TestCase(const LongBowTestCase *testCase) +{ + LongBowRuntimeResult *testCaseResult = longBowTestCase_GetActualResult(testCase); + + char *rusageString = longBowReportRuntime_RUsageToString(longBowRuntimeResult_GetRUsage(testCaseResult)); + + char *elapsedTimeString = longBowReportRuntime_TimevalToString(longBowRuntimeResult_GetElapsedTime(testCaseResult)); + + char *statusString = longBowStatus_ToString(longBowTestCase_GetActualResult(testCase)->status); + char *testCaseString = longBowTestCase_ToString(testCase); + + LongBowString *string = longBowString_CreateFormat("%10s %s %s %zd %s\n", + testCaseString, + elapsedTimeString, + rusageString, + longBowRuntimeResult_GetEventEvaluationCount(longBowTestCase_GetActualResult(testCase)), + statusString); + longBowString_Write(string, stdout); + longBowString_Destroy(&string); + + free(testCaseString); + free(statusString); + free(elapsedTimeString); + free(rusageString); + + return testCase; +} + +void +longBowReportTesting_DisplayTestCaseResult(const LongBowTestCase *testCase) +{ + const LongBowRuntimeResult *testCaseResult = longBowTestCase_GetActualResult(testCase); + + switch (testCaseResult->status) { + case LongBowStatus_UNTESTED: printf("X"); break; + case LONGBOW_STATUS_SUCCEEDED: printf("."); break; + case LONGBOW_STATUS_SKIPPED: printf("S"); break; + case LongBowStatus_WARNED: printf("W"); break; + case LONGBOW_STATUS_SETUP_FAILED: printf("s"); break; + case LONGBOW_STATUS_TEARDOWN_FAILED: printf("t"); break; + case LongBowStatus_TEARDOWN_WARNED: printf("w"); break; + case LONGBOW_STATUS_FAILED: printf("F"); break; + case LongBowStatus_STOPPED: printf("T"); break; + case LongBowStatus_UNIMPLEMENTED: printf("U"); break; + case LongBowStatus_IMPOTENT: printf("I"); break; + default: + if (testCaseResult->status >= LongBowStatus_SIGNALLED) { + printf("K"); + } else { + printf("?"); + } + } + fflush(stdout); +} + +void +longBowReportTesting_Trace(const char *restrict format, ...) +{ + va_list ap; + va_start(ap, format); + char *message; + if (vasprintf(&message, format, ap) == -1) { + return; + } + va_end(ap); + + printf("%s\n", message); + free(message); +} diff --git a/longbow/src/LongBow/Reporting/longBowReport_Runtime.c b/longbow/src/LongBow/Reporting/longBowReport_Runtime.c new file mode 100755 index 00000000..2671cf31 --- /dev/null +++ b/longbow/src/LongBow/Reporting/longBowReport_Runtime.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> + +#include <LongBow/Reporting/longBowReport_Runtime.h> + +char * +longBowReportRuntime_TimevalToString(const struct timeval time) +{ + char *string = NULL; + if (asprintf(&string, "%ld.%06lds", time.tv_sec, (long) time.tv_usec) == -1) { + return NULL; + } + return string; +} + +char * +longBowReportRuntime_RUsageToString(const struct rusage *rusage) +{ + char *string; + + char *ru_utime = longBowReportRuntime_TimevalToString(rusage->ru_utime); + char *ru_stime = longBowReportRuntime_TimevalToString(rusage->ru_stime); + + if (asprintf(&string, "%s %s", ru_utime, ru_stime) == -1) { + return NULL; + } + + free(ru_utime); + free(ru_stime); + + return string; +} diff --git a/longbow/src/LongBow/Reporting/longBowReport_Runtime.h b/longbow/src/LongBow/Reporting/longBowReport_Runtime.h new file mode 100755 index 00000000..5682be15 --- /dev/null +++ b/longbow/src/LongBow/Reporting/longBowReport_Runtime.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file Reporting/longBowReport_Runtime.h + * @ingroup reporting + * @brief The LongBow Runtime Report Generator. + * + * This header specifies the interface for an implementation of a LongBow Test Report generator. + * Different implementations of a Test Report generator are used to connect to external environments to hook in + * LongBow unit tests within a larger framework like an IDE or continuous integration system. + * + * There may be many different ways to report the summary of a LongBow Unit Test, + * and the different ways implement the functions prescribed here. + * The resulting object files are then linked with the unit-test according to the kind of report needed. + * + */ +#ifndef LONGBOW_REPORT_RUNTIME_H_ +#define LONGBOW_REPORT_RUNTIME_H_ + +#include <LongBow/longBow_Event.h> + +#include <LongBow/runtime.h> +#include <LongBow/unit-test.h> + +struct longbow_report_config; +/** + * @brief Configuration for a LongBow Test. + */ +typedef struct longbow_report_config LongBowReportConfig; + +/** + * @struct longbow_report_config + * @brief The configuration information for a LongBow Test Report. + */ +struct longbow_report_config { + struct { + unsigned int untested : 1; + unsigned int succeeded : 1; + unsigned int warned : 1; + unsigned int teardown_warned : 1; + unsigned int skipped : 1; + unsigned int unimplemented : 1; + unsigned int failed : 1; + unsigned int stopped : 1; + unsigned int teardown_failed : 1; + unsigned int setup_failed : 1; + unsigned int signalled : 1; + } suppress_report; /**< Bit fields representing which report to suppress. */ +}; + +/** + * Create a LongBowReportConfiguration from a set of parameters. + * + * @param [in] argc The number of parameters in the argv array. + * @param [in] argv An array of C strings. + * + * @return An allocated LongBowReportConfiguration instance that must be dellocted via longBowReport_Destroy. + * + * Example: + * @code + * { + * char *argv[2] = { "arg1", "arg2" }; + * LongBowReportConfig *report = longBowReport_Create(2, argv); + * } + * @endcode + */ +LongBowReportConfig *longBowReportRuntime_Create(int argc, char *argv[]); + +/** + * Destroy a LongBowReportConfig instance. + * + * @param [in,out] configPtr A pointer to a LongBowReportConfig pointer. The value of configPtr will be set to zero. + * + * Example: + * @code + * { + * char *argv[2] = { "arg1", "arg2" }; + * LongBowReportConfig *report = longBowReport_Create(2, argv); + * LongBowReport_Destroy(&report); + * } + * @endcode + */ +void longBowReportRuntime_Destroy(LongBowReportConfig **configPtr); + +/** + * Report a LongBowEvent. + * + * @param [in] event A pointer to a valid LongBowEvent instance. + */ +void longBowReportRuntime_Event(const LongBowEvent *event); + +/** + * Report a message. + * + * @param [in] message A pointer to a nul-terminated C string. + */ +void longBowReportRuntime_Message(const char *message, ...); + +/** + * Report an error message. + * + * An error message reports an unrecoverable error. + * + * @param [in] message A pointer to a nul-terminated C string. + */ +void longBowReportRuntime_Error(const char *message, ...); + +/** + * Report an error message. + * + * An error message reports an recoverable warning. + * + * @param [in] message A pointer to a nul-terminated C string. + */ +void longBowReportRuntime_Warning(const char *message, ...); + +/** + * Format a struct timeval structure. + * + * @param [in] time A struct timeval value. + * + * @return An allocated nul-terminated C string that must be freed via stdlib free(3). + */ +char *longBowReportRuntime_TimevalToString(const struct timeval time); + +/** + * Format a struct rusage struture. + * + * @param [in] rusage A pointer to a valid `struct rusage` instance. + * @return An allocated nul-terminated C string that must be freed via stdlib free(3). + */ +char *longBowReportRuntime_RUsageToString(const struct rusage *rusage); +#endif // LONGBOW_REPORT_RUNTIME_H_ diff --git a/longbow/src/LongBow/Reporting/longBowReport_Testing.c b/longbow/src/LongBow/Reporting/longBowReport_Testing.c new file mode 100755 index 00000000..646a7a05 --- /dev/null +++ b/longbow/src/LongBow/Reporting/longBowReport_Testing.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> + +#include <LongBow/Reporting/longBowReport_Testing.h> diff --git a/longbow/src/LongBow/Reporting/longBowReport_Testing.h b/longbow/src/LongBow/Reporting/longBowReport_Testing.h new file mode 100755 index 00000000..b4b2eaf8 --- /dev/null +++ b/longbow/src/LongBow/Reporting/longBowReport_Testing.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBowReport_Testing.h + * @ingroup reporting + * @brief The LongBow Test Report Generator. + * + * This header specifies the interface for an implementation of a LongBow Test Report generator. + * Different implementations of a Test Report generator are used to connect to external environments to hook in + * LongBow unit tests within a larger framework like an IDE or continuous integration system. + * + */ +#ifndef LONGBOW_REPORT_TESTING_H_ +#define LONGBOW_REPORT_TESTING_H_ + +#include <LongBow/Reporting/longBowReport_Runtime.h> + +#include <LongBow/runtime.h> +#include <LongBow/unit-test.h> + +/** + * Produce a summary report for the given LongBowTestRunner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The given LongBowTestRunner. + */ +const LongBowTestRunner *longBowReportTesting_TestRunner(const LongBowTestRunner *testRunner); + +/** + * Produce a summary report for the given LongBowTestFixture. + * + * @param [in] testFixture A pointer to a LongBowTestFixture instance. + * @return The given LongBowTestFixture. + */ +const LongBowTestFixture *longBowReportTesting_TestFixture(const LongBowTestFixture *testFixture); + +/** + * Produce a summary report for the given LongBowTestCase. + * + * @param [in] testCase A pointer to a LongBowTestCase instance. + * @return The pointer to the given LongBowTestCase. + */ +const LongBowTestCase *longBowReportTesting_TestCase(const LongBowTestCase *testCase); + +/** + * Produce a single character displaying the status of an individual test case. + * + * @param [in] testCase A pointer to a LongBowTestCase instance. + */ +void longBowReportTesting_DisplayTestCaseResult(const LongBowTestCase *testCase); + +/** + * Make a trace report. + * + * @param [in] format A printf-style format string. + */ +void longBowReportTesting_Trace(const char *restrict format, ...); +#endif // LONGBOW_REPORT_TESTING_H_ diff --git a/longbow/src/LongBow/assertions.h b/longbow/src/LongBow/assertions.h new file mode 100644 index 00000000..c175bb1d --- /dev/null +++ b/longbow/src/LongBow/assertions.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file assertions.h + * @ingroup runtime + * @brief Runtime and Test Assertions + * + */ +#ifndef LongBow_assertions_h +#define LongBow_assertions_h + +#ifndef LongBow_runtime_h +#error "Do not include LongBow/assertions.h directly. Include LongBow/runtime.h" +#endif + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include <LongBow/traps.h> +#include <LongBow/tests.h> + +#include <LongBow/longBow_Location.h> +#include <LongBow/longBow_Event.h> + +/** + * @def assertTrue + * @brief Assert that a condition is true. + * + * @param condition If false, the assertion triggers. + * @param ... A printf formatting string (required) and parameters (optional). + * + * Example: + * @code + * { + * assertTrue(2 + 2 == 4, "Adding 2 + 2 did not equal 4."); + * } + * @endcode + */ +#define assertTrue(condition, ...) longBowAssert(&LongBowAssertEvent, (condition), __VA_ARGS__) + +/** + * @def assertFalse + * @brief Assert that a condition is false. + * + * @param condition If true, the assertion triggers. + * @param ... A printf formatting string (required) and parameters (optional). + * Example: + * @code + * { + * assertFalse(2 + 2 == 5, "Adding 2 + 2 must not equal 5."); + * } + * @endcode + */ +#define assertFalse(condition, ...) longBowAssert(&LongBowAssertEvent, !(condition), __VA_ARGS__) + +/** + * @def assertNotNull + * @brief Assert that the given value is not NULL. + * + * @param x If the value is NULL, the assertion triggers. + * @param ... A printf formatting string (required) and parameters (optional). + * Example: + * @code + * void + * function(char *p) + * { + * assertNotNull(p, "Parameter must not be NULL"); + * } + * @endcode + */ +#define assertNotNull(x, ...) longBowAssert(&LongBowAssertEvent, (x) != NULL, __VA_ARGS__) + +/** + * @def assertNull + * @brief Assert that the given value is NULL. + * + * @param x The value to test. + * @param ... A printf formatting string (required) and parameters (optional). + * Example: + * @code + * void + * function(char *p) + * { + * assertNull(p, "Parameter must be NULL"); + * } + * @endcode + */ +#define assertNull(x, ...) longBowAssert(&LongBowAssertEvent, (x) == NULL, __VA_ARGS__) + +/** + * @def assertAligned + * @brief Assert that the given address is aligned according to `alignment`. + * + * Return true of the given address is aligned according to alignment. + * The value for alignment must be a power of 2. + * + * @param address A pointer to memory + * @param alignment A power of 2 representing the memory alignment of address. + * @param ... A printf formatting string (required) and parameters (optional). + * + * Example: + * @code + * void + * function(void *p) + * { + * assertAligned(p, 4, "Parameter must be aligned on 4 byte boundaries"); + * } + * @endcode + */ +#define assertAligned(address, alignment, ...) \ + longBowAssert(&LongBowAssertEvent, longBowRuntime_TestAddressIsAligned((address), (alignment)), __VA_ARGS__) + +/** + * @def assertEqualStrings + * @brief Assert that two strings are equal. + * + * @param expected + * @param actual + * @param ... A printf formatting string (required) and parameters (optional). + * + * Example: + * @code + * { + * assertEqualStrings("hello", "world"); + * } + * @endcode + */ +#define assertEqualStrings(expected, actual) \ + longBowAssert(&LongBowAssertEvent, strcmp((expected), (actual)) == 0, "Expected '%s' actual '%s'", (expected), (actual)) + +/** + * @def assertEqual + * @brief Assert that two values are equal, using a canonical string message. + */ +#define assertEqual(expected, actual, format) \ + assertTrue((expected) == (actual), "Expected=" format " actual=" format, (expected), (actual)) +#endif /* ASSERTIONS_H_ */ + diff --git a/longbow/src/LongBow/command-line/.gitignore b/longbow/src/LongBow/command-line/.gitignore new file mode 100644 index 00000000..c12b3061 --- /dev/null +++ b/longbow/src/LongBow/command-line/.gitignore @@ -0,0 +1,2 @@ +liblongbow-config +*dSYM diff --git a/longbow/src/LongBow/command-line/liblongbow-config.c b/longbow/src/LongBow/command-line/liblongbow-config.c new file mode 100755 index 00000000..5e7bf6cc --- /dev/null +++ b/longbow/src/LongBow/command-line/liblongbow-config.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ + +#include "config.h" + +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#define stringify(x) "" #x "" + +void +printLoaderDirectory(void) +{ + printf("%s\n", LIB_INSTALL_DIR); +} + +void +printIncludeDirectory(void) +{ +} + +void +printVersion(void) +{ +} + +int +main(int argc, char *argv[]) +{ + for (int i = 1; i < argc; i++) { + if (strcmp("-I", argv[i]) == 0) { + printIncludeDirectory(); + } else if (strcmp("-L", argv[i]) == 0) { + printLoaderDirectory(); + } else if (strcmp("-v", argv[i]) == 0) { + printVersion(); + } else { + printf("unknown option '%s'\n", argv[i]); + } + } + return 0; +} diff --git a/longbow/src/LongBow/config.h.in b/longbow/src/LongBow/config.h.in new file mode 100644 index 00000000..75a5edc2 --- /dev/null +++ b/longbow/src/LongBow/config.h.in @@ -0,0 +1,11 @@ +// +// Created by Ignacio Solis on 12/1/15. +// + +#ifndef LONGBOW_CONFIGURATION_H +#define LONGBOW_CONFIGURATION_H + +#define LIB_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@" + +#endif //LONGBOW_CONFIGURATION_H + diff --git a/longbow/src/LongBow/debugging.h b/longbow/src/LongBow/debugging.h new file mode 100755 index 00000000..b19ca486 --- /dev/null +++ b/longbow/src/LongBow/debugging.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file debugging.h + * @brief Debugging Utilities + * + */ +#ifndef LongBow_debugging_h +#define LongBow_debugging_h + +#include <LongBow/longBow_Debug.h> + +#include <LongBow/longBow_MeasureTime.h> + +/** + * @def longBow_function + * @brief The compile time function name. + */ +#if __STDC_VERSION__ >= 199901L +# define longBow_function __func__ +#else +# define longBow_function ((const char *) 0) +#endif + +/** + * @def longBowDebug + * @brief Print a debugging message. + * + * @param ... A printf-style format string followed by a variable number of parameters supplying values for the format string. + */ +#ifndef LONGBOW_DEBUG_DISABLED +# define longBowDebug(...) \ + do { longBowDebug_Message(NULL, longBowLocation_Create(__FILE__, longBow_function, __LINE__), __VA_ARGS__); } while (0) +#else +# define longBowDebug(...) \ + do { } while (0) +#endif +#endif diff --git a/longbow/src/LongBow/longBow_About.c b/longbow/src/LongBow/longBow_About.c new file mode 100644 index 00000000..1a29eacf --- /dev/null +++ b/longbow/src/LongBow/longBow_About.c @@ -0,0 +1,44 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#include "longBow_About.h" + +const char *longBow_What = "@(#)" "longBow " RELEASE_VERSION " 2017-02-14T21:35:02.945622" + "@(#)" "\tCopyright (c) 2017 Cisco and/or its affiliates."; + +const char * +longBowAbout_Name(void) +{ + return "longBow"; +} + +const char * +longBowAbout_Version(void) +{ + return RELEASE_VERSION; +} + +const char * +longBowAbout_About(void) +{ + return "longBow "RELEASE_VERSION " 2017-02-14T21:35:02.945622" "\nCopyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowAbout_MiniNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowAbout_ShortNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\n"; +} + +const char * +longBowAbout_LongNotice(void) +{ + return "Copyright (c) 2017 Cisco and/or its affiliates.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at:\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n\n"; +} + diff --git a/longbow/src/LongBow/longBow_About.h b/longbow/src/LongBow/longBow_About.h new file mode 100755 index 00000000..5941aa6a --- /dev/null +++ b/longbow/src/LongBow/longBow_About.h @@ -0,0 +1,54 @@ +// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED. +// longbow-generate-about 1.0.20170214.46e2c73a 2017-02-14T20:35:31Z + +#ifndef longBow_About_h +#define longBow_About_h +/** + * Embedded string containing information for the what(1) command. + * + */ +extern const char *longBow_What; + +/** + * Return the name as a C string. + * + * @return The name as a C string. + */ +const char *longBowAbout_Name(void); + +/** + * Return the version as a C string. + * + * @return The version as a C string. + */ +const char *longBowAbout_Version(void); + +/** + * Return the About text as a C string. + * + * @return The About text as a C string. + */ +const char *longBowAbout_About(void); + +/** + * Return the minimum copyright notice as a C string. + * + * @return The minimum copyright notice as a C string. + */ +const char *longBowAbout_MiniNotice(void); + +/** + * Return the short copyright notice as a C string. + * + * @return The short copyright notice as a C string. + */ +const char *longBowAbout_ShortNotice(void); + +/** + * Return the long copyright notice as a C string. + * + * @return The long copyright notice as a C string. + */ +const char *longBowAbout_LongNotice(void); + +#endif // longBow_About_h diff --git a/longbow/src/LongBow/longBow_Backtrace.c b/longbow/src/LongBow/longBow_Backtrace.c new file mode 100755 index 00000000..19625eed --- /dev/null +++ b/longbow/src/LongBow/longBow_Backtrace.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <LongBow/longBow_Backtrace.h> +#include <LongBow/private/longBow_Memory.h> + +#if defined(_WIN64) +# define backtrace(...) (0) +# define backtrace_symbols(...) 0 +# define backtrace_symbols_fd(...) ((void) 0) +#elif defined(_WIN32) +# define backtrace(...) (0) +# define backtrace_symbols(...) 0 +# define backtrace_symbols_fd(...) ((void) 0) +#elif defined(__ANDROID__) +# define backtrace(...) (0) +# define backtrace_symbols(...) 0 +# define backtrace_symbols_fd(...) ((void) 0) +#elif defined(__APPLE__) +# include <execinfo.h> +#elif defined(__linux) +# include <execinfo.h> +#elif defined(__unix) // all unices not caught above +# define backtrace(...) (0) +# define backtrace_symbols(...) 0 +# define backtrace_symbols_fd(...) ((void) 0) +#elif defined(__posix) +# include <execinfo.h> +#endif + +struct longbow_backtrace { + void *callstack; + unsigned int frames; + unsigned int offset; +}; + +LongBowBacktrace * +longBowBacktrace_Create(uint32_t maximumFrames, uint32_t offset) +{ + LongBowBacktrace *result = longBowMemory_Allocate(sizeof(LongBowBacktrace)); + + if (maximumFrames > 0) { + void **stackTrace = longBowMemory_Allocate(sizeof(stackTrace[0]) * ((size_t) maximumFrames + offset)); + + unsigned int frames = (unsigned int) backtrace(stackTrace, (int) (maximumFrames + offset)); + if (frames > offset) { + unsigned int actualFrames = frames - offset; + + if (actualFrames > maximumFrames) { + actualFrames = maximumFrames; + } + + // Shift out the first 'offset' number of frames in the stack trace. + memmove(&stackTrace[0], &stackTrace[offset], actualFrames * sizeof(stackTrace[0])); + + result->callstack = stackTrace; + result->frames = actualFrames; + result->offset = 0; + } + } + + return result; +} + +unsigned int +longBowBacktrace_GetFrameCount(const LongBowBacktrace *backtrace) +{ + return backtrace->frames; +} + +void +longBowBacktrace_Destroy(LongBowBacktrace **backtracePtr) +{ + LongBowBacktrace *backtrace = *backtracePtr; + longBowMemory_Deallocate(&backtrace->callstack); + longBowMemory_Deallocate((void **) backtracePtr); +} + +char ** +longBowBacktrace_Symbols(const LongBowBacktrace *backtrace) +{ + char **result = NULL; + if (backtrace != NULL) { + result = backtrace_symbols(backtrace->callstack, (int) backtrace->frames); + } + + return result; +} + +char * +longBowBacktrace_ToString(const LongBowBacktrace *backtrace) +{ + char *result = NULL; + + char **lines = longBowBacktrace_Symbols(backtrace); + + if (lines == NULL) { + result = longBowMemory_StringCopy("(backtrace symbols not supported)"); + } else { + size_t sum = 0; + for (int i = 0; i < backtrace->frames; i++) { + sum += strlen(lines[i]) + 1; + } + result = longBowMemory_Allocate(sum + 1 * sizeof(char)); + + char *offset = result; + for (int i = 0; i < backtrace->frames; i++) { + strcpy(offset, lines[i]); + offset += strlen(lines[i]); + *offset++ = '\n'; + } + *offset = 0; + } + + return result; +} diff --git a/longbow/src/LongBow/longBow_Backtrace.h b/longbow/src/LongBow/longBow_Backtrace.h new file mode 100755 index 00000000..b7b12bef --- /dev/null +++ b/longbow/src/LongBow/longBow_Backtrace.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Backtrace.h + * @ingroup internals + * @brief Support for Stack Traces + * + */ +#ifndef LongBow_longBow_Backtrace_h +#define LongBow_longBow_Backtrace_h +#include <stdint.h> + +struct longbow_backtrace; +/** + * @typedef LongBowBacktrace + * @brief A Backtrace representation. + */ +typedef struct longbow_backtrace LongBowBacktrace; + +/** + * Create a `LongBowBacktrace`. + * + * The backtrace includes depth number of elements from the stack. + * + * @param [in] depth The number of elements from the stack to include. + * @param [in] offset The offset of the stack to start the Backtrace. + * @return A pointer to an allocated LongBowBacktrace instance. + */ +LongBowBacktrace *longBowBacktrace_Create(uint32_t depth, uint32_t offset); + +/** + * Get the array of symbols from the given `LongBowBacktrace instance`. + * + * @param [in] backtrace A pointer to a valid LongBowBacktrace instance. + * + * @return An array of nul-terminated, C strings each containing a symbolic representatino of the corresponding stack frame. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + */ +char **longBowBacktrace_Symbols(const LongBowBacktrace *backtrace); +/** + * Get the number of frames in the given LongBowBacktrace instance. + * + * @param [in] backtrace A pointer to a valid LongBowBacktrace instance. + * + * @return The number of frames in the LongBowBacktrace. + */ +unsigned int longBowBacktrace_GetFrameCount(const LongBowBacktrace *backtrace); + +/** + * + * @param [in,out] backtracePtr A pointer to a pointer to a valid LongBowBacktrace instance. + */ +void longBowBacktrace_Destroy(LongBowBacktrace **backtracePtr); + +/** + * + * @param [in] backtrace A pointer to a valid LongBowBacktrace instance. + * @return An allocated C string that must be deallocated via longBowMemory_Deallocate(). + */ +char *longBowBacktrace_ToString(const LongBowBacktrace *backtrace); +#endif diff --git a/longbow/src/LongBow/longBow_ClipBoard.c b/longbow/src/LongBow/longBow_ClipBoard.c new file mode 100644 index 00000000..a3264d44 --- /dev/null +++ b/longbow/src/LongBow/longBow_ClipBoard.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <LongBow/longBow_ClipBoard.h> + +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_ArrayList.h> + +struct LongBowClipBoard { + LongBowArrayList *list; +}; + +typedef struct Property { + const char *name; + char *value; +} _Property; + +static void +_property_Destroy(_Property **pointer) +{ + _Property *property = *pointer; + longBowMemory_Deallocate((void **) &property->name); + longBowMemory_Deallocate((void **) property); +} + +void +longBowClipBoard_Destroy(LongBowClipBoard **pointer) +{ + LongBowClipBoard *clipboard = *pointer; + + longBowArrayList_Destroy(&clipboard->list); + longBowMemory_Deallocate((void **) pointer); +} + +LongBowClipBoard * +longBowClipBoard_Create(void) +{ + LongBowClipBoard *result = longBowMemory_Allocate(sizeof(LongBowClipBoard)); + + if (result != NULL) { + result->list = longBowArrayList_Create((void (*)(void **))_property_Destroy); + } + + return result; +} + +static _Property * +_longBowClipBoard_Get(const LongBowClipBoard *clipBoard, const char *name) +{ + _Property *result = NULL; + + for (size_t index = 0; index < longBowArrayList_Length(clipBoard->list); index++) { + _Property *property = longBowArrayList_Get(clipBoard->list, index); + if (strcmp(property->name, name) == 0) { + result = property; + break; + } + } + return result; +} + +void * +longBowClipBoard_Get(const LongBowClipBoard *clipBoard, const char *name) +{ + _Property *property = _longBowClipBoard_Get(clipBoard, name); + + if (property != NULL) { + return property->value; + } + + return NULL; +} + +char * +longBowClipBoard_GetAsCString(const LongBowClipBoard *clipBoard, const char *name) +{ + return (char *) longBowClipBoard_Get(clipBoard, name); +} + +uint64_t +longBowClipBoard_GetAsInt(const LongBowClipBoard *clipBoard, const char *name) +{ + return (uint64_t) longBowClipBoard_Get(clipBoard, name); +} + +void * +longBowClipBoard_Set(LongBowClipBoard *clipBoard, const char *name, void *value) +{ + void *result = NULL; + + _Property *property = _longBowClipBoard_Get(clipBoard, name); + if (property == NULL) { + property = longBowMemory_Allocate(sizeof(_Property)); + property->name = longBowMemory_StringCopy(name); + property->value = value; + longBowArrayList_Add(clipBoard->list, property); + } else { + result = property->value; + property->value = value; + } + return result; +} + +void * +longBowClipBoard_SetInt(LongBowClipBoard *clipBoard, const char *name, uint64_t value) +{ + return longBowClipBoard_Set(clipBoard, name, (void *) (uintptr_t) value); +} + +void * +longBowClipBoard_SetCString(LongBowClipBoard *clipBoard, const char *name, char *value) +{ + return longBowClipBoard_Set(clipBoard, name, (char *) value); +} + +bool +longBowClipBoard_Exists(const LongBowClipBoard *clipBoard, const char *name) +{ + return (_longBowClipBoard_Get(clipBoard, name) != NULL); +} + +bool +longBowClipBoard_Delete(LongBowClipBoard *clipBoard, const char *name) +{ + bool result = false; + + for (size_t index = 0; index < longBowArrayList_Length(clipBoard->list); index++) { + _Property *property = longBowArrayList_Get(clipBoard->list, index); + if (strcmp(property->name, name) == 0) { + longBowArrayList_RemoveAtIndex(clipBoard->list, index); + result = true; + } + } + + return result; +} diff --git a/longbow/src/LongBow/longBow_ClipBoard.h b/longbow/src/LongBow/longBow_ClipBoard.h new file mode 100755 index 00000000..86781953 --- /dev/null +++ b/longbow/src/LongBow/longBow_ClipBoard.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_ClipBoard.h + * @brief <#Brief Description#> + * + * <#Detailed Description#> + * + */ +#ifndef longBow_ClipBoard_h +#define longBow_ClipBoard_h + +#include <stdbool.h> +#include <stdint.h> + +struct LongBowClipBoard; +typedef struct LongBowClipBoard LongBowClipBoard; + +void longBowClipBoard_Destroy(LongBowClipBoard **pointer); + +LongBowClipBoard *longBowClipBoard_Create(void); + +void *longBowClipBoard_Get(const LongBowClipBoard *clipBoard, const char *name); + +char *longBowClipBoard_GetAsCString(const LongBowClipBoard *clipBoard, const char *name); + +uint64_t longBowClipBoard_GetAsInt(const LongBowClipBoard *clipBoard, const char *name); + +void *longBowClipBoard_Set(LongBowClipBoard *clipBoard, const char *name, void *value); + +void *longBowClipBoard_SetInt(LongBowClipBoard *clipBoard, const char *name, uint64_t value); + +void *longBowClipBoard_SetCString(LongBowClipBoard *clipBoard, const char *name, char *value); + +bool longBowClipBoard_Exists(const LongBowClipBoard *clipBoard, const char *name); + +bool longBowClipBoard_Delete(LongBowClipBoard *clipBoard, const char *name); + +#endif /* longBow_ClipBoard_h */ diff --git a/longbow/src/LongBow/longBow_Compiler.h b/longbow/src/LongBow/longBow_Compiler.h new file mode 100755 index 00000000..197e1e8c --- /dev/null +++ b/longbow/src/LongBow/longBow_Compiler.h @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Compiler.h + * @ingroup compiling + * @brief LongBow compile time functionality. + * + */ +#ifndef LongBow_compiling_h +#define LongBow_compiling_h + +/** + * @def LONGBOW_GNUC_EXACTLY + * + * Compile-time test to determine if the compiler is the GNU C compiler with the specfied + * version, revision and patch levels. + * + * @param [in] major The required major version number of the compiler. + * @param [in] minor The required minor version number of the compiler. + * @param [in] patch The required patch number of the compiler. + * + * @return true If the current compiler matches the requirements. + * + * Example: + * @code + * #if LONGBOW_GNUC_EXACTLY(4,2,1) + * printf("Hello GNU compiler 4.2.1\n"); + * #endif + * @endcode + * + * @see LONGBOW_GNUC_ATLEAST + */ +#ifdef __GNUC__ +# define LONGBOW_GNUC_EXACTLY(major, minor, patch) \ + (__GNUC__ == major) && (__GNUC_MINOR__ = minor) && (__GNUC_PATCHLEVEL__ == patch) +#else +# define LONGBOW_GNUC_EXACTLY(major, minor, patch) \ + (0) +#endif + +/** + * @def LONGBOW_GNUC_ATLEAST + * + * Compile-time test to determine if the compiler is the GNU C compiler with at least the specfied + * version, revision and patch levels. + * + * @param [in] major The minimum required major version number of the compiler. + * @param [in] minor The minimum required minor version number of the compiler. + * @param [in] patch The minimum required patch number of the compiler. + * + * @return true If the current compiler matches the requirements. + * @return false If the current compiler fails to match the requirements. + * + * Example: + * @code + * #if LONGBOW_GNUC_ATLEAST(4,0,0) + * printf("Hello GNU compiler 4.x\n"); + * #endif + * @endcode + * + * @see LONGBOW_GNUC_EXACTLY + */ +#ifdef __GNUC__ +# define LONGBOW_GNUC_ATLEAST(major, minor, patch) \ + (__GNUC__ >= major) && (__GNUC_MINOR__ > minor) && (__GNUC_PATCHLEVEL__ >= patch) +#else +# define LONGBOW_GNUC_ATLEAST(major, minor, patch) \ + (0) +#endif + +/** + * @def LONGBOW_CLANG_EXACTLY + * + * Compile-time test to determine if the compiler is the Clang C compiler with the specfied + * version, revision and patch levels. + * + * @param [in] major The required major version number of the compiler. + * @param [in] minor The required minor version number of the compiler. + * @param [in] patch The required patch number of the compiler. + * + * @return true If the current compiler matches the requirements. + * + * Example: + * @code + * #if LONGBOW_CLANG_EXACTLY(5,0,0) + * printf("Hello Clang 5.0.0\n"); + * #endif + * @endcode + * + * @see LONGBOW_CLANG_ATLEAST + */ +#ifdef __clang__ +# define LONGBOW_CLANG_EXACTLY(major, minor, patch) \ + (__clang_major__ == major) && (__clang_major__ = minor) && (__clang_patchlevel__ == patch) +#else +# define LONGBOW_CLANG_EXACTLY(major, minor, patch) \ + (0) +#endif + +/** + * @def LONGBOW_CLANG_ATLEAST + * + * Compile-time test to determine if the compiler is the GNU C compiler with at least the specfied + * version, revision and patch levels. + * + * @param [in] major The minimum required major version number of the compiler. + * @param [in] minor The minimum required minor version number of the compiler. + * @param [in] patch The minimum required patch number of the compiler. + * + * @return true If the current compiler matches the requirements. + * @return false If the current compiler fails to match the requirements. + * + * Example: + * @code + * #if LONGBOW_CLANG_ATLEAST(5,0,0) + * printf("Hello Clang compiler 5.x\n"); + * #endif + * @endcode + * + * @see LONGBOW_CLANG_EXACTLY + */ +#ifdef __clang__ +# define LONGBOW_CLANG_ATLEAST(major, minor, patch) \ + (__clang_major__ >= major) && (__clang_major__ > minor) && (__clang_patchlevel__ >= patch) +#else +# define LONGBOW_CLANG_ATLEAST(major, minor, patch) \ + (0) +#endif + +/** + * @def LONGBOW_START_DEPRECATED_WARNINGS + * + * Compile-time preprocessing to signal the compiler to not report the use of deprecated functions. + * + * Example: + * @code + * LONGBOW_STOP_DEPRECATED_WARNINGS + * someDeprecatedFunction(); + * @endcode + * + * @see LONBOW_STOP_DEPRECATED_WARNINGS + */ + +/** + * @def LONGBOW_STOP_DEPRECATED_WARNINGS + * + * Compile-time preprocessing to signal the compiler to report the use of deprecated functions. + * + * Example: + * @code + * LONGBOW_STOP_DEPRECATED_WARNINGS + * someDeprecatedFunction(); + * @endcode + * + * @see LONBOW_START_DEPRECATED_WARNINGS + */ +#if LONGBOW_CLANG_ATLEAST(5, 0, 0) || LONGBOW_GNUC_ATLEAST(4, 6, 0) +# define LONGBOW_STOP_DEPRECATED_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +# define LONGBOW_START_DEPRECATED_WARNINGS \ + _Pragma("GCC diagnostic pop") + +#elif __clang__ || __GNUC__ + +# define LONGBOW_STOP_DEPRECATED_WARNINGS \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +# define LONGBOW_START_DEPRECATED_WARNINGS \ + _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") + +#else + +# define LONGBOW_STOP_DEPRECATED_WARNINGS /* nothing */ + +# define LONGBOW_START_DEPRECATED_WARNINGS /* nothing */ +#endif + +/** + * @def LongBowCompiler_IgnoreInitializerOverrides + * + * Compile-time preprocessing to signal the compiler to not report the use of structure initializer overrides. + * + * Example: + * @code + * LongBowCompiler_IgnoreInitializerOverrides + * struct foo { + * int a; + * } instance = { + * .a = 1, + * .a = 1 + * }; + * LongBowCompiler_WarnInitializerOverrides + * @endcode + * + * @see LongBowCompiler_WarnInitializerOverrides + */ +#if LONGBOW_CLANG_ATLEAST(5, 0, 0) +# define LongBowCompiler_IgnoreInitializerOverrides \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Winitializer-overrides\"") + +# define LongBowCompiler_WarnInitializerOverrides \ + _Pragma("GCC diagnostic pop") + +#elif LONGBOW_GNUC_ATLEAST(4, 6, 0) +# define LongBowCompiler_IgnoreInitializerOverrides \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Woverride-init\"") + +# define LongBowCompiler_WarnInitializerOverrides \ + _Pragma("GCC diagnostic pop") + +#elif __clang__ || __GNUC__ +# define LongBowCompiler_IgnoreInitializerOverrides \ + _Pragma("GCC diagnostic ignored \"-Woverride-init\"") + +# define LongBowCompiler_WarnInitializerOverrides \ + _Pragma("GCC diagnostic warning \"-Woverride-init\"") + +#else + +# define LongBowCompiler_IgnoreInitializerOverrides /* nothing */ + +# define LongBowCompiler_WarnInitializerOverrides /* nothing */ +#endif + +/** + * @def LONGBOW_STOPWARNINGS_UnusedVariable + * + * Compile-time preprocessing to signal the compiler to report unused variables. + * + * Example: + * @code + * LONGBOW_STOPWARNINGS_UnusedVariable + * void + * foo(int unusedVariable) + * { + * return; + * } + * LONGBOW_STARTWARNINGS_UnusedVariable + * @endcode + * + * @see LONGBOW_STARTWARNINGS_UnusedVariable + * + * @def LONGBOW_STARTWARNINGS_UnusedVariable + * + * Compile-time preprocessing to signal the compiler to report unused variables. + * + * Example: + * @code + * LONGBOW_STOPWARNINGS_UnusedVariable + * void + * foo(int unusedVariable) + * { + * return; + * } + * LONGBOW_STARTWARNINGS_UnusedVariable + * @endcode + * + * @see LONGBOW_STARTWARNINGS_UnusedVariable + */ +#if LONGBOW_CLANG_ATLEAST(5, 0, 0) +# define LONGBOW_STOPWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") +# define LONGBOW_STARTWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic pop") +#elif LONGBOW_GNUC_ATLEAST(4, 6, 0) +# define LONGBOW_STOPWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") +# define LONGBOW_STARTWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic pop") +#elif __clang__ || __GNUC__ +# define LONGBOW_STOPWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") +# define LONGBOW_STARTWARNINGS_UnusedVariable \ + _Pragma("GCC diagnostic warning \"-Wunused-variable\"") +#else + +# define LONGBOW_STOPWARNINGS_UnusedVariable /* nothing */ + +# define LONGBOW_STARTWARNINGS_UnusedVariable /* nothing */ +#endif + + +#endif // LongBow_compiling_h diff --git a/longbow/src/LongBow/longBow_Config.c b/longbow/src/LongBow/longBow_Config.c new file mode 100755 index 00000000..f650661f --- /dev/null +++ b/longbow/src/LongBow/longBow_Config.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> +#include <stdio.h> +#include <inttypes.h> + +#include <LongBow/private/longBow_ArrayList.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_String.h> + +#include <LongBow/longBow_Properties.h> + +#include <LongBow/longBow_Config.h> +#include <LongBow/Reporting/longBowReport_Runtime.h> +#include <LongBow/longBow_About.h> + +/** @cond private */ +struct longbow_configuration { + LongBowReportConfig *reportConfiguration; + LongBowProperties *properties; +}; +/** @endcond */ + +static void +_longBowConfig_SetupEnvironment(const LongBowConfig *config) +{ +} + +static void +_longBowConfig_Show(const LongBowConfig *configuration) +{ + char *string = longBowProperties_ToString(configuration->properties); + ssize_t nwritten = write(1, string, strlen(string)); + if (nwritten != strlen(string)) { + fprintf(stderr, "Failed to write to file descriptor 1.\n"); + exit(-1); + } + longBowMemory_Deallocate((void **) &string); +} + +static bool +_longBowConfig_Set(LongBowConfig *configuration, const char *expression) +{ + bool result = false; + + LongBowArrayList *tokens = longBowString_Tokenise(expression, "="); + if (tokens != NULL) { + if (longBowArrayList_Length(tokens) == 2) { + char *name = longBowArrayList_Get(tokens, 0); + char *value = longBowArrayList_Get(tokens, 1); + result = longBowConfig_SetProperty(configuration, name, value); + longBowArrayList_Destroy(&tokens); + } + } + + return result; +} + +LongBowConfig * +longBowConfig_Create(int argc, char *argv[], const char *mainFileName) +{ + LongBowConfig *result = longBowMemory_Allocate(sizeof(LongBowConfig)); + + result->properties = longBowProperties_Create(); + longBowProperties_Set(result->properties, "trace", "false"); + longBowProperties_Set(result->properties, "silent", "false"); + longBowProperties_Set(result->properties, "run-forked", "false"); + + for (int i = 1; i < argc; i++) { + if (longBowString_Equals("--help", argv[i]) || longBowString_Equals("-h", argv[i])) { + // If the option is "--help", + // then let all of the sub-systems that also take arguments process that option also. + printf("LongBow %s\n", longBowAbout_Version()); + printf("%s\n", longBowAbout_MiniNotice()); + printf("Options\n"); + //printf(" --main Print the name of the main test runner source file.\n"); + printf(" --help Print this help message.\n"); + printf(" --run-forked Run the tests as forked processes.\n"); + printf(" --run-nonforked Run the tests in the same process (default).\n"); + printf(" --version Print the version of LongBow used for this test.\n"); + printf(" --core-dump Produce a core file upon the first failed assertion.\n"); + printf(" --set name=value Set a configuration property name to the specified value\n"); + longBowTestRunner_ConfigHelp(); + longBowTestFixture_ConfigHelp(); + longBowTestCase_ConfigHelp(); + longBowReportRuntime_Create(argc, argv); + longBowConfig_Destroy(&result); + printf("\n"); + return NULL; + } else if (longBowString_Equals("--main", argv[i])) { + printf("%s\n", mainFileName); + longBowConfig_Destroy(&result); + return NULL; + } else if (longBowString_Equals("--version", argv[i])) { + printf("%s\n", longBowAbout_Version()); + longBowConfig_Destroy(&result); + return NULL; + } else if (longBowString_Equals("--run-nonforked", argv[i])) { + longBowProperties_Set(result->properties, "run-forked", "false"); + } else if (longBowString_Equals("--run-forked", argv[i])) { + printf("?\n"); + longBowProperties_Set(result->properties, "run-forked", "true"); + } else if (longBowString_Equals("--trace", argv[i])) { + longBowProperties_Set(result->properties, "trace", "true"); + } else if (longBowString_Equals("--silent", argv[i])) { + longBowProperties_Set(result->properties, "silent", "true"); + } else if (longBowString_Equals("--core-dump", argv[i])) { + longBowProperties_Set(result->properties, "core-dump", "true"); + } else if (longBowString_StartsWith(argv[i], "--set")) { + char *parameter = argv[++i]; + if (_longBowConfig_Set(result, parameter) == false) { + printf("Could not set parameter: %s\n", parameter); + } + } else if (longBowString_StartsWith(argv[i], "--show")) { + _longBowConfig_Show(result); + } else { + printf("Unknown option '%s'\n", argv[i]); + } + } + + LongBowReportConfig *reportConfiguration = longBowReportRuntime_Create(argc, argv); + + if (reportConfiguration == NULL) { + longBowConfig_Destroy(&result); + result = NULL; + } else { + if (result == NULL) { + // nothing to do. + } else { + result->reportConfiguration = reportConfiguration; + } + } + + if (result != NULL) { + _longBowConfig_SetupEnvironment(result); + } + return result; +} + +void +longBowConfig_Destroy(LongBowConfig **configPtr) +{ + LongBowConfig *config = *configPtr; + + if (config != NULL) { + if (config->reportConfiguration != NULL) { + longBowReportRuntime_Destroy(&config->reportConfiguration); + } + longBowProperties_Destroy(&config->properties); + longBowMemory_Deallocate((void **) configPtr); + } +} + +bool +longBowConfig_IsRunForked(const LongBowConfig *config) +{ + return longBowConfig_GetBoolean(config, false, "run-forked"); +} + +bool +longBowConfig_IsTrace(const LongBowConfig *config) +{ + return longBowConfig_GetBoolean(config, false, "trace"); +} + +static const char * +_longBowConfig_GetProperty(const LongBowConfig *config, const char *format, va_list ap) +{ + const char *result = NULL; + + char *propertyName; + if (vasprintf(&propertyName, format, ap) != -1) { + if (config != NULL && config->properties != NULL) { + result = longBowProperties_Get(config->properties, propertyName); + } + free(propertyName); + } + + return result; +} + +const char * +longBowConfig_GetProperty(const LongBowConfig *config, const char *format, ...) +{ + const char *result = NULL; + + if (config != NULL && config->properties != NULL) { + va_list ap; + va_start(ap, format); + result = _longBowConfig_GetProperty(config, format, ap); + va_end(ap); + } + + return result; +} + +bool +longBowConfig_SetProperty(const LongBowConfig *config, const char *name, const char *value) +{ + bool result = false; + + if (config != NULL && config->properties != NULL) { + result = longBowProperties_Set(config->properties, name, value); + } + + return result; +} + +bool +longBowConfig_GetBoolean(const LongBowConfig *config, bool defaultValue, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + const char *value = _longBowConfig_GetProperty(config, format, ap); + va_end(ap); + + bool result = defaultValue; + if (value != NULL) { + result = (strcasecmp(value, "true") == 0); + } + return result; +} + +uint32_t +longBowConfig_GetUint32(const LongBowConfig *config, uint32_t defaultValue, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + const char *value = _longBowConfig_GetProperty(config, format, ap); + va_end(ap); + + uint32_t result = defaultValue; + if (value != NULL) { + result = (uint32_t) strtoul(value, NULL, 10); + } + return result; +} diff --git a/longbow/src/LongBow/longBow_Config.h b/longbow/src/LongBow/longBow_Config.h new file mode 100755 index 00000000..003497b4 --- /dev/null +++ b/longbow/src/LongBow/longBow_Config.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Config.h + * @ingroup internals + * @brief Support for LongBow Configuration + * + */ +#ifndef LONGBOWCONFIGURATION_H_ +#define LONGBOWCONFIGURATION_H_ +#include <stdbool.h> +#include <stdint.h> + +struct longbow_configuration; + +/** + * @typedef LongBowConfig + * @brief The LongBow Configuration + */ +typedef struct longbow_configuration LongBowConfig; + +/** + * Destroy a LongBowConfig instance. + * + * @param [in,out] configPtr A pointer to a LongBowConfig instance pointer. + */ +void longBowConfig_Destroy(LongBowConfig **configPtr); + +/** + * Create a LongBowConfig structure instance from the given array of parameters. + * + * The function parses argv style arguments and composes a LongBowConfig structure. + * + * The argv-style arguments may include parameters not related to creating a LongBowConfig structure. + * + * For example, the arguments may only be `--help` and prints a help message but doesn't create a `LongBowConfig` structure. + * + * @param [in] argc The number of elements in the `argv` array. + * @param [in] argv An array of nul-terminated C strings. + * @param [in] mainFileName The string printed for the `--main` option. + * + * @return non-NULL A LongBowConfig structure instance suitable for running a test + * @return NULL Nothing suitable for running a test (not an error). + */ +LongBowConfig *longBowConfig_Create(int argc, char *argv[], const char *mainFileName); + +/** + * Get a property stored in the configuration. + * @param [in] config A pointer to a valid LongBowConfig instance. + * @param [in] format A pointer to a valid, nul-terminated format string. + * + * @return non-NULL A pointer to nul-terminated, C string. + */ +const char *longBowConfig_GetProperty(const LongBowConfig *config, const char *format, ...); + +/** + * Set the property @p name to @p value + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * + * @return true + * @return true + */ +bool longBowConfig_SetProperty(const LongBowConfig *config, const char *name, const char *value); + +/** + * Get the property @p name interpreted as a 32-bit integer. + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * + * @return The property @p name interpreted as a 32-bit integer. + */ +uint32_t longBowConfig_GetUint32(const LongBowConfig *config, uint32_t defaultValue, const char *format, ...); + +/** + * Get the value of the configuration property named by the formatted property name. + * If the given LongBowConfig instance is not available, or the property is not present, the default value is returned. + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * @param [in] defaultValue Either true or false. + * @param [in] format A printf format string followed by appropriate parameters used to construct the property name. + * + * @return true The property was present with the value true, or the property was not present and the default value is true. + * @return false The property was present with the value false, or the property was not present and the default value is false. + */ +bool longBowConfig_GetBoolean(const LongBowConfig *config, bool defaultValue, const char *format, ...); + +/** + * Return `true` if the given `LongBowConfig` instance specifies that test cases are to be run in a sub-process. + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * @return true if the given specification stipulates tests are to run in a sub-process. + */ +bool longBowConfig_IsRunForked(const LongBowConfig *config); + +/** + * Indicate if the given configuration is specifying the 'trace' flag. + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * + * @return true The given configuration is specifying the 'trace' flag. + * @return false The given configuration is not specifying the 'trace' flag. + * + * Example: + * @code + * if (longBowConfig_IsTrace(longBowRunner_GetConfiguration(testRunner)) { + * longBowTrace_Report(testRunner->configuration); + * } + * @endcode + */ +bool longBowConfig_IsTrace(const LongBowConfig *config); + +#endif // LONGBOWCONFIGURATION_H_ diff --git a/longbow/src/LongBow/longBow_Debug.c b/longbow/src/LongBow/longBow_Debug.c new file mode 100755 index 00000000..6a72603f --- /dev/null +++ b/longbow/src/LongBow/longBow_Debug.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> +#include <string.h> +#include <stdio.h> + +#include <LongBow/longBow_Debug.h> +#include <LongBow/Reporting/longBowReport_Runtime.h> + +/** @cond */ +struct longbow_debug_criteria { + bool enabled; +}; +/** @endcond */ + +static struct longbow_debug_criteria LongBowDebug_StaticCriteria = { + .enabled = true +}; + +static LongBowDebugCriteria *LongBowDebug_CurrentCriteria = &LongBowDebug_StaticCriteria; + +LongBowDebugCriteria * +longBowDebug_CurrentCriteria(void) +{ + return LongBowDebug_CurrentCriteria; +} + +static void +_longBowDebug_MemoryDumpLine(const char *memory, size_t offset, size_t length) +{ + int bytesPerLine = 16; + char accumulator[bytesPerLine + 1]; + memset(accumulator, ' ', bytesPerLine); + accumulator[bytesPerLine] = 0; + + printf("%5zd: ", offset); + + for (size_t i = 0; i < bytesPerLine; i++) { + if (offset + i >= length) { + printf(" "); + accumulator[i] = ' '; + } else { + char c = memory[offset + i]; + printf("%02x ", c & 0xFF); + if (isprint(c)) { + accumulator[i] = c; + } else { + accumulator[i] = '.'; + } + } + } + printf(" %s\n", accumulator); +} + +void +longBowDebug_MemoryDump(const char *memory, size_t length) +{ + size_t bytesPerLine = 16; + + for (size_t offset = 0; offset < length; offset += bytesPerLine) { + _longBowDebug_MemoryDumpLine(memory, offset, length); + } +} + +void +longBowDebug_Message(LongBowDebugCriteria *criteria, const LongBowLocation *location, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + + char *message; + int status = vasprintf(&message, format, ap); + va_end(ap); + if (status != -1) { +#if 1 + char *locationString = longBowLocation_ToString(location); + longBowReportRuntime_Message("%s %s\r\n", locationString, message); + + free(locationString); +#else + longBowReportRuntime_Message(location, message); +#endif + free(message); + } +} + +ssize_t +longBowDebug_WriteFile(const char *fileName, const char *data, size_t length) +{ + ssize_t result = 0; + + int fd = open(fileName, O_CREAT | O_TRUNC | O_WRONLY, 0600); + if (fd == -1) { + perror(fileName); + } else { + result = write(fd, data, length); + } + close(fd); + return result; +} + +ssize_t +longBowDebug_ReadFile(const char *fileName, char **data) +{ + ssize_t result = -1; + struct stat statbuf; + char *buffer; + + int fd = open(fileName, O_RDONLY); + if (fd == -1) { + perror(fileName); + } else { + if (fstat(fd, &statbuf) != -1) { + buffer = malloc((unsigned long) statbuf.st_size + 1); + result = read(fd, buffer, (unsigned long) statbuf.st_size); + buffer[statbuf.st_size] = 0; + *data = buffer; + } + } + return result; +} diff --git a/longbow/src/LongBow/longBow_Debug.h b/longbow/src/LongBow/longBow_Debug.h new file mode 100755 index 00000000..f92df876 --- /dev/null +++ b/longbow/src/LongBow/longBow_Debug.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Debug.h + * @ingroup internals + * @brief Support for LongBow and Application Debugging. + * + */ +#ifndef LongBow_longBow_Debug_h +#define LongBow_longBow_Debug_h + +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + +#include <LongBow/longBow_Location.h> + +typedef struct longbow_debug_criteria LongBowDebugCriteria; + +/** + * Pretty print memory on standard output. + * + * @param [in] memory A pointer to memory. + * @param [in] length The number of bytes to display. + */ +void longBowDebug_MemoryDump(const char *memory, size_t length); + +/** + * Generate and send a message to the specified location. + * + * @param [in] criteria Debug criteria. + * @param [in] location The location to which the message is sent. + * @param [in] format The format string for the message. + * @param [in] ... Remaining arguments for the message string. + */ +void longBowDebug_Message(LongBowDebugCriteria *criteria, const LongBowLocation *location, const char *format, ...); + +/** + * Write data in an array to a file. + * + * Data is written to the specified file from the supplied array. + * + * @param [in] fileName The name of the to write to. + * @param [in] data A pointer to an array of bytes to write. + * @param [in] length The number of bytes to write. + * + * @return The number of bytes written. + * + * Example: + * @code + * { + * size_t numBytesWritten = longBowDebug_WriteFile("log.out", "error", 6); + * } + * @endcode + * + * @see longBowDebug_ReadFile + */ +ssize_t longBowDebug_WriteFile(const char *fileName, const char *data, size_t length); + +/** + * Read data from a file into an allocated array. + * + * Data is read from the specified file into an allocated byte array which must be deallocated by the caller via {stdlib free()}. + * + * For convenience the allocate buffer exceeds the size of the file by one byte, which is set to zero. + * This permits using the result directly as a nul-terminated C string. + * + * @param [in] fileName The name of the file to read from. + * @param [in] data A pointer to a character pointer that will be updated with the address of the read data. + * + * @return The number of bytes read, or -1 if there was an error. + * + * Example: + * @code + * { + * char *buffer = NULL; + * size_t numBytesRead = longBowDebug_ReadFile("log.out", &buffer); + * // use buffer as needed + * } + * @endcode + * + * @see longBowDebug_WriteFile + */ +ssize_t longBowDebug_ReadFile(const char *fileName, char **data); +#endif diff --git a/longbow/src/LongBow/longBow_Event.c b/longbow/src/LongBow/longBow_Event.c new file mode 100755 index 00000000..a24d45bf --- /dev/null +++ b/longbow/src/LongBow/longBow_Event.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <LongBow/longBow_Event.h> +#include <LongBow/longBow_EventType.h> +#include <LongBow/longBow_Backtrace.h> +#include <LongBow/longBow_Location.h> +#include <LongBow/longBow_Status.h> +#include <LongBow/private/longBow_Memory.h> + +/** @cond private */ +struct longbow_event { + const LongBowEventType *type; + const LongBowLocation *location; + const char *kind; + const char *message; + const LongBowBacktrace *backtrace; +}; +/** @endcond */ + +const char * +longBowEvent_GetName(const LongBowEvent *event) +{ + return longBowEventType_GetName(event->type); +} + +LongBowEvent * +longBowEvent_Create(const LongBowEventType *eventType, const LongBowLocation *location, const char *kind, const char *message, const LongBowBacktrace *backtrace) +{ + LongBowEvent *result = longBowMemory_Allocate(sizeof(LongBowEvent)); + if (result != NULL) { + result->type = eventType; + result->location = location; + result->kind = kind; + result->message = strndup(message, strlen(message)); + result->backtrace = backtrace; + } + + return result; +} + +void +longBowEvent_Destroy(LongBowEvent **assertionPtr) +{ + LongBowEvent *assertion = *assertionPtr; + + if (assertion->location != NULL) { + longBowLocation_Destroy((LongBowLocation **) &assertion->location); + } + if (assertion->message != NULL) { + free((void *) assertion->message); + } + + if (assertion->backtrace != NULL) { + longBowBacktrace_Destroy((LongBowBacktrace **) &assertion->backtrace); + } + longBowMemory_Deallocate((void **) assertionPtr); +} + +const LongBowLocation * +longBowEvent_GetLocation(const LongBowEvent *event) +{ + return event->location; +} + +const LongBowEventType * +longBowEvent_GetEventType(const LongBowEvent *event) +{ + return event->type; +} + +const char * +longBowEvent_GetKind(const LongBowEvent *event) +{ + return event->kind; +} + +const char * +longBowEvent_GetMessage(const LongBowEvent *event) +{ + return event->message; +} + +const LongBowBacktrace * +longBowEvent_GetBacktrace(const LongBowEvent *event) +{ + return event->backtrace; +} + +char ** +longBowEvent_CreateSymbolicCallstack(const LongBowEvent *event) +{ + char **result = longBowBacktrace_Symbols(event->backtrace); + + return result; +} + +size_t +longBowEvent_GetCallStackLength(const LongBowEvent *event) +{ + return longBowBacktrace_GetFrameCount(event->backtrace); +} diff --git a/longbow/src/LongBow/longBow_Event.h b/longbow/src/LongBow/longBow_Event.h new file mode 100755 index 00000000..12f903c0 --- /dev/null +++ b/longbow/src/LongBow/longBow_Event.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Event.h + * @ingroup internals + * @brief LongBow Event Support. + * + * LongBow assertions, traps and tests induce "events" which are experienced by the programme runtime as signals or long-jumps. + * + */ +#ifndef LongBow_longBow_Event_h +#define LongBow_longBow_Event_h + +#include <stdlib.h> +#include <stdbool.h> + +#include <LongBow/longBow_EventType.h> +#include <LongBow/longBow_Location.h> +#include <LongBow/longBow_Backtrace.h> + +struct longbow_event; + +/** + * @typedef LongBowEvent + */ +typedef struct longbow_event LongBowEvent; + +/** + * Get the `LongBowEventType` of a LongBowEvent. + * + * @param [in] event A `LongBowEvent` instance. + * + * @return A pointer to the LongBowEventType of the event. + * + * Example: + * @code + * { + * LongBowEvent *event = ... + * LongBowEventType type = longBowEvent_GetEventType(event); + * } + * @endcode + */ +const LongBowEventType *longBowEvent_GetEventType(const LongBowEvent *event); + +/** + * Create a `LongBowEvent`. + * + * Creating a `LongBowEvent` records runtime data and used by report facilities. + * This does not actually cause the process to assert the assertion. + * + * @param [in] eventType The LongBowEventType for this event. + * @param [in] location A LongBowLocation instance recording the location of the event. + * @param [in] kind A string representing the kind of event. + * @param [in] message A message to display. This will be freed via free(3). + * @param [in] backtrace A pointer to a valid LongBowBacktrace instance. + * + * @return An allocated LongBowEvent which must be destroyed via `longBowEvent_Destroy()`. + */ +LongBowEvent *longBowEvent_Create(const LongBowEventType *eventType, const LongBowLocation *location, const char *kind, const char *message, const LongBowBacktrace *backtrace); + +/** + * Destroy a `LongBowEvent`. + * + * The value pointed to by `eventPtr`, is set to `NULL. + * + * @param [in,out] eventPtr The `LongBowEvent` instance to destroy and NULLify. + */ +void longBowEvent_Destroy(LongBowEvent **eventPtr); + +/** + * Get the `LongBowLocation` associated with this `LongBowEvent` instance. + * + * @param [in] event A `LongBowEvent` instance. + * + * @return A pointer to the `LongBowLocation` instance for the given `LongBowEvent`. + */ +const LongBowLocation *longBowEvent_GetLocation(const LongBowEvent *event); + +/** + * Get the name. + * + * @param [in] event A `LongBowEvent` instance. + * + * @return The name of the given LongBowEvent. + */ +const char *longBowEvent_GetName(const LongBowEvent *event); + +/** + * Get a pointer to the string representing the kind of this event. + * + * Currently the kind is only a static string set when creating a `LongBowEvent`. + * + * @param [in] event A pointer to a `LongBowEvent` instance. + * + * @return non-NULL The pointer to the string representing the kind of this event. + * @return NULL The kind was not set. + * + * @see longBowEvent_Create + */ +const char *longBowEvent_GetKind(const LongBowEvent *event); + +/** + * Retrieve the message associated with this `LongBowEvent` instance. + * + * @param [in] event A `LongBowEvent` instance. + * + * @return The message associated with the given `LongBowEvent`. + */ +const char *longBowEvent_GetMessage(const LongBowEvent *event); + +/** + * Get the `LongBowBacktrace` instance for the given `LongBowEvent` instance. + * + * @param [in] event A pointer to a valid LongBowEvent instance. + * + * @return A pointer to a LongBowBacktrace instance. + */ +const LongBowBacktrace *longBowEvent_GetBacktrace(const LongBowEvent *event); + +/** + * Get an array of nul-terminated C strings containing the symbolic representation of the given `LongBowEvent` stack backtrace. + * The length of the array is provided by `longBowEvent_GetCallStackLength` + * + * @param [in] event A pointer to a valid `LongBowEvent` instance. + * + * @return non-NULL An array of nul-terminated C strings + * @see longBowEvent_GetCallStackLength + */ +char **longBowEvent_CreateSymbolicCallstack(const LongBowEvent *event); + +/** + * Retrieve the call stack length associated with this `LongBowEvent` instance. + * + * @param [in] event A `LongBowEvent` instance. + * + * @return The length of the call stack. + */ +size_t longBowEvent_GetCallStackLength(const LongBowEvent *event); +#endif // LongBow_longBow_Event_h diff --git a/longbow/src/LongBow/longBow_EventType.c b/longbow/src/LongBow/longBow_EventType.c new file mode 100755 index 00000000..7a99b0c3 --- /dev/null +++ b/longbow/src/LongBow/longBow_EventType.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * + */ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#include <signal.h> + +#include <LongBow/longBow_Status.h> +#include <LongBow/longBow_EventType.h> + +/** @cond private */ +struct longbow_event_type { + const char *kind; + const char *name; + LongBowStatus statusCode; + bool suppressBacktrace; + bool suppressAlert; +}; +/** @endcond */ + +#define _eventType(_kind, _name, _code, _suppressBacktrace, _suppressAlert) { \ + .kind = _kind, \ + .name = _name, \ + .statusCode = _code, \ + .suppressBacktrace = _suppressBacktrace, \ + .suppressAlert = _suppressAlert \ +} + +LongBowEventType LongBowAssertEvent = _eventType("Assert", "Assert", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapEvent = _eventType("Trap", "Trap", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapOutOfBounds = _eventType("Trap", "OutOfBounds", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapIllegalValue = _eventType("Trap", "IllegalValue", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapInvalidValue = _eventType("Trap", "InvalidValue", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapUnrecoverableState = _eventType("Trap", "UnrecoverableState", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapNotImplemented = _eventType("Trap", "Implemented", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapOutOfMemoryEvent = _eventType("Trap", "Out of Memory", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapCannotObtainLockEvent = _eventType("Trap", "Cannot obtain lock", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTrapUnexpectedStateEvent = _eventType("Trap", "Unexpected State", LONGBOW_STATUS_FAILED, false, false); + +LongBowEventType LongBowTestSkippedEvent = _eventType("Test", "Skipped", LONGBOW_STATUS_SKIPPED, true, false); + +LongBowEventType LongBowTestUnimplementedEvent = _eventType("Test", "Unimplemented", LongBowStatus_UNIMPLEMENTED, true, true); + +LongBowEventType LongBowEventSIGHUP = _eventType("Signal", "SIGHUP", LongBowStatus_SIGNAL(SIGHUP), false, false); + +LongBowEventType LongBowEventSIGINT = _eventType("Signal", "SIGINT", LongBowStatus_SIGNAL(SIGINT), false, false); + +LongBowEventType LongBowEventSIGQUIT = _eventType("Signal", "SIGQUIT", LongBowStatus_SIGNAL(SIGQUIT), false, false); + +LongBowEventType LongBowEventSIGILL = _eventType("Signal", "SIGILL", LongBowStatus_SIGNAL(SIGILL), false, false); + +LongBowEventType LongBowEventSIGTRAP = _eventType("Signal", "SIGTRAP", LongBowStatus_SIGNAL(SIGTRAP), false, false); + +LongBowEventType LongBowEventSIGABRT = _eventType("Signal", "SIGABRT", LongBowStatus_SIGNAL(SIGABRT), false, false); + +#ifdef _DARWIN_C_SOURCE +LongBowEventType LongBowEventSIGEMT = _eventType("Signal", "SIGEMT", LongBowStatus_SIGNAL(SIGEMT), false, false); +#else +LongBowEventType LongBowEventSIGEMT = _eventType("Signal", "SIGBUS", LongBowStatus_SIGNAL(SIGBUS), false, false); +#endif + +LongBowEventType LongBowEventSIGFPE = _eventType("Signal", "SIGFPE", LongBowStatus_SIGNAL(SIGFPE), false, false); + +LongBowEventType LongBowEventSIGKILL = _eventType("Signal", "SIGKILL", LongBowStatus_SIGNAL(SIGKILL), false, false); + +LongBowEventType LongBowEventSIGBUS = _eventType("Signal", "SIGBUS", LongBowStatus_SIGNAL(SIGBUS), false, false); + +LongBowEventType LongBowEventSIGSEGV = _eventType("Signal", "SIGSEGV", LongBowStatus_SIGNAL(SIGSEGV), false, false); + +LongBowEventType LongBowEventSIGSYS = _eventType("Signal", "SIGSYS", LongBowStatus_SIGNAL(SIGSYS), false, false); + +LongBowEventType LongBowEventSIGPIPE = _eventType("Signal", "SIGPIPE", LongBowStatus_SIGNAL(SIGPIPE), false, false); + +LongBowEventType LongBowEventSIGALRM = _eventType("Signal", "SIGALRM", LongBowStatus_SIGNAL(SIGALRM), false, false); + +LongBowEventType LongBowEventSIGTERM = _eventType("Signal", "SIGTERM", LongBowStatus_SIGNAL(SIGTERM), false, false); + +LongBowEventType LongBowEventSIGURG = _eventType("Signal", "SIGURG", LongBowStatus_SIGNAL(SIGURG), false, false); + +LongBowEventType LongBowEventSIGSTOP = _eventType("Signal", "SIGSTOP", LongBowStatus_SIGNAL(SIGSTOP), false, false); + +LongBowEventType LongBowEventSIGTSTP = _eventType("Signal", "SIGTSTP", LongBowStatus_SIGNAL(SIGTSTP), false, false); + +LongBowEventType LongBowEventSIGCONT = _eventType("Signal", "SIGCONT", LongBowStatus_SIGNAL(SIGCONT), false, false); + +LongBowEventType LongBowEventSIGCHLD = _eventType("Signal", "SIGCHLD", LongBowStatus_SIGNAL(SIGCHLD), false, false); + +LongBowEventType LongBowEventSIGTTIN = _eventType("Signal", "SIGTTIN", LongBowStatus_SIGNAL(SIGTTIN), false, false); + +LongBowEventType LongBowEventSIGTTOU = _eventType("Signal", "SIGTTOU", LongBowStatus_SIGNAL(SIGTTOU), false, false); + +LongBowEventType LongBowEventSIGIO = _eventType("Signal", "SIGIO", LongBowStatus_SIGNAL(SIGIO), false, false); + +LongBowEventType LongBowEventSIGXCPU = _eventType("Signal", "SIGXCPU", LongBowStatus_SIGNAL(SIGXCPU), false, false); + +LongBowEventType LongBowEventSIGXFSZ = _eventType("Signal", "SIGXFSZ", LongBowStatus_SIGNAL(SIGXFSZ), false, false); + +LongBowEventType LongBowEventSIGVTALRM = _eventType("Signal", "SIGVTALRM", LongBowStatus_SIGNAL(SIGVTALRM), false, false); + +LongBowEventType LongBowEventSIGPROF = _eventType("Signal", "SIGPROF", LongBowStatus_SIGNAL(SIGPROF), false, false); + +LongBowEventType LongBowEventSIGWINCH = _eventType("Signal", "SIGWINCH", LongBowStatus_SIGNAL(SIGWINCH), false, false); + +#if (!defined (_ANDROID_) && (!defined(_POSIX_C_SOURCE)) || defined(_DARWIN_C_SOURCE)) +LongBowEventType LongBowEventSIGINFO = _eventType("Signal", "SIGINFO", LongBowStatus_SIGNAL(SIGINFO), false, false); +#else +LongBowEventType LongBowEventSIGINFO = _eventType("Signal", "SIGIO", LongBowStatus_SIGNAL(SIGIO), false, false); +#endif + +LongBowEventType LongBowEventSIGUSR1 = _eventType("Signal", "SIGUSR1", LongBowStatus_SIGNAL(SIGUSR1), false, false); + +LongBowEventType LongBowEventSIGUSR2 = _eventType("Signal", "SIGUSR2", LongBowStatus_SIGNAL(SIGUSR2), false, false); + +LongBowEventType LongBowTestEvent = _eventType("Test", "Test", LongBowStatus_WARNED, false, false); + +static LongBowEventType *signalToEventType[NSIG] = { + NULL, + &LongBowEventSIGHUP /* 1 */, + &LongBowEventSIGINT /* 2 */, + &LongBowEventSIGQUIT /* 3 */, + &LongBowEventSIGILL /* 4 */, + &LongBowEventSIGTRAP /* 5 */, + &LongBowEventSIGABRT /* 6 */, + &LongBowEventSIGEMT /* 7 */, + &LongBowEventSIGFPE /* 8 */, + &LongBowEventSIGKILL /* 9 */, + &LongBowEventSIGBUS /* 10 */, + &LongBowEventSIGSEGV /* 11 */, + &LongBowEventSIGSYS /* 12 */, + &LongBowEventSIGPIPE /* 13 */, + &LongBowEventSIGALRM /* 14 */, + &LongBowEventSIGTERM /* 15 */, + &LongBowEventSIGURG /* 16 */, + &LongBowEventSIGSTOP /* 17 */, + &LongBowEventSIGTSTP /* 18 */, + &LongBowEventSIGCONT /* 19 */, + &LongBowEventSIGCHLD /* 20 */, + &LongBowEventSIGTTIN /* 21 */, + &LongBowEventSIGTTOU /* 22 */, + &LongBowEventSIGIO /* 23 */, + &LongBowEventSIGXCPU /* 24 */, + &LongBowEventSIGXFSZ /* 25 */, + &LongBowEventSIGVTALRM /* 26 */, + &LongBowEventSIGPROF /* 27 */, + &LongBowEventSIGWINCH /* 28 */, + &LongBowEventSIGINFO /* 29 */, + &LongBowEventSIGUSR1 /* 30 */, + &LongBowEventSIGUSR2 /* 31 */ +}; + +const char * +longBowEventType_GetName(const LongBowEventType *eventType) +{ + return eventType->name; +} + +LongBowStatus +longBowEventType_GetStatus(const LongBowEventType *eventType) +{ + return eventType->statusCode; +} + +bool +longBowEventType_IsSuppressBacktrace(const LongBowEventType *eventType) +{ + return eventType->suppressBacktrace; +} + +bool +longBowEventType_IsSuppressAlert(const LongBowEventType *eventType) +{ + return eventType->suppressAlert; +} + +bool +longBowEventType_Equals(const LongBowEventType *x, const LongBowEventType *y) +{ + if (x == y) { + return true; + } + if (x == NULL || y == NULL) { + return false; + } + + if (strcmp(x->name, y->name) == 0) { + return true; + } + return false; +} + +LongBowEventType * +longBowEventType_GetEventTypeForSignal(const int signal) +{ + return signalToEventType[signal]; +} + diff --git a/longbow/src/LongBow/longBow_EventType.h b/longbow/src/LongBow/longBow_EventType.h new file mode 100755 index 00000000..03774abd --- /dev/null +++ b/longbow/src/LongBow/longBow_EventType.h @@ -0,0 +1,409 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_EventType.h + * @ingroup internals + * @ingroup runtime + * @ingroup testing + * @brief LongBow Events and Support. + * + */ +#ifndef LongBow_longBow_EventType_h +#define LongBow_longBow_EventType_h + +#include <LongBow/longBow_Status.h> + +struct longbow_event_type; +/** + * @typedef LongBowEventType + * + * A LongBowEventType identifies a specific Event induced or generated by a running programme. + */ +typedef struct longbow_event_type LongBowEventType; + +/** + * @var LongBowAssertEvent + */ +extern LongBowEventType LongBowAssertEvent; + +/** + * @var LongBowTestEvent + */ +extern LongBowEventType LongBowTestEvent; + +/** + * @var LongBowTestSkippedEvent + */ +extern LongBowEventType LongBowTestSkippedEvent; + +/** + * @var LongBowTestUnimplementedEvent + */ +extern LongBowEventType LongBowTestUnimplementedEvent; + +/** + * @var LongBowTrapOutOfMemoryEvent + */ +extern LongBowEventType LongBowTrapOutOfMemoryEvent; + +/** + * @var LongBowTrapUnexpectedStateEvent + */ +extern LongBowEventType LongBowTrapUnexpectedStateEvent; + +/** + * @var LongBowTrapEvent + */ +extern LongBowEventType LongBowTrapEvent; + +/** + * @var LongBowTrapOutOfBounds + */ +extern LongBowEventType LongBowTrapOutOfBounds; + +/** + * @var LongBowTrapIllegalValue + */ +extern LongBowEventType LongBowTrapIllegalValue; + +/** + * @var LongBowTrapInvalidValue + */ +extern LongBowEventType LongBowTrapInvalidValue; + +/** + * @var LongBowTrapUnrecoverableState + */ +extern LongBowEventType LongBowTrapUnrecoverableState; + +/** + * @var LongBowTrapNotImplemented + */ +extern LongBowEventType LongBowTrapNotImplemented; + +/** + * @var LongBowTrapCannotObtainLockEvent + */ +extern LongBowEventType LongBowTrapCannotObtainLockEvent; + +/** + * @var LongBowEventSIGHUP + */ +extern LongBowEventType LongBowEventSIGHUP; + +/** + * @var LongBowEventSIGINT + */ +extern LongBowEventType LongBowEventSIGINT; + +/** + * @var LongBowEventSIGQUIT + */ +extern LongBowEventType LongBowEventSIGQUIT; + +/** + * @var LongBowEventSIGILL + */ +extern LongBowEventType LongBowEventSIGILL; + +/** + * @var LongBowEventSIGTRAP + */ +extern LongBowEventType LongBowEventSIGTRAP; + +/** + * @var LongBowEventSIGABRT + */ +extern LongBowEventType LongBowEventSIGABRT; + +/** + * @var LongBowEventSIGIOT + */ +extern LongBowEventType LongBowEventSIGIOT; + +/** + * @var LongBowEventSIGEMT + */ +extern LongBowEventType LongBowEventSIGEMT; + +/** + * @var LongBowEventSIGFPE + */ +extern LongBowEventType LongBowEventSIGFPE; + +/** + * @var LongBowEventSIGKILL + */ +extern LongBowEventType LongBowEventSIGKILL; + +/** + * @var LongBowEventSIGBUS + */ +extern LongBowEventType LongBowEventSIGBUS; + +/** + * @var LongBowEventSIGSEGV + */ +extern LongBowEventType LongBowEventSIGSEGV; + +/** + * @var LongBowEventSIGSYS + */ +extern LongBowEventType LongBowEventSIGSYS; + +/** + * @var LongBowEventSIGPIPE + */ +extern LongBowEventType LongBowEventSIGPIPE; + +/** + * @var LongBowEventSIGALRM + */ +extern LongBowEventType LongBowEventSIGALRM; + +/** + * @var LongBowEventSIGTERM + */ +extern LongBowEventType LongBowEventSIGTERM; + +/** + * @var LongBowEventSIGURG + */ +extern LongBowEventType LongBowEventSIGURG; + +/** + * @var LongBowEventSIGSTOP + */ +extern LongBowEventType LongBowEventSIGSTOP; + +/** + * @var LongBowEventSIGTSTP + */ +extern LongBowEventType LongBowEventSIGTSTP; + +/** + * @var LongBowEventSIGCONT + */ +extern LongBowEventType LongBowEventSIGCONT; + +/** + * @var LongBowEventSIGCHLD + */ +extern LongBowEventType LongBowEventSIGCHLD; + +/** + * @var LongBowEventSIGTTIN + */ +extern LongBowEventType LongBowEventSIGTTIN; + +/** + * @var LongBowEventSIGTTOU + */ +extern LongBowEventType LongBowEventSIGTTOU; + +/** + * @var LongBowEventSIGIO + */ +extern LongBowEventType LongBowEventSIGIO; + +/** + * @var LongBowEventSIGXCPU + */ +extern LongBowEventType LongBowEventSIGXCPU; + +/** + * @var LongBowEventSIGXFSZ + */ +extern LongBowEventType LongBowEventSIGXFSZ; + +/** + * @var LongBowEventSIGVTALRM + */ +extern LongBowEventType LongBowEventSIGVTALRM; + +/** + * @var LongBowEventSIGPROF + */ +extern LongBowEventType LongBowEventSIGPROF; + +/** + * @var LongBowEventSIGWINCH + */ +extern LongBowEventType LongBowEventSIGWINCH; + +/** + * @var LongBowEventSIGINFO + */ +extern LongBowEventType LongBowEventSIGINFO; + +/** + * @var LongBowEventSIGUSR1 + */ +extern LongBowEventType LongBowEventSIGUSR1; + +/** + * @var LongBowEventSIGUSR2 + */ +extern LongBowEventType LongBowEventSIGUSR2; + +/** + * Determine if two `LongBowEventType` instances are equal. + * + * The following equivalence relations on non-null `LongBowEventType` instances are maintained: + * + * * It is reflexive: for any non-null reference value x, `longBowEventType_Equals(x, x)` must return true. + * + * * It is symmetric: for any non-null reference values x and y, `longBowEventType_Equals(x, y)` must return true if and only if + * `longBowEventType_Equals(y x)` returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * `longBowEventType_Equals(x, y)` returns true and + * `longBowEventType_Equals(y, z)` returns true, + * then `longBowEventType_Equals(x, z)` must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple invocations of `longBowEventType_Equals(x, y)` + * consistently return true or consistently return false. + * + * * For any non-null reference value x, `longBowEventType_Equals(x, NULL)` must return false. + * + * + * @param [in] x A pointer to a `LongBowEventType` instance. + * @param [in] y A pointer to a `LongBowEventType` instance. + * + * @return true `LongBowEventType` x and y are equal. + * @return false `LongBowEventType` x and y are not equal. + * + * Example: + * @code + * { + * LongBowEventType *e1 = LongBowAssertEvent; + * LongBowEventType *e2 = LongBowAssertEvent; + * + * if (longBowEventType_Equals(bufferA, bufferB)) { + * printf("The events are equal.\n"); + * } else { + * printf("The events are NOT equal.\n"); + * } + * } + * @endcode + */ +bool longBowEventType_Equals(const LongBowEventType *x, const LongBowEventType *y); + +/** + * Produce a nul-terminated C string representation of this `LongBowEventType` instance. + * + * @param [in] eventType A pointer to a `LongBowEventType` instance. + * + * @return The C string name of the given LongBowEventType. + * + * Example: + * @code + * { + * LongBowEventType *event = LongBowAssertEvent; + * + * printf("Event = %s\n", longBowEventType_GetName(event)); + * } + * @endcode + */ +const char *longBowEventType_GetName(const LongBowEventType *eventType); + +/** + * Test if a `LongBowEventType` is specified to not report a stack backtrace. + * + * @param [in] eventType A pointer to a `LongBowEventType` instance. + * + * @return true if the LongBowEventType indicates that a backtrace report is not to be printed. + * + * Example: + * @code + * { + * LongBowEvent *event = ... + * + * if (longBowEventType_IsSuppressBacktrace(longBowEvent_GetEventType(event)) == false) { + * char **strs = longBowEvent_CreateSymbolicCallstack(event); + * if (strs != NULL) { + * for (size_t i = 0; i < longBowEvent_GetCallStackLength(event); ++i) { + * printf("%s\r\n", strs[i]); + * } + * free(strs); + * } + * } + * } + * @endcode + */ +bool longBowEventType_IsSuppressBacktrace(const LongBowEventType *eventType); + +/** + * Test if a LongBowEventType is specified to not report an alert. + * + * @param [in] eventType A pointer to a `LongBowEventType` instance. + * + * @return true if the LongBowEventType is specified to not report an alert. + * + * Example: + * @code + * { + * LongBowEvent *event = ... + * + * if (longBowEventType_IsSuppressAlert(longBowEvent_GetEventType(event)) == false) { + * char *location = longBowLocation_ToString(longBowEvent_GetLocation(event)); + * printf("%s %s %s %s\r\n", + * longBowEvent_GetName(event), location, longBowEvent_GetKind(event), longBowEvent_GetMessage(event)); + * + * ... + * } + * + * } + * @endcode + */ +bool longBowEventType_IsSuppressAlert(const LongBowEventType *eventType); + +/** + * Get the status of the specified `LongBowEventType` instance. + * + * @param [in] eventType A pointer to a `LongBowEventType` instance. + * + * @return The LongBowStatus associated with the given LongBowEventType. + * + * Example: + * @code + * { + * LongBowEvent *event = ... + * + * LongBowStatus status = longBowEventType_GetStatus(event); + * // use the status as needed + * } + * @endcode + */ +LongBowStatus longBowEventType_GetStatus(const LongBowEventType *eventType); + +/** + * Get the LongBowEventType corresponding to the given signal. + * + * @param [in] signal The signal to index. + * + * @return the LongBowEventType corresponding to the given signal. + * + * Example: + * @code + * { + * LongBowEventType *type = longBowEventType_GetEventTypeForSignal(1); + * // type is equal to LongBowEventSIGHUP + * } + * @endcode + */ +LongBowEventType *longBowEventType_GetEventTypeForSignal(const int signal); +#endif // LongBow_longBow_EventType_h diff --git a/longbow/src/LongBow/longBow_Location.c b/longbow/src/LongBow/longBow_Location.c new file mode 100755 index 00000000..3d58a11c --- /dev/null +++ b/longbow/src/LongBow/longBow_Location.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#include <LongBow/longBow_Location.h> + +#include <LongBow/private/longBow_Memory.h> + +/** @cond private */ +struct longbow_location { + char *fileName; + char *functionName; + uint32_t lineNumber; +}; +/** @endcond */ + +LongBowLocation * +longBowLocation_Create(const char *fileName, const char *functionName, uint32_t lineNumber) +{ + LongBowLocation *result = longBowMemory_Allocate(sizeof(LongBowLocation)); + + if (result != NULL) { + result->fileName = (fileName == NULL) ? NULL : strdup(fileName); + result->functionName = (functionName == NULL) ? NULL : strdup(functionName); + result->lineNumber = lineNumber; + } + + return result; +} + +void +longBowLocation_Destroy(LongBowLocation **locationPtr) +{ + assert(locationPtr != NULL); + + LongBowLocation *location = *locationPtr; + + if (location->fileName != NULL) { + free(location->fileName); + } + if (location->functionName != NULL) { + free(location->functionName); + } + longBowMemory_Deallocate((void **) locationPtr); +} + +char * +longBowLocation_ToString(const LongBowLocation *location) +{ + assert(location != NULL); + + char *result; + + if (location->functionName == 0) { + int status = asprintf(&result, "%s:%u", location->fileName, location->lineNumber); + if (status == -1) { + return NULL; + } + } else { + int status = asprintf(&result, "%s:%u %s()", location->fileName, location->lineNumber, location->functionName); + if (status == -1) { + return NULL; + } + } + + return result; +} diff --git a/longbow/src/LongBow/longBow_Location.h b/longbow/src/LongBow/longBow_Location.h new file mode 100755 index 00000000..a1e271c3 --- /dev/null +++ b/longbow/src/LongBow/longBow_Location.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Location.h + * @ingroup internals + * @brief LongBow Source File Location + * + * LongBow records events during execution and insofar that it's possible, + * it records the source code location information for reporting. + * + */ +#ifndef LongBow_longBow_Location_h +#define LongBow_longBow_Location_h + +#include <stdint.h> + +struct longbow_location; +/** + * @typedef LongBowLocation + */ +typedef struct longbow_location LongBowLocation; + +/** + * Create a new LongBow location within a source code file. + * + * @param [in] fileName The file target of the location. + * @param [in] functionName The function target of the location. + * @param [in] lineNumber The exact line number within the target file. + * + * @return A pointer to an allocated LongBowLocation instance that must be deallocated via `longBowLocation_Destroy()`. + * + * Example: + * @code + * { + * LongBowLocation *location = longBowLocation_Create("test.c", "main", 101); + * } + * @endcode + */ +LongBowLocation *longBowLocation_Create(const char *fileName, const char *functionName, uint32_t lineNumber); + +/** + * Destroy the `LongBowLocation` instance. + * + * @param [in,out] locationPtr A pointer to the `LongBowLocation` instance to be destroyed. + * + * Example: + * @code + * { + * LongBowLocation *location = longBowLocation_Create("test.c", "main", 101); + * ... + * longBowLocation_Destroy(&location); + * } + * @endcode + */ +void longBowLocation_Destroy(LongBowLocation **locationPtr); + +/** + * Create a human readable representation of the `LongBowLocation` instance. + * + * @param [in] location The `LongBowLocation` instance from which to generate the string representation. + * + * @return An allocated, null-terminated C string that must be freed via free(). + * + * Example: + * @code + * { + * LongBowLocation *location = longBowLocation_Create("test.c", "main", 101); + * char *stringRep = longBowLocation_ToString(location); + * ... + * longBowLocation_Destroy(&location); + * } + * @endcode + */ +char *longBowLocation_ToString(const LongBowLocation *location); +#endif // LongBow_longBow_Location_h diff --git a/longbow/src/LongBow/longBow_Main.c b/longbow/src/LongBow/longBow_Main.c new file mode 100755 index 00000000..7b3e5c01 --- /dev/null +++ b/longbow/src/LongBow/longBow_Main.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdarg.h> + +#include <LongBow/longBow_Main.h> + +#include <LongBow/unit-test.h> +#include <LongBow/Reporting/longBowReport_Testing.h> +#include <LongBow/longBow_Config.h> + +int +longBowMain_Impl(int argc, char *argv[argc], ...) +{ + LongBowStatus exitStatus = LONGBOW_STATUS_SUCCEEDED; + + // Perform some processing on the input parameters. + + LongBowConfig *config = longBowConfig_Create(argc, argv, NULL); + if (config == NULL) { + return LONGBOW_STATUS_FAILED; + } + va_list ap; + va_start(ap, argv); + + for (LongBowTestRunner *testRunner = va_arg(ap, LongBowTestRunner *); testRunner != NULL; testRunner = va_arg(ap, LongBowTestRunner *)) { + if (testRunner != NULL) { + longBowTestRunner_SetConfiguration(testRunner, config); + longBowTestRunner_Run(testRunner); + longBowReportTesting_TestRunner(testRunner); + + if (!longBowTestRunner_IsSuccessful(testRunner)) { + exitStatus = longBowTestRunner_GetStatus(testRunner); + } + } + } + va_end(ap); + + longBowConfig_Destroy(&config); + + return (int) exitStatus; +} diff --git a/longbow/src/LongBow/longBow_Main.h b/longbow/src/LongBow/longBow_Main.h new file mode 100755 index 00000000..a3e35a8d --- /dev/null +++ b/longbow/src/LongBow/longBow_Main.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Main.h + * @ingroup testing + * @brief A main() function to run one or more LongBow Test Runners. + * + * The functions in this file provide execution time support for running LongBow Tests. + * + */ +#ifndef LONGBOWMAIN_H_ +#define LONGBOWMAIN_H_ + +/** + * Run one or more LongBow Test Runners. + * + * The encapsulating function creates one or more `LongBowTestRunner` instances and supplies + * these as a NULL terminated variable argument list to the longBowMain function. + * The return value from longBowMain is suitable as an exit status from an executable as zero is success. + * + * @param [in] argc The number of elements in argv. + * @param [in] argv An array of C string arguments. + * + * @return 0 All tests for all LongBowTestRunners were successful. Otherwise one of `LongBowStatus`. + * + * Example Usage: + * @code + * int + * main(int argc, char *argv[argc]) + * { + * LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(MyTestRunner); + * int exitStatus = longBowMain(argc, argv, testRunner, NULL); + * longBowTestRunner_Destroy(&testRunner); + * exit(exitStatus); + * } + * @endcode + */ +int longBowMain_Impl(int argc, char *argv[], ...); +#endif /* LONGBOWMAIN_H_ */ diff --git a/longbow/src/LongBow/longBow_MeasureTime.c b/longbow/src/LongBow/longBow_MeasureTime.c new file mode 100755 index 00000000..2fc566a5 --- /dev/null +++ b/longbow/src/LongBow/longBow_MeasureTime.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> +#include <stdio.h> +#include <sys/time.h> + +#include <LongBow/longBow_MeasureTime.h> +#include <LongBow/private/longBow_Memory.h> + +struct longBowMeasureTime { + struct timeval start; + struct timeval stop; + unsigned int iterations; +}; + +LongBowMeasureTime * +longBowMeasureTime_Start(unsigned int iterations) +{ + LongBowMeasureTime *result = longBowMemory_Allocate(sizeof(LongBowMeasureTime)); + + if (result != NULL) { + gettimeofday(&result->start, NULL); + result->iterations = iterations; + result->stop = (struct timeval) { .tv_sec = 0, .tv_usec = 0 }; + } + + return result; +} + +LongBowMeasureTime * +longBowMeasureTime_Stop(LongBowMeasureTime *measure) +{ + if (measure != NULL) { + gettimeofday(&measure->stop, NULL); + } + + return measure; +} + +uint64_t +longBowMeasureTime_GetMicroseconds(const LongBowMeasureTime *measure) +{ + struct timeval result; + timersub(&(measure->stop), &(measure->start), &result); + + return ((uint64_t) result.tv_sec * 1000000ULL) + ((uint64_t) result.tv_usec); +} + +uint64_t +longBowMeasureTime_GetNanoseconds(const LongBowMeasureTime *measure) +{ + struct timeval result; + timersub(&(measure->stop), &(measure->start), &result); + + return ((uint64_t) result.tv_sec * 1000000000ULL) + ((uint64_t) result.tv_usec * 1000); +} + +unsigned int +longBowMeasureTime_CountDown(LongBowMeasureTime *measure) +{ + return measure->iterations--; +} + +bool +longBowMeasureTime_Report(LongBowMeasureTime *measure, const char *file, const char *function, unsigned int line) +{ + struct timeval result; + if (measure->stop.tv_sec == 0 && measure->stop.tv_usec == 0) { + longBowMeasureTime_Stop(measure); + } + + timersub(&(measure->stop), &(measure->start), &result); + printf("%s %s %d %ld.%06ld\n", file, function, line, result.tv_sec, (long) result.tv_usec); + return true; +} + +void +longBowMeasureTime_Destroy(LongBowMeasureTime **instancePtr) +{ + longBowMemory_Deallocate((void **) instancePtr); +} diff --git a/longbow/src/LongBow/longBow_MeasureTime.h b/longbow/src/LongBow/longBow_MeasureTime.h new file mode 100644 index 00000000..5e2931e0 --- /dev/null +++ b/longbow/src/LongBow/longBow_MeasureTime.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_MeasureTime.h + * + * Measure elapsed time, providing various fetching and reporting mechanisms. + * + */ +#ifndef __LongBow__longBow_Measure__ +#define __LongBow__longBow_Measure__ +#include <stdint.h> +#include <stdbool.h> + +#ifdef LongBow_DISABLE_MEASUREMENTS +# define longBowMeasureTime(_iterations_) +#else +# define longBowMeasureTime(_iterations_) for (LongBowMeasureTime *_measure = longBowMeasureTime_Start(_iterations_); \ + longBowMeasureTime_CountDown(_measure) ? true : (longBowMeasureTime_Report(_measure, __FILE__, __func__, __LINE__), longBowMeasureTime_Destroy(&_measure), false); ) + +#endif + +struct longBowMeasureTime; +typedef struct longBowMeasureTime LongBowMeasureTime; + +/** + * Create and start a `LongBowMeasureTime` instance. + * + * @param [in] iterations The number of iterations to perform when used with `longBowMeasureTime_CountDown` + * + * @return non-NULL A pointer to a valid LongBowMeasureTime instance that must be destroyed by `longBowMeasureTime_Destroy` + */ +LongBowMeasureTime *longBowMeasureTime_Start(unsigned int iterations); + +/** + * Report on the `LongBowMeasureTime` instance. + * + * @param [in] measure A pointer to a valid LongBowMeasureTime instance. + * @param [in] file A pointer to a nul-terminated C string representing the file name causing the report. + * @param [in] function A pointer to a nul-terminated C string representing the function name causing the report. + * @param [in] line An unsigned integer representing the line number of the file causing the report. + * + * @return true The report was successful. + */ +bool longBowMeasureTime_Report(LongBowMeasureTime *measure, const char *file, const char *function, unsigned int line); + +/** + * A simple count-down supporting measurement iterations. + * + * See {@link longBowMeasureTime} for an example. + * + * @param [in] measure A pointer to a valid LongBowMeasureTime instance. + * + * @return The current value of the counter. + */ +unsigned int longBowMeasureTime_CountDown(LongBowMeasureTime *measure); + +/** + * Get the total number of microseconds represented by the `LongBowMeasureTime` instance. + * + * @param [in] measure A pointer to a valid LongBowMeasureTime instance. + * + * @return The number of microseconds represented by the `LongBowMeasureTime` instance. + */ +uint64_t longBowMeasureTime_GetMicroseconds(const LongBowMeasureTime *measure); + +/** + * Get the total number of nanoseconds represented by the `LongBowMeasureTime` instance. + * + * @param [in] measure A pointer to a valid LongBowMeasureTime instance. + * + * @return The number of nanoseconds represented by the `LongBowMeasureTime` instance. + */ +uint64_t longBowMeasureTime_GetNanoseconds(const LongBowMeasureTime *measure); + +/** + * Destroy a valid `LongBowMeasureTime` instance. + * + * @param [in,out] instancePtr A pointer to a pointer to a valid LongBowMeasureTime instance, that will be set to zero. + */ +void longBowMeasureTime_Destroy(LongBowMeasureTime **instancePtr); + +#endif /* defined(__LongBow__longBow_Measure__) */ diff --git a/longbow/src/LongBow/longBow_Properties.c b/longbow/src/LongBow/longBow_Properties.c new file mode 100644 index 00000000..bf5a9da4 --- /dev/null +++ b/longbow/src/LongBow/longBow_Properties.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <string.h> + +#include <LongBow/private/longBow_String.h> +#include <LongBow/longBow_Properties.h> +#include <LongBow/private/longBow_ArrayList.h> +#include <LongBow/private/longBow_Memory.h> + +struct LongBowProperties { + LongBowArrayList *list; +}; + +typedef struct Property { + const char *name; + const char *value; +} _Property; + +static void +_property_Destroy(_Property **pointer) +{ + _Property *property = *pointer; + longBowMemory_Deallocate((void **) &property->name); + longBowMemory_Deallocate((void **) &property->value); + longBowMemory_Deallocate((void **) property); +} + +LongBowProperties * +longBowProperties_Create(void) +{ + LongBowProperties *result = longBowMemory_Allocate(sizeof(LongBowProperties)); + + if (result != NULL) { + result->list = longBowArrayList_Create((void (*)(void **))_property_Destroy); + } + + return result; +} + +static _Property * +_longBowProperties_Get(const LongBowProperties *properties, const char *name) +{ + _Property *result = NULL; + + for (size_t index = 0; index < longBowArrayList_Length(properties->list); index++) { + _Property *property = longBowArrayList_Get(properties->list, index); + if (strcmp(property->name, name) == 0) { + result = property; + break; + } + } + return result; +} + +const char * +longBowProperties_Get(const LongBowProperties *properties, const char *name) +{ + _Property *property = _longBowProperties_Get(properties, name); + + if (property != NULL) { + return property->value; + } + + return NULL; +} + +bool +longBowProperties_Set(LongBowProperties *properties, const char *name, const char *value) +{ + bool result = false; + + _Property *property = _longBowProperties_Get(properties, name); + if (property == NULL) { + property = longBowMemory_Allocate(sizeof(_Property)); + property->name = longBowMemory_StringCopy(name); + property->value = longBowMemory_StringCopy(value); + longBowArrayList_Add(properties->list, property); + result = true; + } else { + longBowMemory_Deallocate((void **) &property->value); + property->value = longBowMemory_StringCopy(value); + } + return result; +} + +bool +longBowProperties_Exists(const LongBowProperties *properties, const char *name) +{ + return (_longBowProperties_Get(properties, name) == NULL) ? false : true; +} + +bool +longBowProperties_Delete(LongBowProperties *properties, const char *name) +{ + bool result = false; + + for (size_t index = 0; index < longBowArrayList_Length(properties->list); index++) { + _Property *property = longBowArrayList_Get(properties->list, index); + if (strcmp(property->name, name) == 0) { + longBowArrayList_RemoveAtIndex(properties->list, index); + result = true; + } + } + + return result; +} + +size_t +longBowProperties_Length(const LongBowProperties *properties) +{ + return longBowArrayList_Length(properties->list); +} + +char * +longBowProperties_ToString(const LongBowProperties *properties) +{ + LongBowString *string = longBowString_Create(128); + + for (size_t index = 0; index < longBowArrayList_Length(properties->list); index++) { + _Property *property = longBowArrayList_Get(properties->list, index); + longBowString_Format(string, "%s=%s\n", property->name, property->value); + } + + char *result = longBowString_ToString(string); + longBowString_Destroy(&string); + + return result; +} + +void +longBowProperties_Destroy(LongBowProperties **propertiesPtr) +{ + LongBowProperties *properties = *propertiesPtr; + longBowArrayList_Destroy(&properties->list); + longBowMemory_Deallocate((void **) propertiesPtr); +} diff --git a/longbow/src/LongBow/longBow_Properties.h b/longbow/src/LongBow/longBow_Properties.h new file mode 100755 index 00000000..493ce00e --- /dev/null +++ b/longbow/src/LongBow/longBow_Properties.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Properties.h + * @brief A simple properties store. + * + */ +#ifndef __LongBow__longBow_Properties__ +#define __LongBow__longBow_Properties__ + +#include <stdbool.h> +#include <stdlib.h> + +struct LongBowProperties; +typedef struct LongBowProperties LongBowProperties; + +LongBowProperties *longBowProperties_Create(void); + +const char *longBowProperties_Get(const LongBowProperties *properties, const char *name); + +size_t longBowProperties_Length(const LongBowProperties *properties); + +bool longBowProperties_Set(LongBowProperties *properties, const char *name, const char *value); + +bool longBowProperties_Exists(const LongBowProperties *properties, const char *name); + +bool longBowProperties_Delete(LongBowProperties *properties, const char *name); + +void longBowProperties_Destroy(LongBowProperties **propertiesPtr); + +char *longBowProperties_ToString(const LongBowProperties *properties); + +#endif /* defined(__LongBow__longBow_Properties__) */ diff --git a/longbow/src/LongBow/longBow_Runtime.c b/longbow/src/LongBow/longBow_Runtime.c new file mode 100755 index 00000000..c283b743 --- /dev/null +++ b/longbow/src/LongBow/longBow_Runtime.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <stdint.h> +#include <signal.h> +#include <errno.h> + +#include <LongBow/longBow_Runtime.h> +#include <LongBow/longBow_Backtrace.h> +#include <LongBow/longBow_Location.h> +#include <LongBow/longBow_Event.h> +#include <LongBow/longBow_Config.h> + +#include <LongBow/Reporting/longBowReport_Runtime.h> + +#include <LongBow/private/longBow_Memory.h> + +static unsigned int longBowStackTraceDepth = 128; + +struct longbow_runtime { + LongBowConfig *config; + LongBowRuntimeResult expectedResult; + LongBowRuntimeResult actualResult; +}; + +static LongBowRuntime longBowRuntimeGlobal; + +static LongBowRuntime *longBowCurrentRuntime = &longBowRuntimeGlobal; + + +static char * +_longBowRuntime_FormatErrnoMessage(void) +{ + char *result = NULL; + if (errno != 0) { + if (asprintf(&result, "%s: ", strerror(errno)) == -1) { + return NULL; + } + } + return result; +} + +static char * +_longBowRuntime_FormatMessage(const char *format, va_list args) +{ + char *errnoMessage = _longBowRuntime_FormatErrnoMessage(); + + char *string; + if (vasprintf(&string, format, args) == -1) { + return NULL; + } + + char *result = NULL; + + if (errnoMessage != NULL) { + int check = asprintf(&result, "%s%s", errnoMessage, string); + free(errnoMessage); + if (check == -1) { + return NULL; + } + } else { + result = strndup(string, strlen(string)); + } + + free(string); + + return result; +} + +LongBowRuntime * +longBowRuntime_Create(const LongBowRuntimeResult *expectedResultTemplate, LongBowConfig *config) +{ + assert(expectedResultTemplate != NULL); + + LongBowRuntime *result = longBowMemory_Allocate(sizeof(LongBowRuntime)); + if (result != NULL) { + result->expectedResult = *expectedResultTemplate; + result->config = config; + } + return result; +} + +size_t +longBowRuntime_GetActualEventEvaluationCount(LongBowRuntime *runtime) +{ + return longBowRuntimeResult_GetEventEvaluationCount(longBowRuntime_GetActualTestCaseResult(runtime)); +} + +void +longBowRuntime_Destroy(LongBowRuntime **runtimePtr) +{ + longBowMemory_Deallocate((void **) runtimePtr); +} + +LongBowRuntimeResult * +longBowRuntime_GetExpectedTestCaseResult(const LongBowRuntime *const runtime) +{ + return (LongBowRuntimeResult *) &(runtime->expectedResult); +} + +LongBowRuntimeResult * +longBowRuntime_GetActualTestCaseResult(const LongBowRuntime *runtime) +{ + return (LongBowRuntimeResult *) &(runtime->actualResult); +} + +LongBowRuntime * +longBowRuntime_SetCurrentRuntime(LongBowRuntime *runtime) +{ + LongBowRuntime *result = longBowCurrentRuntime; + longBowCurrentRuntime = runtime; + return result; +} + +LongBowRuntime * +longBowRuntime_GetCurrentRuntime(void) +{ + return longBowCurrentRuntime; +} + +LongBowConfig * +longBowRuntime_GetCurrentConfig(void) +{ + return longBowCurrentRuntime->config; +} + +void +longBowRuntime_SetCurrentConfig(LongBowConfig *config) +{ + longBowCurrentRuntime->config = config; +} + +LongBowEventType * +longBowRuntime_GetActualEventType(const LongBowRuntime *runtime) +{ + return runtime->actualResult.event; +} + +LongBowEventType * +longBowRuntime_GetExpectedEventType(const LongBowRuntime *runtime) +{ + return runtime->expectedResult.event; +} + +void +longBowRuntime_SetActualEventType(LongBowRuntime *runtime, LongBowEventType *eventType) +{ + runtime->actualResult.event = eventType; +} + +bool +longBowRuntime_EventEvaluation(const LongBowEventType *type) +{ + longBowCurrentRuntime->actualResult.eventEvaluationCount++; + return true; +} + +unsigned int +longBowRuntime_SetStackTraceDepth(unsigned int newDepth) +{ + unsigned int previousValue = longBowStackTraceDepth; + longBowStackTraceDepth = newDepth; + return previousValue; +} + +unsigned int +longBowRuntime_GetStackTraceDepth(void) +{ + return longBowStackTraceDepth; +} + +bool +longBowRuntime_EventTrigger(LongBowEventType *eventType, LongBowLocation *location, const char *kind, const char *format, ...) +{ + LongBowRuntime *runtime = longBowRuntime_GetCurrentRuntime(); + + longBowRuntime_SetActualEventType(runtime, eventType); + + if (runtime->expectedResult.status == LONGBOW_STATUS_FAILED) { + return true; + } + + if (longBowEventType_Equals(longBowRuntime_GetActualEventType(runtime), longBowRuntime_GetExpectedEventType(runtime))) { + return true; + } + + va_list args; + va_start(args, format); + + char *messageString = _longBowRuntime_FormatMessage(format, args); + + va_end(args); + + LongBowBacktrace *stackTrace = longBowBacktrace_Create(longBowRuntime_GetStackTraceDepth(), 2); + + LongBowEvent *event = longBowEvent_Create(eventType, location, kind, messageString, stackTrace); + + free(messageString); + longBowReportRuntime_Event(event); + longBowEvent_Destroy(&event); + return true; +} + +void +longBowRuntime_StackTrace(int fileDescriptor) +{ + LongBowBacktrace *backtrace = longBowBacktrace_Create(longBowRuntime_GetStackTraceDepth(), 1); + char *string = longBowBacktrace_ToString(backtrace); + fwrite(string, strlen(string), 1, stdout); + longBowMemory_Deallocate((void **) &string); + longBowBacktrace_Destroy(&backtrace); +} + +bool +longBowRuntime_TestAddressIsAligned(const void *address, size_t alignment) +{ + if ((alignment & (~alignment + 1)) == alignment) { + return (((uintptr_t) address) % alignment) == 0 ? true : false; + } + return false; +} + +void +longBowRuntime_CoreDump(void) +{ + struct rlimit coreDumpLimit; + + coreDumpLimit.rlim_cur = RLIM_INFINITY; + coreDumpLimit.rlim_max = RLIM_INFINITY; + + if (setrlimit(RLIMIT_CORE, &coreDumpLimit) < 0) { + fprintf(stderr, "setrlimit: %s\n", strerror(errno)); + exit(1); + } + kill(0, SIGTRAP); +} + +void +longBowRuntime_Abort(void) +{ + bool coreDump = longBowConfig_GetBoolean(longBowRuntime_GetCurrentConfig(), false, "core-dump"); + if (coreDump == false) { + abort(); + } else { + longBowRuntime_CoreDump(); + } +} diff --git a/longbow/src/LongBow/longBow_Runtime.h b/longbow/src/LongBow/longBow_Runtime.h new file mode 100644 index 00000000..ff5527eb --- /dev/null +++ b/longbow/src/LongBow/longBow_Runtime.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Runtime.h + * @ingroup runtime + * @brief The LongBow Runtime support. + * + */ +#ifndef LongBow_longBow_Runtime_h +#define LongBow_longBow_Runtime_h + +#include <LongBow/longBow_Event.h> +#include <LongBow/longBow_RuntimeResult.h> +#include <LongBow/longBow_Config.h> + +struct longbow_runtime; +typedef struct longbow_runtime LongBowRuntime; + +/** + * Create and return a new `LongBowRuntime` instance with the specified `LongBowRuntimeResult` instance. + * + * @param [in] expectedResultTemplate A `LongBowRuntimeResult` instance. + * + * @return A pointer to an allocated LongBowRuntime instance that must be deallocated via longBowRuntime_Destroy + */ +LongBowRuntime *longBowRuntime_Create(const LongBowRuntimeResult *expectedResultTemplate, LongBowConfig *config); + +/** + * Destroy the `LongBowRuntime` instance. + * + * @param [in,out] runtimePtr A pointer to a `LongBowRuntime` instance. + */ +void longBowRuntime_Destroy(LongBowRuntime **runtimePtr); + +/** + * Get the expected test case result from the `LongBowRuntime` instance. + * + * @param [in] runtime A `LongBowRuntime` instance. + * + * @return A pointer to the expected LongBowRuntimeResult. + */ +LongBowRuntimeResult *longBowRuntime_GetExpectedTestCaseResult(const LongBowRuntime *runtime); + +/** + * Get the actual test case result from the `LongBowRuntime` instance. + * + * @param [in] runtime A `LongBowRuntime` instance. + * + * @return A pointer to the actual LongBowRuntimeResult. + */ +LongBowRuntimeResult *longBowRuntime_GetActualTestCaseResult(const LongBowRuntime *runtime); + +/** + * Get the number of events that were evalutated. + * + * @param [in] runtime A `LongBowRuntime` instance. + * + * @return The number of events that were evalutated. + */ +size_t longBowRuntime_GetActualEventEvaluationCount(LongBowRuntime *runtime); + +/** + * Get the LongBowEventType of the given LongBowRuntime. + * + * @param [in] runtime A `LongBowRuntime` instance. + * + * @return The LongBowEventType of the given LongBowRuntime. + */ +LongBowEventType *longBowRuntime_GetActualEventType(const LongBowRuntime *runtime); + +/** + * Get the expected EventType from the given LongBowRuntime. + * + * When testing, a test may set a LongBowEventType that is expected to be triggered. + * This function simply gets the expected LongBowEventType from the given LongBowRuntime instance. + * + * @param [in] runtime A pointer to a LongBowRuntime instance. + * + * @return The expected EventType in the LongBowRuntime. + */ +LongBowEventType *longBowRuntime_GetExpectedEventType(const LongBowRuntime *runtime); + +/** + * Set the "actual" LongBowEventType of the given LongBowRuntime. + * + * @param [in] runtime A `LongBowRuntime` instance. + * @param [in] eventType A `LongBowEventType` instance. + */ +void longBowRuntime_SetActualEventType(LongBowRuntime *runtime, LongBowEventType *eventType); + +/** + * Set the current `LongBowRuntime`. + * + * @param [in] runtime A `LongBowRuntime` instance. + * + * @return The previous LongBowRuntime + */ +LongBowRuntime *longBowRuntime_SetCurrentRuntime(LongBowRuntime *runtime); + +/** + * Retrieve the current `LongBowRuntime`. + * + * @return The current global LongBowRuntime. + */ +LongBowRuntime *longBowRuntime_GetCurrentRuntime(void); + +/** + * Retrieve the `LongBowConfig` instance of the current global runtime. + * + * @return The `LongBowConfig` instance of the current global runtime. + */ +LongBowConfig *longBowRuntime_GetCurrentConfig(void); + +/** + * Set the `LongBowConfig` instance of the current global runtime. + * + * @param [in] config The new `LongBowConfig` instance of the current global runtime. + */ +void longBowRuntime_SetCurrentConfig(LongBowConfig *config); + +/** + * Trigger a LongBow event. + * + * The event will be reported via the longBowReport_Event. + * + * @param [in] eventType The type of event. + * @param [in] location The LongBowLocation of the event (this will be destroyed). + * @param [in] kind A string indicating the kind of event this is triggering. + * @param [in] format A printf format string. + * @param [in] ... Parameters associated with the printf format string. + * + * @return true Always return true. + */ +bool longBowRuntime_EventTrigger(LongBowEventType *eventType, + LongBowLocation *location, + const char *kind, + const char *format, ...) __attribute__((__format__(__printf__, 4, 5))); +/** + * Record an event evaluation. + * + * This only records the fact of the evaluation, not the results of the evaluation. + * + * @param [in] type A pointer to the LongBowEventType being evaluated. + * + * @return true Always returns true. + * + * Example: + * @code + * { + * longBowRuntime_EventEvaluation(&LongBowAssertEvent); + * } + * @endcode + */ +bool longBowRuntime_EventEvaluation(const LongBowEventType *type); + +/** + * Set the current value for the depth of printed stack trace. + * + * If the depth is less than 1, no stack trace is displayed. + * + * @param [in] newDepth The new value to set. + * + * @return The previous value. + */ +unsigned int longBowRuntime_SetStackTraceDepth(unsigned int newDepth); + +/** + * Get the current value for the depth of printed stack trace. + * + * @return The current stack-trace depth. + */ +unsigned int longBowRuntime_GetStackTraceDepth(void); + +/** + * Print a formatted stack trace to the current output file descriptor. + * + * @param [in] fileDescriptor A valid file descriptor. + */ +void longBowRuntime_StackTrace(int fileDescriptor); + +/** + * Abort the running process using the current runtime environment. + * If the configuration is set to produce a core dump, this function simply returns. + * This permits the caller to use the form: + * <code> + * longBowRuntime_Abort(), kill(0, SIGTRACE) + * </code> + * To generate a core image. + * + * See the assertion macros for how this is used. + */ +void longBowRuntime_Abort(void); +#endif // LongBow_longBow_Runtime_h diff --git a/longbow/src/LongBow/longBow_RuntimeResult.c b/longbow/src/LongBow/longBow_RuntimeResult.c new file mode 100755 index 00000000..f91dfe1e --- /dev/null +++ b/longbow/src/LongBow/longBow_RuntimeResult.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <sys/time.h> + +#include <LongBow/longBow_RuntimeResult.h> + +size_t +longBowRuntimeResult_GetEventEvaluationCount(const LongBowRuntimeResult *testCaseResult) +{ + return testCaseResult->eventEvaluationCount; +} + +LongBowEventType * +longBowRuntimeResult_GetEvent(const LongBowRuntimeResult *testCaseResult) +{ + return testCaseResult->event; +} + +void +longBowRuntimeResult_SetEvent(LongBowRuntimeResult *testCaseResult, LongBowEventType *eventType) +{ + testCaseResult->event = eventType; +} + +void +longBowRuntimeResult_SetStatus(LongBowRuntimeResult *testCaseResult, LongBowStatus status) +{ + testCaseResult->status = status; +} +void +longBowRuntimeResult_SetElapsedTime(LongBowRuntimeResult *testCaseResult, struct timeval *elapsedTime) +{ + testCaseResult->elapsedTime = *elapsedTime; +} + +struct rusage * +longBowRuntimeResult_GetRUsage(LongBowRuntimeResult *testCaseResult) +{ + return &testCaseResult->resources; +} + +void +longBowRuntimeResult_SetRUsage(LongBowRuntimeResult *testCaseResult, struct rusage *resources) +{ + testCaseResult->resources = *resources; +} + +LongBowStatus +longBowRuntimeResult_GetStatus(const LongBowRuntimeResult *testCaseResult) +{ + return testCaseResult->status; +} + +struct timeval +longBowRuntimeResult_GetElapsedTime(const LongBowRuntimeResult *testCaseResult) +{ + return testCaseResult->elapsedTime; +} diff --git a/longbow/src/LongBow/longBow_RuntimeResult.h b/longbow/src/LongBow/longBow_RuntimeResult.h new file mode 100755 index 00000000..367ad1ae --- /dev/null +++ b/longbow/src/LongBow/longBow_RuntimeResult.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_RuntimeResult.h + * @ingroup internals + * @brief LongBow Test Case Results + * + * LongBow Test Cases have expected and actual results. + * The expected results are typically a statically created instance of {@link LongBowRuntimeResult} + * which is used when the Test Case is executed to compare with the actual results. + * This permits, for example, a Test Case to indicate that it is expected to induce a specific LongBowEvent. + * In which case, the actual LongBowEvent must equal the expected event for the Test Case to be considered a success. + * + */ +#ifndef LongBow_longBow_CaseResult_h +#define LongBow_longBow_CaseResult_h + +#include <stdlib.h> +#include <stdint.h> +#include <sys/resource.h> + +#include <LongBow/longBow_Status.h> +#include <LongBow/longBow_Event.h> + +struct longbow_testcase_result; + +/** + * @typedef LongBowRuntimeResult + * @brief The expected and actual result of a LongBow Test. + */ +typedef struct longbow_testcase_result LongBowRuntimeResult; + +/** + * @struct longbow_testcase_result + * @brief The expected and actual result of a LongBow Test. + */ +struct longbow_testcase_result { + /** + * The number of event evaluations performed. + * These asserts and traps with conditions that were evaluated. + */ + size_t eventEvaluationCount; + LongBowStatus status; /**< The resulting status of the test case. */ + struct timeval elapsedTime; /**< The elapsed time of the test case. */ + struct rusage resources; /**< The resulting resource usage of the test case. */ + LongBowEventType *event; /**< The expected or actual event. */ +}; + +/** + * Return the event evaluation count associated with the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * + * @return The number of Event evaluations. + */ +size_t longBowRuntimeResult_GetEventEvaluationCount(const LongBowRuntimeResult *testCaseResult); + +/** + * Retrieve the event type associated with the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * + * @return The LongBowEventType for the given LongBowRuntimeResult. + */ +LongBowEventType *longBowRuntimeResult_GetEvent(const LongBowRuntimeResult *testCaseResult); + +/** + * Set the event type associated with the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * @param [in] eventType A new `LongBowEventType` instance. + */ +void longBowRuntimeResult_SetEvent(LongBowRuntimeResult *testCaseResult, LongBowEventType *eventType); + +/** + * Get the LongBowStatus type from the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * + * @return The LongBowStatus of the given LongBowRuntimeResult. + */ +LongBowStatus longBowRuntimeResult_GetStatus(const LongBowRuntimeResult *testCaseResult); + +/** + * Set the LongBowStatus type for the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * @param [in] status A `LongBowStatus` value. + */ +void longBowRuntimeResult_SetStatus(LongBowRuntimeResult *testCaseResult, LongBowStatus status); + +/** + * Set the elapsed time for the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * @param [in] elapsedTime A `struct timeval` instance. + */ +void longBowRuntimeResult_SetElapsedTime(LongBowRuntimeResult *testCaseResult, struct timeval *elapsedTime); + +/** + * Get the elapsed time associated with the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * + * @return A copy of the timeval of the given LongBowRuntimeResult. + */ +struct timeval longBowRuntimeResult_GetElapsedTime(const LongBowRuntimeResult *testCaseResult); + +/** + * Retrieve the RUsage struct from the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * + * @return A pointer to the struct rusage instance in the given LongBowRuntimeResult. + */ +struct rusage *longBowRuntimeResult_GetRUsage(LongBowRuntimeResult *testCaseResult); + +/** + * Set the RUsage struct for the given `LongBowRuntimeResult` instance. + * + * @param [in] testCaseResult A `LongBowRuntimeResult` instance. + * @param [in] rusage A `struct rusage` instance. + */ +void longBowRuntimeResult_SetRUsage(LongBowRuntimeResult *testCaseResult, struct rusage *rusage); +#endif diff --git a/longbow/src/LongBow/longBow_Status.c b/longbow/src/LongBow/longBow_Status.c new file mode 100644 index 00000000..200a2aea --- /dev/null +++ b/longbow/src/LongBow/longBow_Status.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> + +#include <LongBow/longBow_Status.h> +#include <LongBow/unit-test.h> + +bool +longBowStatus_IsSuccessful(LongBowStatus status) +{ + if (status == LONGBOW_STATUS_SUCCEEDED || longBowStatus_IsWarning(status) || longBowStatus_IsIncomplete(status)) { + return true; + } + return false; +} + +bool +longBowStatus_IsFailed(LongBowStatus status) +{ + switch (status) { + case LONGBOW_STATUS_FAILED: + case LONGBOW_STATUS_MEMORYLEAK: + case LongBowStatus_STOPPED: + case LONGBOW_STATUS_TEARDOWN_FAILED: + case LONGBOW_STATUS_SETUP_FAILED: + return true; + + default: + if (status >= LongBowStatus_SIGNALLED) { + return true; + } + return false; + } +} + +bool +longBowStatus_IsWarning(LongBowStatus status) +{ + switch (status) { + case LongBowStatus_WARNED: + case LongBowStatus_TEARDOWN_WARNED: + return true; + + default: + return false; + } +} + +bool +longBowStatus_IsIncomplete(LongBowStatus status) +{ + switch (status) { + case LONGBOW_STATUS_SKIPPED: + case LongBowStatus_UNIMPLEMENTED: + case LongBowStatus_IMPOTENT: + return true; + + default: + return false; + } +} + +bool +longBowStatus_IsSignalled(LongBowStatus status) +{ + return status >= LongBowStatus_SIGNALLED; +} + +static struct toString { + LongBowStatus status; + char *string; +} toString[] = { + { LONGBOW_STATUS_SUCCEEDED, "Succeeded" }, + { LongBowStatus_WARNED, "Warning" }, + { LongBowStatus_TEARDOWN_WARNED, "Tear Down Warning" }, + { LONGBOW_STATUS_SKIPPED, "Skipped" }, + { LongBowStatus_UNIMPLEMENTED, "Unimplemented" }, + { LongBowStatus_IMPOTENT, "Impotent" }, + { LONGBOW_STATUS_FAILED, "Failed" }, + { LongBowStatus_STOPPED, "Stopped" }, + { LONGBOW_STATUS_TEARDOWN_FAILED, "Tear Down Failed" }, + { LONGBOW_STATUS_SETUP_FAILED, "Setup Failed" }, + { LONGBOW_STATUS_MEMORYLEAK, "Memory Leak" }, + { 0, NULL }, +}; + +static const char * +_longBowStatus_StatusToString(const LongBowStatus status) +{ + const char *result = NULL; + for (const struct toString *element = &toString[0]; element->string != NULL; element++) { + if (element->status == status) { + result = element->string; + break; + } + } + return result; +} + +char * +longBowStatus_ToString(const LongBowStatus status) +{ + char *result = (char *) _longBowStatus_StatusToString(status); + + if (result == NULL) { + if (status >= LongBowStatus_SIGNALLED) { + int signalNumber = status - LongBowStatus_SIGNALLED; + char *signalName = strsignal(signalNumber); + int check; + if (signalName == NULL) { + check = asprintf(&result, "Signaled %d.", signalNumber); + } else { + check = asprintf(&result, "Signaled %s.", signalName); + } + if (check == -1) { + return NULL; + } + } else { + int check = asprintf(&result, "Unknown status: %d. This is a bug.", status); + if (check == -1) { + return NULL; + } + } + } else { + result = strdup(result); + } + + return result; +} diff --git a/longbow/src/LongBow/longBow_Status.h b/longbow/src/LongBow/longBow_Status.h new file mode 100755 index 00000000..de45ae6d --- /dev/null +++ b/longbow/src/LongBow/longBow_Status.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Status.h + * @ingroup testing + * @brief A simple status representation for a LongBow Test Case. + * + */ +#ifndef LongBow_longBow_Status_h +#define LongBow_longBow_Status_h + +#include <stdbool.h> +#include <stdint.h> + +/** + * @typedef LongBowStatus + * @brief The status of an individual Test Case, and aggregate Test Fixture, or Test Runner. + * + * Status is either successful or not and each has a subset of qualifiers. + * + * A successful status is an outright success, or a qualified success. + * + * Qualified success is a test that issued an explicit warning (via <code>testWarn(...)</code>), + * was purposefully skipped (via <code>testSkip(...)</code>), + * or is unimplemented (via <code>testUnimplemented(...)</code>). + * + * Correspondingly, an unsuccessful test is outright failure, + * or a qualified failure. + * Qualified values indicate that the test process received a signal during the test, + * or either the Test Fixture set-up or tear-down steps signaled failure. + * + */ +enum LongBowStatus { + /** + * Used for expressing the expected status. + */ + LongBowStatus_DONTCARE = -2, + + /** + * The test was not run (initial state). + */ + LongBowStatus_UNTESTED = -1, + + /* successful */ + /** + * The test was successful. + */ + LONGBOW_STATUS_SUCCEEDED = 0, + /** + * The test was successful, but with a warning. + */ + + LongBowStatus_WARNED = 10, + /** + * The test was successful, but the tear down issued a warning. + */ + + LongBowStatus_TEARDOWN_WARNED = 11, + + /** + * The test was purposefully skipped by the test implementor. + */ + LONGBOW_STATUS_SKIPPED = 21, + + /** + * The test was incomplete because it signals that it is not implemented. + */ + LongBowStatus_UNIMPLEMENTED = 22, + + /** + * The test ran but evaluated nothing. + */ + LongBowStatus_IMPOTENT = 23, + + /** + * The setup function signals that all of the subordinate test cases must be skipped. + */ + LONGBOW_STATUS_SETUP_SKIPTESTS = 24, + + /* failures */ + /** + * The tests failed. + */ + LONGBOW_STATUS_FAILED = 1, + + /** + * The test failed because it was stopped by a signal. + */ + LongBowStatus_STOPPED = 3, + + /** + * The tear down of the test failed. + * + * This doesn't imply that the test failed. + */ + LONGBOW_STATUS_TEARDOWN_FAILED = 4, + + /** + * The test was incomplete because the setup for the test failed. + */ + LONGBOW_STATUS_SETUP_FAILED = 5, + + /** + * The test was incomplete because a memory leak was detected. + */ + LONGBOW_STATUS_MEMORYLEAK = 6, + + /** + * The test failed due to an uncaught signal. + */ + LongBowStatus_SIGNALLED = 100, + + /** + * The limit of LongBowStatus values + */ + LongBowStatus_LIMIT = 200, +}; +typedef enum LongBowStatus LongBowStatus; + +/** + * Compose a LongBowStatus from the given signalNumber. + */ +#define LongBowStatus_SIGNAL(signalNumber) (LongBowStatus_SIGNALLED + signalNumber) + +/** + * Generate a human readable, nul-terminated C string representation of the `LongBowStatus` value. + * + * @param [in] status A `LongBowStatus` value + * + * @return A pointer to an allocated C string that must be freed via stdlib.h free(3). + * + * Example: + * @code + * { + * LongBowStatus status = LONGBOW_STATUS_SUCCEEDED; + * printf("Status = %s\n", longBowStatus_ToString(status)); + * } + * @endcode + */ +char *longBowStatus_ToString(LongBowStatus status); + +/** + * Return `true` if the given status indicates an outright or qualified success. + * + * Success, outright or qualified, encompasses `LONGBOW_STATUS_SUCCEEDED`, + * longBowStatus_IsWarning(status), or + * longBowStatus_IsIncomplete(status) + * + * @param [in] status A `LongBowStatus` value. + * + * @return `true` if the given status indicated an outright or qualified success. + * + * Example: + * @code + * { + * LongBowStatus status = LONGBOW_STATUS_SUCCEEDED; + * printf("Is success? = %d\n", longBowStatus_IsSuccessful(status)); + * } + * @endcode + */ +bool longBowStatus_IsSuccessful(LongBowStatus status); + +/** + * Return <code>true</code> if the given status indicates a failure. + * + * @param [in] status A `LongBowStatus` value. + * + * @return `true` if the given status indicated a failure. + * + * Example: + * @code + * { + * LongBowStatus status = LONGBOW_STATUS_FAILED; + * printf("Is warned? = %d\n", longBowStatus_IsFailed(status)); + * } + * @endcode + */ +bool longBowStatus_IsFailed(LongBowStatus status); + +/** + * Return <code>true</code> if the given status indicates a warning. + * + * @param [in] status A `LongBowStatus` value. + * + * @return Return `true` if the given status indicate a warning. + */ +bool longBowStatus_IsWarning(LongBowStatus status); + +/** + * Return <code>true</code> if the given status indicates a test was incomplete. + * + * @param [in] status A `LongBowStatus` value. + * + * @return `true` if the given status indicated it was incomplete. + * + * Example: + * @code + * { + * LongBowStatus status = LONGBOW_STATUS_SKIPPED; + * printf("Is incomplete? = %d\n", longBowStatus_IsIncomplete(status)); + * } + * @endcode + */ +bool longBowStatus_IsIncomplete(LongBowStatus status); + +/** + * Return <code>true</code> if the given status indicated a test induced a signal. + * + * @param [in] status A `LongBowStatus` value. + * + * @return `true` if the given status indicated a test induced a signal. + * + * Example: + * @code + * { + * LongBowStatus status = LongBowStatus_SIGNALLED; + * printf("Is signalled? = %d\n", longBowStatus_IsSignalled(status)); + * } + * @endcode + */ +bool longBowStatus_IsSignalled(LongBowStatus status); +#endif // LONGBOWSTATUS_H_ diff --git a/longbow/src/LongBow/longBow_SubProcess.c b/longbow/src/LongBow/longBow_SubProcess.c new file mode 100755 index 00000000..2bd91dd5 --- /dev/null +++ b/longbow/src/LongBow/longBow_SubProcess.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +# include "longBow_SubProcess_Darwin_x86_64.c" diff --git a/longbow/src/LongBow/longBow_SubProcess.h b/longbow/src/LongBow/longBow_SubProcess.h new file mode 100755 index 00000000..83aac8c8 --- /dev/null +++ b/longbow/src/LongBow/longBow_SubProcess.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_SubProcess.h + * @ingroup testing + * @brief Facilities for running and managing subprocesses. + * + */ +#ifndef LongBow_longBow_SubProcess_h +#define LongBow_longBow_SubProcess_h + +#include <stdbool.h> + +struct longbow_subprocess; +typedef struct longbow_subprocess LongBowSubProcess; + +/** + * Start a subprocess. + * + * @param [in] path The pathname, either absolute or relative to the current directory, of the program to execute. + * @param [in] ... A NULL terminated parameter list consisting of the parameters of the executable starting at `argv[0]`. + * + * @return A pointer to a `LongBowSubProcess` instance. + * + * Example: + * @code + * { + * LongBowSubProcess *process = longBowSubProcess_Exec("/bin/pwd", "pwd", NULL); + * } + * @endcode + * + * @see longBowSubProcess_Wait + * @see longBowSubProcess_Signal + * @see longBowSubProcess_Terminate + * @see longBowSubProcess_Wait + */ +LongBowSubProcess *longBowSubProcess_Exec(const char *path, ... /*, (char *)0 */); + +/** + * Destroy a `LongBowSubProcess` + * + * If the process is still running it is sent the SIGKILL signal. + * + * @param [in] subProcessPtr A pointer to a `LongBowSubProcess` instance. + * + * Example: + * @code + * { + * LongBowSubProcess *process = longBowSubProcess_Exec("/bin/pwd", "pwd", NULL); + * + * longBowSubProcess_Destroy(&process); + * } + * @endcode + * + * @see longBowSubProcess_Exec + */ +void longBowSubProcess_Destroy(LongBowSubProcess **subProcessPtr); + +/** + * Send a signal to a LongBowSubProcess + * + * @param [in] subProcess The LongBowSubProcess to receive the signal. + * @param [in] signalNumber The signal to send. + * + * @return true The signal was successfully sent. + * @return false The signal was not successfully sent. + * + * Example: + * @code + * { + * longBowSubProcess_Signal(subProcess, SIGTERM); + * } + * @endcode + * + * @see longBowSubProcess_Terminate + */ +bool longBowSubProcess_Signal(LongBowSubProcess *subProcess, int signalNumber); + +/** + * Send a SIGTERM to a LongBowSubProcess + * + * @param [in] subProcess The LongBowSubProcess to receive the signal. + * + * @return true The signal was successfully sent. + * @return false The signal was not successfully sent. + * + * Example: + * @code + * { + * longBowSubProcess_Signal(subProcess, SIGTERM); + * } + * @endcode + * + * @see longBowSubProcess_Terminate + */ +bool longBowSubProcess_Terminate(LongBowSubProcess *subProcess); + +/** + * Wait for a `LongBowSubProcess` to stop or terminate + * + * @param [in] subProcess The LongBowSubProcess to wait for. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + * + */ +void longBowSubProcess_Wait(LongBowSubProcess *subProcess); + +/** + * Print a human readable representation of the given `LongBowSubProcess`. + * + * @param [in] indentation The level of indentation to use to pretty-print the output. + * @param [in] subprocess A pointer to the instance to display. + * + * Example: + * @code + * { + * LongBowSubProcess *process = longBowSubProcess_Exec("/bin/pwd", "pwd", NULL); + * + * longBowSubProcess_Display(process, 0); + * + * longBowSubProcess_Destroy(&process); + * } + * @endcode + * + */ +void longBowSubProcess_Display(const LongBowSubProcess *subprocess, int indentation); +#endif diff --git a/longbow/src/LongBow/longBow_SubProcess_Darwin_x86_64.c b/longbow/src/LongBow/longBow_SubProcess_Darwin_x86_64.c new file mode 100755 index 00000000..6c0a0f7a --- /dev/null +++ b/longbow/src/LongBow/longBow_SubProcess_Darwin_x86_64.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <signal.h> + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> + +#include <LongBow/longBow_SubProcess.h> +#include <LongBow/private/longBow_Memory.h> + +struct longbow_subprocess { + const char *path; + char **arguments; + pid_t pid; + int exitStatus; + struct rusage rusage; +}; + +static void +_resetAllSignals(void) +{ + struct sigaction signalAction; + signalAction.sa_handler = SIG_DFL; + signalAction.sa_flags = SA_SIGINFO; + sigemptyset(&signalAction.sa_mask); + + for (int i = 1; i < NSIG; i++) { + sigaction(i, &signalAction, NULL); + } +} + +LongBowSubProcess * +longBowSubProcess_Exec(const char *path, ... /*, (char *)0 */) +{ + va_list ap; + va_start(ap, path); + + size_t count = 0; + for (char *arg = va_arg(ap, char *); arg != NULL; arg = va_arg(ap, char *)) { + count++; + } + + LongBowSubProcess *result = longBowMemory_Allocate(sizeof(LongBowSubProcess)); + + result->path = path; + longBowMemory_Allocate(sizeof(char *) * count + 1); + va_end(ap); + // This relies on the last element being all zeros. + va_start(ap, path); + + for (size_t i = 0; i < count; i++) { + result->arguments[i] = va_arg(ap, char *); + } + va_end(ap); + + result->pid = fork(); + if (result->pid == 0) { + _resetAllSignals(); + printf("Exec %s\n", result->path); + int error = execv(result->path, result->arguments); + printf("Error %d\n", error); + perror(path); + exit(1); + } + + printf("Process group child=%d, parent=%d\n", getpgid(result->pid), getpgrp()); + return result; +} + +void +longBowSubProcess_Destroy(LongBowSubProcess **processPtr) +{ + LongBowSubProcess *process = *processPtr; + + if (process->pid) { + longBowSubProcess_Signal(process, SIGKILL); + } + + longBowMemory_Deallocate((void **) process->arguments); + longBowMemory_Deallocate((void **) processPtr); +} + +bool +longBowSubProcess_Terminate(LongBowSubProcess *subProcess) +{ + return longBowSubProcess_Signal(subProcess, SIGTERM); +} + +bool +longBowSubProcess_Signal(LongBowSubProcess *subProcess, int signalNumber) +{ + return kill(subProcess->pid, signalNumber) == 0; +} + +void +longBowSubProcess_Wait(LongBowSubProcess *subProcess) +{ + wait4(subProcess->pid, &subProcess->exitStatus, 0, &subProcess->rusage); + subProcess->pid = 0; +} + +void +longBowSubProcess_Display(const LongBowSubProcess *subprocess, int indentation) +{ + printf("%*s%s: ", indentation, "", subprocess->path); + if (subprocess->pid == 0) { + printf("not running .exitStatus=%d ", subprocess->exitStatus); + } else { + printf(".pid=%d", subprocess->pid); + } + + printf("\n"); +} diff --git a/longbow/src/LongBow/longBow_TestCase.c b/longbow/src/LongBow/longBow_TestCase.c new file mode 100644 index 00000000..ca506ae8 --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCase.c @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <unistd.h> +#include <setjmp.h> +#include <assert.h> +#include <errno.h> + +#include <LongBow/unit-test.h> + +#include <LongBow/Reporting/longBowReport_Testing.h> + +#include <LongBow/longBow_Config.h> +#include <LongBow/longBow_TestCaseClipBoard.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_String.h> + + +/** + * @struct longbow_testcase + * @brief The specification of a LongBow Test Case. + * + */ +struct longbow_testcase { + /** + * The name of the test case as a C string. + */ + const char *testCaseName; + + const LongBowTestCaseMetaData *metaData; + + char *fullName; + + /** + * The fixture that is running this test case. + */ + const LongBowTestFixture *fixture; + + /** + * The function to execute the test case. + */ + LongBowTestCaseFunction *testCase; + + /** + * The runtime characteristics consisting of the expected and actual results. + */ + LongBowRuntime *runtime; +}; + + +void +longBowTestCase_ConfigHelp(void) +{ + printf("Test Case options:\n"); + printf(" --set <runnerName>/<fixtureName>/iterations=<integer> Run the named test case <integer> times.\n"); +} + +LongBowTestCase * +longBowTestCase_Create(const char *testCaseName, + const LongBowTestFixture *testFixture, + LongBowTestCaseFunction *testCase, + const LongBowTestCaseMetaData *metaData) +{ + assert(testCaseName != NULL); + + LongBowTestCase *result = longBowMemory_Allocate(sizeof(LongBowTestCase)); + if (result != NULL) { + result->testCaseName = testCaseName; + int status = asprintf(&result->fullName, "%s/%s", longBowTestFixture_GetFullName(testFixture), testCaseName); + assert(status != -1); + result->fixture = testFixture; + result->testCase = testCase; + result->runtime = longBowRuntime_Create(&metaData->expectedResult, + longBowTestRunner_GetConfiguration(longBowTestFixture_GetRunner(testFixture))); + result->metaData = metaData; + } + return result; +} + +const char * +longBowTestCase_GetFullName(const LongBowTestCase *testCase) +{ + assert(testCase != NULL); + return testCase->fullName; +} + +void +longBowTestCase_Destroy(LongBowTestCase **testCaseP) +{ + LongBowTestCase *testCase = *testCaseP; + + longBowRuntime_Destroy(&(testCase->runtime)); + + longBowMemory_Deallocate((void **) testCaseP); +} + +/* + * Given the exit status of a test as returned by wait(2), return the corresponding {@link LongBowStatus}. + * + * @param [in] waitStatus + * @return LongBowStatus + */ +static LongBowStatus +_longBowTestCase_ParseWaitStatus(int waitStatus) +{ + LongBowStatus result = LongBowStatus_WARNED; + if (WIFSIGNALED(waitStatus)) { + int exitSignal = WTERMSIG(waitStatus); + if (exitSignal == SIGABRT) { + result = LONGBOW_STATUS_FAILED; + } else { + result = LongBowStatus_SIGNALLED + exitSignal; + } + } else if (WIFEXITED(waitStatus)) { + result = (LongBowStatus) WEXITSTATUS(waitStatus); + } else { + result = LongBowStatus_STOPPED; + } + + return result; +} + +LongBowLocation * +longBowTestCase_CreateLocation(const LongBowTestCase *testCase) +{ + LongBowLocation *result = longBowLocation_Create(testCase->metaData->fileName, testCase->fullName, testCase->metaData->lineNumber); + return result; +} + +const char * +longBowTestCase_GetName(const LongBowTestCase *testCase) +{ + return testCase->testCaseName; +} + +LongBowTestFixture * +longBowTestCase_GetFixture(const LongBowTestCase *testCase) +{ + return (LongBowTestFixture *) testCase->fixture; +} + +LongBowRuntimeResult * +longBowTestCase_GetExpectedResult(const LongBowTestCase *testCase) +{ + return longBowRuntime_GetExpectedTestCaseResult(testCase->runtime); +} + +LongBowRuntimeResult * +longBowTestCase_GetActualResult(const LongBowTestCase *testCase) +{ + return longBowRuntime_GetActualTestCaseResult(testCase->runtime); +} + +size_t +longBowTestCase_GetEventEvaluationCount(const LongBowTestCase *testCase) +{ + return longBowRuntime_GetActualEventEvaluationCount(testCase->runtime); +} + +static jmp_buf longBowTestCaseAbort; + +/* + * The process running the Test Case receives a signal. + * + * A regular, passing Test Case induces no signal and as a result does not pass through this function. + * A Test Case that fails an assertion will induce the SIGABRT signal which does pass through this function. + * Any other signal is because the Test Case either purposefully sent itself a signal, (including calling abort()), + * or it induced one through some implicit behaviour (like a SIGSEGV). + * + * In all remaining cases, encode the signal received into a return value for the + * corresponding setjmp() and invoke the longjmp(). + */ +__attribute__((noreturn)) +static void +_longBowTestCase_ReceiveSignal(int signal, siginfo_t *siginfo __attribute__((unused)), void *data __attribute__((unused))) +{ + if (signal == SIGINT) { + printf("Howdy\n"); + } + longjmp(longBowTestCaseAbort, signal); +} + +/** + * Return true or false, if LongBow should capture a signal, or not. + * + * LongBow captures signals in order to report on the success or failure of a test. + * Some signals do not indicate that a test failed, + * only that the environment changed, + * or some other event that is unrelated to success or failure. + * Unless, of course, the test is checking for the event (this is not yet supported). + */ +static bool +_longBowTestCase_MustCaptureSignal(const int signal) +{ + switch (signal) { + case SIGTRAP: + return false; + + case SIGCHLD: + return false; + + case SIGKILL: + return false; + + case SIGSTOP: + return false; + + case SIGWINCH: + return false; + + default: + return true; + } +} + +/** + * Setup signals to point to the testCaseSignalAction handler for all signals possible. + */ +static void +_longBowTestCase_TestInitSignals(void) +{ + struct sigaction signalAction; + signalAction.sa_sigaction = _longBowTestCase_ReceiveSignal; + signalAction.sa_flags = SA_SIGINFO; + sigemptyset(&signalAction.sa_mask); + + struct sigaction oldSignals[NSIG]; + for (int i = 1; i < NSIG; i++) { + if (_longBowTestCase_MustCaptureSignal(i)) { + sigaction(i, &signalAction, &oldSignals[i]); + } + } +} + +/** + * Setup signals to their default behaviour. + */ +static void +_longBowTestCase_TestFiniSignals(void) +{ + struct sigaction signalAction; + signalAction.sa_handler = SIG_DFL; + signalAction.sa_flags = SA_SIGINFO; + sigemptyset(&signalAction.sa_mask); + + for (int i = 1; i < NSIG; i++) { + if (_longBowTestCase_MustCaptureSignal(i)) { + sigaction(i, &signalAction, NULL); + } + } +} + +/* + * Determine the status of the given LongBowTestCase. + * + * If the actual event recorded in the test case is equal to the expected event, + * then return LONGBOW_STATUS_SUCCEEDED. + * If the actual event is NULL and the expected event is not, then return LONGBOW_STATUS_FAILED. + * Otherwise, the result is the actual event. + */ +static LongBowStatus +_longBowTestCase_ExpectedVsActualEvent(const LongBowTestCase *testCase) +{ + LongBowStatus result = LONGBOW_STATUS_FAILED; + LongBowEventType *expectedEvent = longBowRuntimeResult_GetEvent(longBowTestCase_GetExpectedResult(testCase)); + LongBowEventType *actualEvent = longBowRuntimeResult_GetEvent(longBowTestCase_GetActualResult(testCase)); + + if (longBowEventType_Equals(expectedEvent, actualEvent)) { + result = LONGBOW_STATUS_SUCCEEDED; + } else if (actualEvent == NULL && expectedEvent != NULL) { + LongBowString *messageString = longBowString_CreateFormat("failed to induce an expected %s event.", + longBowEventType_GetName(expectedEvent)); + + LongBowLocation *location = longBowTestCase_CreateLocation(testCase); + LongBowEvent *event = longBowEvent_Create(expectedEvent, location, "", longBowString_ToString(messageString), NULL); + + longBowReportRuntime_Event(event); + longBowEvent_Destroy(&event); + longBowString_Destroy(&messageString); + + result = LONGBOW_STATUS_FAILED; + } else { + result = longBowEventType_GetStatus(actualEvent); + } + + return result; +} + +/* + * Invoke the test case function and see if it succeeds. + * + * The technique here is to assume the test case will succeed, + * setup a longjmp back to this function + * and then setup signal handling and invoke the test case. + * This essentially wraps the test function an catches and handles the abort() + * (SIGABRT) that results from the LongBow assertion or trap. + * + * If the test case simply returns (ie. the longjmp was never executed), + * then it was successful. + * Otherwise, the longjmp contains a code indicating the status captured by + * the signal handler that was invoked when the test code executed the abort() function. + * Extract relevant information from the current runtime context + * (which is always present whether in a unit test case or not) + * + * Note that it's actually not necessary for the test code to execute an abort(), + * it could invoke the longjmp() directly. + * Something that might be advantagous in the future. + */ +static LongBowStatus +_longBowTestCase_Execute(LongBowTestCase *testCase) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + if (longBowConfig_IsTrace(longBowTestCase_GetConfiguration(testCase))) { + longBowReportTesting_Trace(" %s/%s/%s", + longBowTestRunner_GetName(longBowTestFixture_GetRunner(longBowTestCase_GetFixture(testCase))), + longBowTestFixture_GetName(longBowTestCase_GetFixture(testCase)), + longBowTestCase_GetName(testCase)); + } + + int receivedSignal = setjmp(longBowTestCaseAbort); + if (receivedSignal == 0) { + _longBowTestCase_TestInitSignals(); + + errno = 0; + + LongBowClipBoard *testClipBoard = longBowTestFixture_GetClipBoard(longBowTestCase_GetFixture(testCase)); + + (testCase->testCase)(longBowTestFixture_GetRunner(longBowTestCase_GetFixture(testCase)), + longBowTestCase_GetFixture(testCase), + testCase, + testClipBoard, + longBowTestCaseAbort); + } else { + // We get here as the result of an extraordinary abort from the testCase invoked just above. + // Sort out the meaning of the received signal here. + // + // If an SIGABRT is received, we expect that the Global Runtime contains a valid LongBowEventType. + // If not, then an old-timey <assert.h> assert() was used and the programmer should be warned, + // or the system under test actually uses SIGABRT and the programmer is warned that this + // incompatible with LongBow. + + LongBowEventType *event = NULL; + if (receivedSignal == SIGABRT) { + if (longBowRuntime_GetActualEventType(longBowRuntime_GetCurrentRuntime()) == NULL) { + char *testCaseString = longBowTestCase_ToString(testCase); + longBowReportRuntime_Warning("Warning: %s commingling LongBow with assert(3) or with SIGABRT will not work.\n", testCaseString); + free(testCaseString); + } + + event = longBowRuntime_GetActualEventType(longBowRuntime_GetCurrentRuntime()); + } else if (receivedSignal == SIGTERM) { + char *testCaseString = longBowTestCase_ToString(testCase); + longBowReportRuntime_Warning("\nWarning: %s premature termination.\n", testCaseString); + free(testCaseString); + event = longBowEventType_GetEventTypeForSignal(receivedSignal); + } else if (receivedSignal == SIGINT) { + char *testCaseString = longBowTestCase_ToString(testCase); + longBowReportRuntime_Warning("\nWarning: %s interrupted.\n", testCaseString); + free(testCaseString); + event = longBowEventType_GetEventTypeForSignal(receivedSignal); + } else { + event = longBowEventType_GetEventTypeForSignal(receivedSignal); + } + + longBowRuntimeResult_SetEvent(longBowTestCase_GetActualResult(testCase), event); + } + + result = _longBowTestCase_ExpectedVsActualEvent(testCase); + + if (result == LONGBOW_STATUS_SUCCEEDED) { + if (longBowTestCase_GetEventEvaluationCount(testCase) == 0) { + result = LongBowStatus_IMPOTENT; + } + } else if (longBowStatus_IsFailed(result)) { + ; + } + + memset(&longBowTestCaseAbort, 0, sizeof(longBowTestCaseAbort)); + + _longBowTestCase_TestFiniSignals(); + + return result; +} + +static LongBowStatus +_longBowTestCase_ExecuteOnce(LongBowTestCase *testCase) +{ + LongBowStatus result = LONGBOW_STATUS_FAILED; + + LongBowTestFixture *fixture = longBowTestCase_GetFixture(testCase); + + LongBowStatus setupStatus = longBowTestFixture_Setup(fixture, testCase); + + if (longBowStatus_IsSuccessful(setupStatus) == true) { + LongBowStatus testCaseStatus = _longBowTestCase_Execute(testCase); + + LongBowStatus tearDownStatus = longBowTestFixture_TearDown(fixture, testCase); + + // Ensure that things only go from "bad" to "worse." If a test case is indicating a failure + // and yet the tear-down is also indicating something NOT successful (like a warning), don't + // demote the status from LONGBOW_STATUS_FAILED to LONGBOW_STATUS_TEARDOWN_WARNING. + // This is messy. Perhaps a better approach would be to structure status as an ordered arrangement of status. + + result = testCaseStatus; + + if (testCaseStatus == LONGBOW_STATUS_SUCCEEDED) { + if (tearDownStatus != LONGBOW_STATUS_SUCCEEDED) { + result = tearDownStatus; + } + } + } + + return result; +} + +static LongBowStatus +_longBowTestCase_Iterate(LongBowTestCase *testCase) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + LongBowConfig *config = longBowTestCase_GetConfiguration(testCase); + + uint32_t iterations = longBowConfig_GetUint32(config, 1, "%s/iterations", longBowTestCase_GetFullName(testCase)); + + for (uint32_t i = 0; i < iterations && longBowStatus_IsSuccessful(result); i++) { + LongBowRuntime *previousRuntime = longBowRuntime_SetCurrentRuntime(testCase->runtime); + result = _longBowTestCase_ExecuteOnce(testCase); + longBowRuntime_SetCurrentRuntime(previousRuntime); + } + + return result; +} + +/* + * Run a LongBowTestCase in a forked process. + * + * @param testCase The LongBowTestCase to run. + * @return 0 + */ +static int +_longBowTestCase_RunForked(LongBowTestCase *testCase) +{ + struct timeval startTime; + gettimeofday(&startTime, NULL); + + pid_t pid = fork(); + if (pid == 0) { + exit(_longBowTestCase_Iterate(testCase)); + } else { + // Rummage around in various things to obtain the post-mortem + // results of the test that was run in a separate process. + int waitStatus; + struct rusage rusage; +#ifndef _ANDROID_ + wait3(&waitStatus, 0, &rusage); +#else + wait4(-1, &waitStatus, 0, &rusage); +#endif + struct timeval endTime; + gettimeofday(&endTime, NULL); + + struct timeval elapsedTime; + timersub(&endTime, &startTime, &elapsedTime); + + longBowRuntimeResult_SetElapsedTime(longBowTestCase_GetActualResult(testCase), &elapsedTime); + longBowRuntimeResult_SetRUsage(longBowTestCase_GetActualResult(testCase), &rusage); + longBowRuntimeResult_SetStatus(longBowTestCase_GetActualResult(testCase), _longBowTestCase_ParseWaitStatus(waitStatus)); + } + return 0; +} + +/* + * Run a LongBowTestCase in this address space (ie. not a forked process). + * + * @param testCase The LongBowTestCase to run. + * @return 0 + */ +static int +_longBowTestCase_RunNonForked(LongBowTestCase *testCase) +{ + struct timeval startTime; + gettimeofday(&startTime, NULL); + + LongBowStatus status = _longBowTestCase_Iterate(testCase); + + struct timeval endTime; + gettimeofday(&endTime, NULL); + + struct timeval elapsedTime; + timersub(&endTime, &startTime, &elapsedTime); + + longBowRuntimeResult_SetElapsedTime(longBowTestCase_GetActualResult(testCase), &elapsedTime); + longBowRuntimeResult_SetStatus(longBowTestCase_GetActualResult(testCase), status); + + return 0; +} + +LongBowStatus +longBowTestCase_GetExpectedStatus(const LongBowTestCase *testCase) +{ + return longBowRuntimeResult_GetStatus(longBowTestCase_GetExpectedResult(testCase)); +} + +LongBowTestCase * +longBowTestCase_Run(const char *testCaseName, + const LongBowTestFixture *fixture, + LongBowTestCaseFunction *testCase, + const LongBowTestCaseMetaData *testCaseMetaData) +{ + LongBowTestCase *result = longBowTestCase_Create(testCaseName, fixture, testCase, testCaseMetaData); + + if (result != NULL) { + if (longBowConfig_IsRunForked(longBowTestRunner_GetConfiguration(longBowTestFixture_GetRunner(fixture)))) { + _longBowTestCase_RunForked(result); + } else { + _longBowTestCase_RunNonForked(result); + } + + longBowTestFixture_AddTestCase(fixture, result); + longBowReportTesting_DisplayTestCaseResult(result); + } + return result; +} + +LongBowStatus +longBowTestCase_GetStatus(const LongBowTestCase *testCase) +{ + return longBowRuntimeResult_GetStatus(longBowTestCase_GetActualResult(testCase)); +} + +static LongBowClipBoard * +_longBowTestCase_GetClipBoard(const LongBowTestCase *testCase) +{ + return longBowTestFixture_GetClipBoard(testCase->fixture); +} + +void * +longBowTestCase_SetClipBoardData(const LongBowTestCase *testCase, void *data) +{ + return longBowClipBoard_Set(_longBowTestCase_GetClipBoard(testCase), "testCase", data); +} + +void * +longBowTestCase_GetClipBoardData(const LongBowTestCase *testCase) +{ + return longBowClipBoard_Get(_longBowTestCase_GetClipBoard(testCase), "testCase"); +} + +void * +longBowTestCase_Set(const LongBowTestCase *testCase, const char *name, void *value) +{ + return longBowClipBoard_Set(_longBowTestCase_GetClipBoard(testCase), name, value); +} + +void * +longBowTestCase_Get(const LongBowTestCase *testCase, const char *name) +{ + return longBowClipBoard_Get(_longBowTestCase_GetClipBoard(testCase), name); +} + +char * +longBowClipBoard_GetCString(const LongBowTestCase *testCase, const char *name) +{ + return longBowClipBoard_GetAsCString(_longBowTestCase_GetClipBoard(testCase), name); +} + +void * +longBowTestCase_SetInt(const LongBowTestCase *testCase, const char *name, int value) +{ + return longBowClipBoard_SetInt(_longBowTestCase_GetClipBoard(testCase), name, (uint64_t) value); +} + +void * +longBowTestCase_SetCString(const LongBowTestCase *testCase, const char *name, char *value) +{ + return longBowClipBoard_SetCString(_longBowTestCase_GetClipBoard(testCase), name, value); +} + +int +longBowTestCase_GetInt(const LongBowTestCase *testCase, const char *name) +{ + return (intptr_t) longBowTestCase_Get(testCase, name); +} + +LongBowConfig * +longBowTestCase_GetConfiguration(const LongBowTestCase *testCase) +{ + return longBowTestRunner_GetConfiguration(longBowTestFixture_GetRunner(longBowTestCase_GetFixture(testCase))); +} + +char * +longBowTestCase_ToString(const LongBowTestCase *testCase) +{ + return strdup(longBowTestCase_GetFullName(testCase)); +} + +bool +longBowTestCase_IsSuccessful(const LongBowTestCase *testCase) +{ + return longBowStatus_IsSuccessful(longBowTestCase_GetStatus(testCase)); +} + +bool +longBowTestCase_IsFailed(const LongBowTestCase *testCase) +{ + return longBowStatus_IsFailed(longBowTestCase_GetStatus(testCase)); +} + +bool +longBowTestCase_IsWarning(const LongBowTestCase *testCase) +{ + return longBowStatus_IsWarning(longBowTestCase_GetStatus(testCase)); +} + +bool +longBowTestCase_IsIncomplete(const LongBowTestCase *testCase) +{ + return longBowStatus_IsIncomplete(longBowTestCase_GetStatus(testCase)); +} diff --git a/longbow/src/LongBow/longBow_TestCase.h b/longbow/src/LongBow/longBow_TestCase.h new file mode 100755 index 00000000..670adc84 --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCase.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_TestCase.h + * @ingroup internals + * @brief The interface and supporting functionality of a LongBow Test Case. + * + */ +#ifndef LONGBOWTESTCASE_H_ +#define LONGBOWTESTCASE_H_ + +#include <setjmp.h> + +struct longbow_testcase; +typedef struct longbow_testcase LongBowTestCase; + +#include <LongBow/longBow_TestCaseClipBoard.h> +#include <LongBow/longBow_ClipBoard.h> + +#include <LongBow/longBow_TestRunner.h> +#include <LongBow/longBow_TestFixture.h> +#include <LongBow/longBow_RuntimeResult.h> +#include <LongBow/longBow_TestCaseMetaData.h> + +typedef void (LongBowTestCaseFunction)(const LongBowTestRunner *, const LongBowTestFixture *, const LongBowTestCase *, const LongBowClipBoard *c, jmp_buf); + +/** + * Get the name of the given LongBowTestCase. + * + * @param [in] testCase A pointer to a `LongBowTestCase` instance. + * + * @return A pointer to an immutable C string. + * + * Example: + * @code + * const char *name = longBowTestCase_GetName(testCase); + * @endcode + */ +const char *longBowTestCase_GetName(const LongBowTestCase *testCase); + +/** + * Get the corresponding LongBowTestFixture for the given LongBowTestCase. + * + * @param [in] testCase A pointer to a LongBowTestCase instance. + * + * @return A pointer to the corresponding LongBowTestFixture. + * + * Example: + * @code + * <#example#> + * @endcode + */ +LongBowTestFixture *longBowTestCase_GetFixture(const LongBowTestCase *testCase); + +/** + * Create a LongBowTestCase instance. + * + * @param [in] testCaseName A nul-terminated C string of the test case name. + * @param [in] fixture A pointer to a valid LongBowTestFixture instance. + * @param [in] testCase A pointer to a test case function. + * @param [in] metaData A pointer to a LongBowTestCaseMetaData instance. + * @return A pointer to an allocated LongBowTestCase instance, that must be destroyed via longBowTestCase_Destroy(). + */ +LongBowTestCase *longBowTestCase_Create(const char *testCaseName, + const LongBowTestFixture *fixture, + LongBowTestCaseFunction *testCase, + const LongBowTestCaseMetaData *metaData); + +/** + * Print command line and configuration help applicable to a Long Bow Test Case. + * + */ +void longBowTestCase_ConfigHelp(void); + +/** + * @param [in,out] testCasePtr A pointer to a pointer to a LongBowTestCase instance. + */ +void longBowTestCase_Destroy(LongBowTestCase **testCasePtr); + +/** + * Get the fully qualified name of the given `LongBowTestCase`. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * + * @return A constant nul-terminated, C string. + */ +const char *longBowTestCase_GetFullName(const LongBowTestCase *testCase); + +/** + * + * @param [in] testCaseName A nul-terminated C string of the test case name. + * @param [in] fixture A pointer to a valid LongBowTestFixture instance. + * @param [in] testCase A pointer to a test case function. + * @param [in] testCaseMetaData A pointer to a LongBowTestCaseMetaData instance. + * @return return + */ +LongBowTestCase *longBowTestCase_Run(const char *testCaseName, + const LongBowTestFixture *fixture, + LongBowTestCaseFunction *testCase, + const LongBowTestCaseMetaData *testCaseMetaData); + +/** + * Get the string representation of the given LongBowTestCase. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return An allocated, nul-terminated C string that must be deallocated via free(3) + */ +char *longBowTestCase_ToString(const LongBowTestCase *testCase); + +/** + * Return the LongBowStatus of the given test case. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return The LongBowStatus of the given test case. + */ +LongBowStatus longBowTestCase_GetStatus(const LongBowTestCase *testCase); + +/** + * Get the LongBowStatus value for the expected status of the given LongBowTestCase. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return A LongBowStatus value for the expected status of the given LongBowTestCase. + */ +LongBowStatus longBowTestCase_GetExpectedStatus(const LongBowTestCase *testCase); + +/** + * Get a pointer to the expected LongBowRuntimeResult value for the given LongBowTestCase. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return A LongBowStatus value for the expected status of the given LongBowTestCase. + */ +LongBowRuntimeResult *longBowTestCase_GetExpectedResult(const LongBowTestCase *testCase); + +/** + * Get the count of event evaluations performed during the execution of a LongBow Test Case. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * + * @return The count of event evaluations performed during the execution of a LongBow Test Case. + */ +size_t longBowTestCase_GetEventEvaluationCount(const LongBowTestCase *testCase); + +/** + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return A LongBowRuntimeResult pointer. + */ +LongBowRuntimeResult *longBowTestCase_GetActualResult(const LongBowTestCase *testCase); + +/** + * Return <code>true</code> if the given test case was successful. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return <code>true</code> if the given test case succeeded. + */ +bool longBowTestCase_IsSuccessful(const LongBowTestCase *testCase); + +/** + * Return <code>true</code> if the given test case issued a warning. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return <code>true</code> if the given test case issued a warning. + */ +bool longBowTestCase_IsWarning(const LongBowTestCase *testCase); + +/** + * Return <code>true</code> if the given test case was incomplete. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return <code>true</code> if the given test case was incomplete. + */ +bool longBowTestCase_IsIncomplete(const LongBowTestCase *testCase); + +/** + * Return <code>true</code> if the given test case failed. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return <code>true</code> if the given test case failed. + */ +bool longBowTestCase_IsFailed(const LongBowTestCase *testCase); + +///** +// * Place a value on the Test Case "clipboard" +// * +// * Every Test Case has an associated "clipboard" which is shared between the Test Fixture Setup, +// * Test Case, and Test Fixture Tear Down. +// * +// * @param [in] testCase A pointer to a valid LongBowTestCase instance. +// * @param [in] data The value to share on the clipboard. +// * @return The previous value on the "clipboard", or NULL if no previous value was set. +// */ +//void *longBowTestCase_SetClipBoard(const LongBowTestCase *testCase, const char *name, void *data); + +///** +// * Get the named clipboard data from the given `LongBowTestCase`. +// * +// * @param [in] testCase A pointer to a valid LongBowTestCase instance. +// * @param [in] name A nul-terminate, C string of the name of the clipboard entry. +// */ +//void *longBowTestCase_GetClipBoard(const LongBowTestCase *testCase, const char *name); + +/** + * Get the LongBowConfig instance for the given LongBowTestCase instance. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * + * @return non-NULL The LongBowConfig instance for the given LongBowTestCase instance. + * @return NULL No LongBowConfig instance for the given LongBowTestCase. + */ +LongBowConfig *longBowTestCase_GetConfiguration(const LongBowTestCase *testCase); + +/** + * Get the clipboard data from the given `LongBowTestCase`. + * + * NOTE: Use `longBowTestCase_GetClipBoard`. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + */ +void *longBowTestCase_GetClipBoardData(const LongBowTestCase *testCase); + +void *longBowTestCase_SetClipBoardData(const LongBowTestCase *testCase, void *data); + +void *longBowTestCase_Set(const LongBowTestCase *testCase, const char *name, void *value); + +void *longBowTestCase_Get(const LongBowTestCase *testCase, const char *name); + +char *longBowClipBoard_GetCString(const LongBowTestCase *testCase, const char *name); + +void *longBowTestCase_SetInt(const LongBowTestCase *testCase, const char *name, int value); + +void *longBowTestCase_SetCString(const LongBowTestCase *testCase, const char *name, char *value); + +int longBowTestCase_GetInt(const LongBowTestCase *testCase, const char *name); +#endif // LONGBOWTESTCASE_H_ diff --git a/longbow/src/LongBow/longBow_TestCaseClipBoard.c b/longbow/src/LongBow/longBow_TestCaseClipBoard.c new file mode 100755 index 00000000..acdf4c3d --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCaseClipBoard.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdlib.h> + +#include <LongBow/longBow_TestCaseClipBoard.h> +#include <LongBow/private/longBow_Memory.h> + +struct longbow_testcase_clipboard { + /** + * A pointer to arbitrary data shared between the setup, test case, and teardown. + */ + void *shared; +}; + +LongBowTestCaseClipBoard * +longBowTestCaseClipBoard_Create(void *shared) +{ + LongBowTestCaseClipBoard *result = longBowMemory_Allocate(sizeof(LongBowTestCaseClipBoard)); + longBowTestCaseClipBoard_Set(result, shared); + return result; +} + +void +longBowTestCaseClipBoard_Destroy(LongBowTestCaseClipBoard **clipBoardPtr) +{ + longBowMemory_Deallocate((void **) clipBoardPtr); +} + +void * +longBowTestCaseClipBoard_Get(const LongBowTestCaseClipBoard *clipBoard) +{ + return clipBoard->shared; +} + +LongBowTestCaseClipBoard * +longBowTestCaseClipBoard_Set(LongBowTestCaseClipBoard *clipBoard, void *shared) +{ + void *previousValue = clipBoard->shared; + clipBoard->shared = shared; + return previousValue; +} diff --git a/longbow/src/LongBow/longBow_TestCaseClipBoard.h b/longbow/src/LongBow/longBow_TestCaseClipBoard.h new file mode 100755 index 00000000..4b8da1aa --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCaseClipBoard.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_TestCaseClipboard.h + * @ingroup testing + * @brief LongBow Clipboard shared between the setup, test case, and teardown. + * + */ +#ifndef LongBow_longBowTestCaseClipBoard_h +#define LongBow_longBowTestCaseClipBoard_h + +struct longbow_testcase_clipboard; + +/** + * @typedef LongBowTestCaseClipBoard + */ +typedef struct longbow_testcase_clipboard LongBowTestCaseClipBoard; + +/** + * Create a `LongBowTestCaseClipBoard` containing the shared data pointer. + * + * @param [in] shared A pointer to a value that is shared between the setup, test-case, and tear-down functions. + * @return A pointer to a valid LongBowTestCaseClipBoard instance. + * + * @see longBowTestCaseClipBoard_Destroy + */ +LongBowTestCaseClipBoard *longBowTestCaseClipBoard_Create(void *shared); + +/** + * + * @param [in,out] clipBoardPtr A pointer to a pointer to a LongBowTestCaseClipBoard instance. + */ +void longBowTestCaseClipBoard_Destroy(LongBowTestCaseClipBoard **clipBoardPtr); + +/** + * + * @param [in] clipBoard A pointer to a valid LongBowTestCaseClipBoard instance. + * @param [in] shared A pointer to a value that is shared between the setup, test-case, and tear-down functions. + * @return The previous value of the "clipboard", or NULL if there was no previous value. + */ +LongBowTestCaseClipBoard *longBowTestCaseClipBoard_Set(LongBowTestCaseClipBoard *clipBoard, void *shared); + +/** + * + * @param [in] clipBoard A pointer to a valid LongBowTestCaseClipBoard instance. + * @return The value currently stored on the clipboard. + */ +void *longBowTestCaseClipBoard_Get(const LongBowTestCaseClipBoard *clipBoard); +#endif diff --git a/longbow/src/LongBow/longBow_TestCaseMetaData.c b/longbow/src/LongBow/longBow_TestCaseMetaData.c new file mode 100755 index 00000000..1596d60c --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCaseMetaData.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <LongBow/longBow_TestCaseMetaData.h> diff --git a/longbow/src/LongBow/longBow_TestCaseMetaData.h b/longbow/src/LongBow/longBow_TestCaseMetaData.h new file mode 100755 index 00000000..589b90ec --- /dev/null +++ b/longbow/src/LongBow/longBow_TestCaseMetaData.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#ifndef longBow_TestCaseMetaData_h +#define longBow_TestCaseMetaData_h + +#include <stdint.h> + +#include <LongBow/longBow_RuntimeResult.h> + +struct LongBowTestCaseMetaData { + const char *fileName; + const char *functionName; + uint32_t lineNumber; + LongBowRuntimeResult expectedResult; +}; + +typedef struct LongBowTestCaseMetaData LongBowTestCaseMetaData; + +#endif /* longBow_TestCaseMetaData_h */ diff --git a/longbow/src/LongBow/longBow_TestFixture.c b/longbow/src/LongBow/longBow_TestFixture.c new file mode 100644 index 00000000..d4efc86f --- /dev/null +++ b/longbow/src/LongBow/longBow_TestFixture.c @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> +#include <stdio.h> + +#include <LongBow/private/longBow_ArrayList.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_String.h> + +#include <LongBow/longBow_TestFixture.h> +#include <LongBow/longBow_TestFixtureConfig.h> +#include <LongBow/longBow_TestCase.h> +#include <LongBow/longBow_RuntimeResult.h> + +#include <LongBow/unit-test.h> + +/** + * @struct longbow_fixture + * @brief The LongBow Test Fixture. + * + * This structure is created and initialized by the LongBow Test Runner. + * When the Test Fixture represented by this structure is executed, + * this structure is updated with the results of each LongBow Test Case that belongs to this Fixture. + */ +struct longbow_fixture { + /** + * The name of this test fixture. + */ + const char *name; + + /** + * The fully qualified name of this test fixture. + */ + char *fullName; + + /** + * + */ + LongBowTestFixtureConfig *config; + + /** + * The Test Runner of this test fixture. + */ + LongBowTestRunner *runner; + + /** + * The `LongBowTestFixtureSummary` of this test fixture. + */ + LongBowTestFixtureSummary summary; + + /** + * A list of `LongBowTestCase` structures, one for each executed test case. + */ + LongBowArrayList *testCases; + + /** + * The function to call to setup the Test Fixture. + * + * This function is called before each Test Case is run. + * @param testCase The LongBow Test Case that is being set-up. + */ + LongBowTestFixtureSetupFunction *setUp; + + /** + * The function to call to execute the Test Fixture. + * + * @param testFixture A pointer to this `struct longbow_fixture` structure. + */ + LongBowTestFixtureFunction *fixture; + + /** + * The function to call to tear-down the Test Fixture. + * + * This function is called after each Test Case is run. + * @param testCase The LongBow Test Case that is being torn-down. + */ + LongBowTestFixtureTearDownFunction *tearDown; +}; + +static void +_longBowTestFixture_TestSucceeded(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalSucceeded++; +} + +static void +_longBowTestFixture_TestFailed(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalFailed++; +} + +static void +_longBowTestFixture_TestLeakedResources(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalFailed++; +} + +static void +_longBowTestFixture_TestSkipped(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalSkipped++; +} + +static void +_longBowTestFixture_TestSkipTests(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalSkipped++; +} + +static void +_longBowTestFixture_TestWarned(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalWarned++; +} + +static void +_longBowTestFixture_TestSetupFailed(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalSetupFailed++; +} + +static void +_longBowTestFixture_TestSignalled(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalSignalled++; +} + +static void +_longBowTestFixture_TestStopped(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalStopped++; +} + +static void +_longBowTestFixture_TestUnimplemented(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalUnimplemented++; +} + +static void +_longBowTestFixture_TestImpotent(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalUnimplemented++; +} + +static void +_longBowTestFixture_Untested(LongBowTestFixtureSummary *summary __attribute__((unused))) +{ +} + +static void +_longBowTestFixture_TearDownFailed(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalTearDownFailed++; +} + +static void +_longBowTestFixture_TearDownWarned(LongBowTestFixtureSummary *summary) +{ + summary->totalTested++; + summary->totalTearDownWarned++; +} + +void +longBowTestFixture_ConfigHelp(void) +{ + printf("Test Fixture options:\n"); + printf(" --set <runnerName>/<fixtureName>/iterations=<integer> Run the named test fixture <integer> times.\n"); + printf(" --set <runnerName>/<fixtureName>/enable=(true|false) Enable or disable execution of the named test fixture.\n"); +} + +bool +longBowTestFixture_Config(LongBowConfig *config, const char *parameter) +{ + bool result = false; + return result; +} + +LongBowTestFixture * +longBowTestFixture_Create(const LongBowTestRunner *testRunner, + const char *fixtureName, + LongBowTestFixtureSetupFunction *setup, + LongBowTestFixtureFunction *fixtureFunction, + LongBowTestFixtureTearDownFunction *tearDown) +{ + LongBowTestFixture *fixture = longBowMemory_Allocate(sizeof(LongBowTestFixture)); + if (fixture != NULL) { + fixture->runner = (LongBowTestRunner *) testRunner; + fixture->name = fixtureName; + + int status = asprintf(&fixture->fullName, "%s/%s", longBowTestRunner_GetName(testRunner), fixtureName); + if (status == -1) { + return NULL; + } + + fixture->testCases = longBowArrayList_Create((void (*)(void **))longBowTestCase_Destroy); + fixture->setUp = setup; + fixture->fixture = fixtureFunction; + fixture->tearDown = tearDown; + } + + return fixture; +} + +void +longBowTestFixture_Destroy(LongBowTestFixture **fixturePtr) +{ + LongBowTestFixture *fixture = *fixturePtr; + + free(fixture->fullName); + + longBowArrayList_Destroy(&fixture->testCases); + longBowMemory_Deallocate((void **) fixturePtr); +} + +const char * +longBowTestFixture_GetFullName(const LongBowTestFixture *testFixture) +{ + return testFixture->fullName; +} + +void +longBowTestFixture_UpdateSummary(LongBowTestCase *longBowTestCase) +{ + switch (longBowRuntimeResult_GetStatus(longBowTestCase_GetActualResult(longBowTestCase))) { + case LONGBOW_STATUS_SUCCEEDED: + _longBowTestFixture_TestSucceeded(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_SKIPPED: + _longBowTestFixture_TestSkipped(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_WARNED: + _longBowTestFixture_TestWarned(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_SETUP_FAILED: + _longBowTestFixture_TestSetupFailed(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_SETUP_SKIPTESTS: + _longBowTestFixture_TestSkipTests(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_TEARDOWN_FAILED: + _longBowTestFixture_TearDownFailed(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_TEARDOWN_WARNED: + _longBowTestFixture_TearDownWarned(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_FAILED: + _longBowTestFixture_TestFailed(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_STOPPED: + _longBowTestFixture_TestStopped(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_UNIMPLEMENTED: + _longBowTestFixture_TestUnimplemented(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_IMPOTENT: + _longBowTestFixture_TestImpotent(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LongBowStatus_UNTESTED: + _longBowTestFixture_Untested(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + case LONGBOW_STATUS_MEMORYLEAK: + _longBowTestFixture_TestLeakedResources(&longBowTestCase_GetFixture(longBowTestCase)->summary); + break; + + default: + if (longBowTestCase_GetActualResult(longBowTestCase)->status >= LongBowStatus_SIGNALLED) { + _longBowTestFixture_TestSignalled(&longBowTestCase_GetFixture(longBowTestCase)->summary); + } else { + printf("longBowTestFixture_UpdateSummary: unhandled status %d\n", + longBowTestCase_GetActualResult(longBowTestCase)->status); + } + } +} + +void +longBowTestFixture_AddTestCase(const LongBowTestFixture *fixture, LongBowTestCase *longBowTestCase) +{ + longBowTestFixture_UpdateSummary(longBowTestCase); + + longBowArrayList_Add(fixture->testCases, longBowTestCase); +} + +LongBowTestCase * +longBowTestFixture_GetTestCase(const LongBowTestFixture *fixture, size_t index) +{ + LongBowTestCase *testCase = longBowArrayList_Get(fixture->testCases, index); + + return testCase; +} + +const char * +longBowTestFixture_GetName(const LongBowTestFixture *fixture) +{ + return fixture->name; +} + +const LongBowTestFixtureSummary * +longBowTestFixture_GetSummary(const LongBowTestFixture *fixture) +{ + return &(fixture->summary); +} + +size_t +longBowTestFixture_GetTestCaseCount(const LongBowTestFixture *fixture) +{ + return longBowArrayList_Length(fixture->testCases); +} + +LongBowStatus +longBowTestFixture_Setup(LongBowTestFixture *fixture, LongBowTestCase *testCase) +{ + if (longBowConfig_IsTrace(longBowTestRunner_GetConfiguration(longBowTestFixture_GetRunner(fixture)))) { + longBowReportTesting_Trace(" %s/%s: setup", + longBowTestRunner_GetName(longBowTestFixture_GetRunner(fixture)), + longBowTestFixture_GetName(fixture)); + } + LongBowClipBoard *testClipBoard = longBowTestFixture_GetClipBoard(fixture); + LongBowStatus result = (longBowTestCase_GetFixture(testCase)->setUp)(longBowTestFixture_GetRunner(fixture), fixture, testCase, testClipBoard); + return result; +} + +LongBowStatus +longBowTestFixture_TearDown(LongBowTestFixture *fixture, LongBowTestCase *testCase) +{ + if (longBowConfig_IsTrace(longBowTestRunner_GetConfiguration(longBowTestFixture_GetRunner(fixture)))) { + longBowReportTesting_Trace(" %s/%s: tearDown", + longBowTestRunner_GetName(longBowTestFixture_GetRunner(fixture)), + longBowTestFixture_GetName(fixture)); + } + LongBowClipBoard *testClipBoard = longBowTestFixture_GetClipBoard(fixture); + LongBowStatus result = (longBowTestCase_GetFixture(testCase)->tearDown)(longBowTestFixture_GetRunner(fixture), fixture, testCase, testClipBoard); + return result; +} + +LongBowStatus +longBowTestFixture_GetStatus(const LongBowTestFixture *fixture) +{ + size_t nTestCases = longBowTestFixture_GetTestCaseCount(fixture); + + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + // Just return the status of the first non-successful test case. + for (size_t i = 0; i < nTestCases; i++) { + LongBowTestCase *testCase = longBowTestFixture_GetTestCase(fixture, i); + if (!longBowTestCase_IsSuccessful(testCase)) { + result = longBowTestCase_GetStatus(testCase); + break; + } + } + return result; +} + +bool +longBowTestFixture_IsSuccessful(const LongBowTestFixture *testFixture) +{ + return longBowStatus_IsSuccessful(longBowTestFixture_GetStatus(testFixture)); +} + +char * +longBowTestFixture_ToString(const LongBowTestFixture *fixture) +{ + char *runnerString = longBowTestRunner_ToString(longBowTestFixture_GetRunner(fixture)); + + char *string; + if (asprintf(&string, "%s/%s", runnerString, longBowTestFixture_GetName(fixture)) == -1) { + return NULL; + } + + free(runnerString); + + return string; +} + +LongBowTestFixture * +longBowTestFixture_Run(const LongBowTestRunner *testRunner, + const char *fixtureName, + const LongBowTestFixtureConfig *config, + LongBowTestFixtureSetupFunction *setup, + LongBowTestFixtureFunction *fixtureRun, + LongBowTestFixtureTearDownFunction *tearDown) +{ + LongBowTestFixture *testFixture = longBowTestFixture_Create(testRunner, fixtureName, setup, fixtureRun, tearDown); + + LongBowConfig *configuration = longBowTestRunner_GetConfiguration(testRunner); + + bool enabled = longBowConfig_GetBoolean(configuration, config->enabled, "%s/enabled", longBowTestFixture_GetFullName(testFixture)); + unsigned long iterations = longBowConfig_GetUint32(configuration, 1, "%s/iterations", longBowTestFixture_GetFullName(testFixture)); + + if (enabled) { + for (unsigned long i = 0; i < iterations; i++) { + (*testFixture->fixture)(testRunner, testFixture); + } + longBowTestRunner_AddFixture(testFixture->runner, testFixture); + } + + return testFixture; +} + +LongBowTestRunner * +longBowTestFixture_GetRunner(const LongBowTestFixture *fixture) +{ + return fixture->runner; +} + +LongBowClipBoard * +longBowTestFixture_GetClipBoard(const LongBowTestFixture *fixture) +{ + return longBowTestRunner_GetClipBoard(fixture->runner); +} diff --git a/longbow/src/LongBow/longBow_TestFixture.h b/longbow/src/LongBow/longBow_TestFixture.h new file mode 100644 index 00000000..926f3e03 --- /dev/null +++ b/longbow/src/LongBow/longBow_TestFixture.h @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_TestFixture.h + * @ingroup internals + * @brief Manage the execution of Test Cases. + * + * A Test Fixture manages the individual execution of Test Cases. + * + */ +#ifndef LongBowTestFixture_H_ +#define LongBowTestFixture_H_ + +#include <string.h> + +struct longbow_fixture; + +/** + * @typedef LongBowTestFixture + * @brief The LongBow Test Fixture. + * + * This structure is created and initialized by the LongBow Test Runner. + * When the Test Fixture represented by this structure is executed, + * this structure is updated with the results of each LongBow Test Case that belongs to this Fixture. + */ +typedef struct longbow_fixture LongBowTestFixture; + +#include <LongBow/longBow_ClipBoard.h> +#include <LongBow/longBow_TestRunner.h> +#include <LongBow/longBow_TestCase.h> +#include <LongBow/longBow_TestFixtureConfig.h> + +typedef void (LongBowTestFixtureFunction)(const LongBowTestRunner *testRunner, const LongBowTestFixture *testFixture); + +typedef int (LongBowTestFixtureSetupFunction)(const LongBowTestRunner *, const LongBowTestFixture *, const LongBowTestCase *, LongBowClipBoard *); + +typedef int (LongBowTestFixtureTearDownFunction)(const LongBowTestRunner *, const LongBowTestFixture *, const LongBowTestCase *, LongBowClipBoard *); + +/** + * @typedef LongBowTestFixtureSummary + * @brief The summary for a test fixture. + */ +typedef struct longbow_fixture_summary { + /** + * The total number of test cases executed. + */ + unsigned int totalTested; + /** + * The number of test cases that succeeded. + */ + unsigned int totalSucceeded; + /** + * The number of test cases that failed. + */ + unsigned int totalFailed; + /** + * The number of test cases that were skipped. + */ + unsigned int totalSkipped; + /** + * The number of test cases that issued a warning. + */ + unsigned int totalWarned; + /** + * The number of test cases that setup failed. + */ + unsigned int totalSetupFailed; + /** + * The number of test cases that failed due to an signal. + */ + unsigned int totalSignalled; + /** + * The number of test cases that failed due to a stop signal. + */ + unsigned int totalStopped; + /** + * The number of test cases in which the tear-down failed. + */ + unsigned int totalTearDownFailed; + /** + * The number of test cases in which the tear-down issued a warning. + */ + unsigned int totalTearDownWarned; + /** + * The number of test cases that existed but indicated they were unimplemented. + */ + unsigned int totalUnimplemented; +} LongBowTestFixtureSummary; + +/** + * Update the summary information from the given LongBowTestCase. + * + * @param testCase A pointer to a valid LongBowTestCase instance. + */ +void longBowTestFixture_UpdateSummary(LongBowTestCase *testCase); + +/** + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @param testCase A pointer to a valid LongBowTestCase instance. + */ +void longBowTestFixture_AddTestCase(const LongBowTestFixture *testFixture, LongBowTestCase *testCase); + +/** + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @param index The index of the instance to get. + * @return A pointer to the LongBowTestCase instance at the given index. + */ +LongBowTestCase *longBowTestFixture_GetTestCase(const LongBowTestFixture *testFixture, size_t index); + +/** + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return A pointer ot the LongBowTestRunner instance of the given LongBowTestFixture. + */ +LongBowTestRunner *longBowTestFixture_GetRunner(const LongBowTestFixture *testFixture); + +/** + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return A pointer to the C string of the name of the given LongBowTestFixture. + */ +const char *longBowTestFixture_GetName(const LongBowTestFixture *testFixture); + +/** + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return The number of LongBow Test Cases in the given LongBowTestFixture. + */ +size_t longBowTestFixture_GetTestCaseCount(const LongBowTestFixture *testFixture); + +/** + * Initialise a {@link LongBowTestFixture} structure with the given parameters. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] fixtureName The name of this Test Fixture. + * @param [in] setup A pointer to the function to call before invoking the first Test Case. + * @param [in] fixtureFunction A pointer to the function to call that will run each Test Case. + * @param [in] tearDown A pointer to the function to call after invoking the last Test Case. + * @return A pointer to an allocated LongBowTestFixture instance that must be deallocated via LongBowTestFixture_Destroy. + */ +LongBowTestFixture *longBowTestFixture_Create(const LongBowTestRunner *testRunner, + const char *fixtureName, + LongBowTestFixtureSetupFunction *setup, + LongBowTestFixtureFunction *fixtureFunction, + + LongBowTestFixtureTearDownFunction *tearDown); + +/** + * Destroy a LongBowTestFixture structure. + * + * @param fixturePtr A pointer to a LongBowTestFixture structure pointer. + */ +void longBowTestFixture_Destroy(LongBowTestFixture **fixturePtr); + +/** + * Get the fully qualified name of the given `LongBowTestFixture`. + * + * @param [in] testFixture A pointer to a valid LongBowTestCase instance. + * + * @return A constant nul-terminated, C string. + */ +const char *longBowTestFixture_GetFullName(const LongBowTestFixture *testFixture); + +void longBowTestFixture_ConfigHelp(void); + +bool longBowTestFixture_Config(LongBowConfig *config, const char *parameter); + +/** + * Execute a LongBow Test Fixture. + * + * The Test Fixture will execute Test Cases in the order they appear in the Test Fixture function. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] fixtureName The name of this Test Fixture. + * @param [in] config A pointer to a LongBowTestFixtureConfig to use when running the Test Fixture. + * @param [in] setup A pointer to the function to call before invoking the first Test Case. + * @param [in] fixtureRun A pointer to the function to call that will run each Test Case. + * @param [in] tearDown A pointer to the function to call after invoking the last Test Case. + * @return An allocated structure representing this Test Fixture. + * + * Example: + * @code + * <#example#> + * @endcode + * + * @see LONGBOW_TEST_FIXTURE + */ +LongBowTestFixture *longBowTestFixture_Run(const LongBowTestRunner *testRunner, + const char *fixtureName, + const LongBowTestFixtureConfig *config, + LongBowTestFixtureSetupFunction *setup, + LongBowTestFixtureFunction *fixtureRun, + LongBowTestFixtureTearDownFunction *tearDown); + +/** + * Get the status of the given LongBow Test Fixture. + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return The `LongBowStatus` of the given Test Fixture. + */ +LongBowStatus longBowTestFixture_GetStatus(const LongBowTestFixture *testFixture); + +/** + * Return <code>true</code> if the given test case was successful. + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return `true` if the given test case was successful. + */ +bool longBowTestFixture_IsSuccessful(const LongBowTestFixture *testFixture); + +/** + * Get a pointer to {@link LongBowTestFixtureSummary} for the given Test Fixture. + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @return A pointer to {@link LongBowTestFixtureSummary} for the given Test Fixture. + */ +const LongBowTestFixtureSummary *longBowTestFixture_GetSummary(const LongBowTestFixture *testFixture); + +/** + * Perform a test case setup. + * + * @param [in] testFixture A pointer to a valid LongBowTestFixture instance. + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return The `LongBowStatus` returned from the setup function. + */ +LongBowStatus longBowTestFixture_Setup(LongBowTestFixture *testFixture, LongBowTestCase *testCase); + +/** + * Perform a test case teardown. + * + * @param testFixture A pointer to a valid LongBowTestFixture instance. + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return The `LongBowStatus` returned from the teardown function. + */ +LongBowStatus longBowTestFixture_TearDown(LongBowTestFixture *testFixture, LongBowTestCase *testCase); + +/** + * Get the clipboard that belongs to the given Test Fixture. + * + * Every LongBow test fixure has an associated "clipboard" that is specific to that fixture and + * is shared between the test runner setup and tear down functions. + * Test Runner setup may store things on the test fixture's clipboard, + * the test fixture may access them and the tear down destroy them. + * + * @param [in] testFixture A pointer to a valid LongBowTestFixture instance. + * @return The `LongBowTestCaseClipBoard` for the given `LongBowTestFixture`. + * + * @see longBowTestCase_GetClipBoard + */ +LongBowClipBoard *longBowTestFixture_GetClipBoard(const LongBowTestFixture *testFixture); + +/** + * Compose a C string representing the current state of the given `LongBowTestFixture`. + * + * @param [in] testFixture A pointer to a valid LongBowTestFixture instance. + * @return An allocated, nul-terminated C string that must be deallocated via free(3) + */ +char *longBowTestFixture_ToString(const LongBowTestFixture *testFixture); +#endif // LongBowTestFixture_H_ diff --git a/longbow/src/LongBow/longBow_TestFixtureConfig.c b/longbow/src/LongBow/longBow_TestFixtureConfig.c new file mode 100755 index 00000000..756c908a --- /dev/null +++ b/longbow/src/LongBow/longBow_TestFixtureConfig.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <stdio.h> + +#include <LongBow/longBow_TestFixtureConfig.h> +#include <LongBow/private/longBow_Memory.h> + +LongBowTestFixtureConfig * +longBowTestFixtureConfig_Create(const char *name, bool enabled) +{ + LongBowTestFixtureConfig *result = longBowMemory_Allocate(sizeof(LongBowTestFixtureConfig)); + + result->name = longBowMemory_StringCopy(name); + result->enabled = enabled; + + return result; +} + +void +longBowTestFixtureConfig_Destroy(LongBowTestFixtureConfig **configPtr) +{ + LongBowTestFixtureConfig *config = *configPtr; + + longBowMemory_Deallocate((void **) &config->name); + longBowMemory_Deallocate((void **) configPtr); +} diff --git a/longbow/src/LongBow/longBow_TestFixtureConfig.h b/longbow/src/LongBow/longBow_TestFixtureConfig.h new file mode 100755 index 00000000..0ccaf538 --- /dev/null +++ b/longbow/src/LongBow/longBow_TestFixtureConfig.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_TestFixtureConfig.h + * @ingroup testing + * @brief The Test Fixture configuration interface + * + */ +#ifndef LongBow_longBow_FixtureConfig_h +#define LongBow_longBow_FixtureConfig_h +#include <stdbool.h> + +struct longbow_fixture_config { + char *name; + + bool enabled; +}; +typedef struct longbow_fixture_config LongBowTestFixtureConfig; + +/** + * Create and initialise a LongBowTestFixtureConfig instance. + * + * @param [in] name The name of the Test Fixture + * @param [in] enabled True if the fixture is enabled, false otherwise. + * + * @return non-NULL A pointer to an allocated `LongBowTestFixtureConfig` isntance that must be destroyed via `longBowTestFixtureConfig_Destroy`. + * @return NULL An error occurred. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + * + * @see longBowTestFixtureConfig_Destroy + */ +LongBowTestFixtureConfig *longBowTestFixtureConfig_Create(const char *name, bool enabled); + +/** + * Destroy a LongBowTestFixtureConfig intance. + * + * @param [in,out] configPtr A pointer to a pointer to a `LongBowTestFixtureConfig` instance. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + * + * @see longBowTestFixtureConfig_Create + */ +void longBowTestFixtureConfig_Destroy(LongBowTestFixtureConfig **configPtr); +#endif // LongBow_longBow_FixtureConfig_h diff --git a/longbow/src/LongBow/longBow_TestRunner.c b/longbow/src/LongBow/longBow_TestRunner.c new file mode 100644 index 00000000..730333f4 --- /dev/null +++ b/longbow/src/LongBow/longBow_TestRunner.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <assert.h> +#include <inttypes.h> + +#include <LongBow/unit-test.h> + +#include <LongBow/longBow_TestRunner.h> +#include <LongBow/longBow_Properties.h> + +#include <LongBow/private/longBow_String.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_ArrayList.h> + +struct LongBowTestRunner { + const char *name; /**< The name of this LongBow test runner. */ + + LongBowStatus (*testRunnerSetup)(LongBowTestRunner *); /**< The Test Runner Setup function */ + + void (*testRunner)(LongBowTestRunner *); /**< The Test Case Runner function */ + + LongBowStatus (*testRunnerTearDown)(LongBowTestRunner *); /**< The Test Runner TearDown function */ + + LongBowArrayList *fixtures; /**< The LongBowTestFixtures of this Test Runner */ + + LongBowConfig *configuration; /**< The LongBowConfiguration for this Test Runner. */ + + /** + * The clipboard of information shared between the fixture setup, + * the test case, and the fixture tear-down. + */ + LongBowClipBoard *clipBoard; +}; + +void +longBowTestRunner_ConfigHelp(void) +{ + printf("Test Runner options:\n"); + printf(" --set <testRunnerName>/iterations=<count> Run the named test runner <count> times\n"); +} + +bool +longBowTestRunner_Config(LongBowConfig *config, const char *parameter) +{ + bool result = false; + LongBowArrayList *tokens = longBowString_Tokenise(parameter, "-="); + if (tokens != NULL) { + if (longBowArrayList_Length(tokens) == 2) { + result = longBowConfig_SetProperty(config, longBowArrayList_Get(tokens, 0), longBowArrayList_Get(tokens, 1)); + } + longBowArrayList_Destroy(&tokens); + } + return result; +} + +const char * +longBowTestRunner_GetName(const LongBowTestRunner *testRunner) +{ + assert(testRunner != NULL); + return testRunner->name; +} + +void +longBowTestRunner_AddFixture(LongBowTestRunner *testRunner, LongBowTestFixture *testFixture) +{ + longBowArrayList_Add(testRunner->fixtures, testFixture); +} + +LongBowTestRunner * +longBowTestRunner_Create(const char *name, + LongBowTestRunnerSetUp *setup, + LongBowTestRunnerRun *runner, + LongBowTestRunnerTearDown *tearDown) +{ + LongBowTestRunner *testRunner = longBowMemory_Allocate(sizeof(LongBowTestRunner)); + + if (testRunner != NULL) { + testRunner->name = name; + testRunner->testRunnerSetup = setup; + testRunner->testRunner = runner; + testRunner->testRunnerTearDown = tearDown; + testRunner->fixtures = longBowArrayList_Create((void (*)(void **))longBowTestFixture_Destroy); + testRunner->clipBoard = longBowClipBoard_Create(); + } + return testRunner; +} + +void +longBowTestRunner_Destroy(LongBowTestRunner **testRunnerPtr) +{ + if (testRunnerPtr != NULL) { + LongBowTestRunner *testRunner = *testRunnerPtr; + + longBowArrayList_Destroy(&testRunner->fixtures); + if (testRunner->clipBoard) { + longBowClipBoard_Destroy(&testRunner->clipBoard); + } + if (testRunner != NULL) { + longBowMemory_Deallocate((void **) testRunnerPtr); + } + } +} + +LongBowTestRunner * +longBowTestRunner_Run(LongBowTestRunner *testRunner) +{ + LongBowConfig *configuration = longBowTestRunner_GetConfiguration(testRunner); + unsigned long iterations = longBowConfig_GetUint32(configuration, 1, + "%s/iterations", longBowTestRunner_GetName(testRunner)); + + if (longBowConfig_IsTrace(configuration)) { + longBowReportTesting_Trace("%s: setup", longBowTestRunner_GetName(testRunner)); + } + LongBowStatus setupStatus = (*testRunner->testRunnerSetup)(testRunner); + + if (setupStatus != LONGBOW_STATUS_SETUP_SKIPTESTS) { + if (!longBowStatus_IsSuccessful(setupStatus)) { + char *statusString = longBowStatus_ToString(setupStatus); + printf("Warning: %s setup returned: %s.\n", testRunner->name, statusString); + free(statusString); + return testRunner; + } + + for (unsigned long i = 0; i < iterations; i++) { + if (longBowConfig_IsTrace(configuration)) { + longBowReportTesting_Trace("%s: run", longBowTestRunner_GetName(testRunner)); + } + (*testRunner->testRunner)(testRunner); + } + + if (longBowConfig_IsTrace(configuration)) { + longBowReportTesting_Trace("%s: tear-down", longBowTestRunner_GetName(testRunner)); + } + + LongBowStatus tearDownStatus = (*testRunner->testRunnerTearDown)(testRunner); + if (!longBowStatus_IsSuccessful(tearDownStatus)) { + char *statusString = longBowStatus_ToString(tearDownStatus); + printf("Warning: %s tear-down returned: %s.\n", testRunner->name, statusString); + free(statusString); + return testRunner; + } + } + + return testRunner; +} + +char * +longBowTestRunner_ToString(const LongBowTestRunner *runner) +{ + LongBowString *string = longBowString_CreateFormat("%s", longBowTestRunner_GetName(runner)); + + char *cString = longBowString_ToString(string); + longBowString_Destroy(&string); + return cString; +} + +LongBowTestFixture * +longBowTestRunner_GetFixture(const LongBowTestRunner *testRunner, size_t index) +{ + return longBowArrayList_Get(testRunner->fixtures, index); +} + +size_t +longBowTestRunner_GetFixtureCount(const LongBowTestRunner *testRunner) +{ + return longBowArrayList_Length(testRunner->fixtures); +} + +LongBowConfig * +longBowTestRunner_GetConfiguration(const LongBowTestRunner *testRunner) +{ + return testRunner->configuration; +} + +LongBowStatus +longBowTestRunner_GetStatus(const LongBowTestRunner *testRunner) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + // Just return the status of the first non-successful Test Fixture. + size_t nTestFixtures = longBowTestRunner_GetFixtureCount(testRunner); + for (size_t i = 0; i < nTestFixtures; i++) { + LongBowTestFixture *fixture = longBowTestRunner_GetFixture(testRunner, i); + if (!longBowTestFixture_IsSuccessful(fixture)) { + result = longBowTestFixture_GetStatus(fixture); + break; + } + } + return result; +} + +bool +longBowTestRunner_IsSuccessful(const LongBowTestRunner *testRunner) +{ + return longBowStatus_IsSuccessful(longBowTestRunner_GetStatus(testRunner)); +} + +bool +longBowTestRunner_IsFailed(const LongBowTestCase *testCase) +{ + return longBowStatus_IsFailed(longBowTestCase_GetStatus(testCase)); +} + +bool +longBowTestRunner_IsWarning(const LongBowTestRunner *testCase) +{ + return longBowStatus_IsWarning(longBowTestRunner_GetStatus(testCase)); +} + +bool +longBowTestRunner_IsIncomplete(const LongBowTestCase *testCase) +{ + return longBowStatus_IsIncomplete(longBowTestCase_GetStatus(testCase)); +} + +void +longBowTestRunner_SetConfiguration(LongBowTestRunner *testRunner, LongBowConfig *config) +{ + testRunner->configuration = config; +} + +LongBowClipBoard * +longBowTestRunner_GetClipBoard(const LongBowTestRunner *testRunner) +{ + return testRunner->clipBoard; +} + +bool +longBowTestRunner_SetClipBoardData(const LongBowTestRunner *testRunner, void *shared) +{ + return longBowClipBoard_Set(longBowTestRunner_GetClipBoard(testRunner), "testRunner", shared); +} + +void * +longBowTestRunner_GetClipBoardData(const LongBowTestRunner *testRunner) +{ + return longBowClipBoard_Get(longBowTestRunner_GetClipBoard(testRunner), "testRunner"); +} diff --git a/longbow/src/LongBow/longBow_TestRunner.h b/longbow/src/LongBow/longBow_TestRunner.h new file mode 100644 index 00000000..d787a17c --- /dev/null +++ b/longbow/src/LongBow/longBow_TestRunner.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_TestRunner.h + * @ingroup testing + * @brief LongBow Test Runner Support. + * + */ +#ifndef LONGBOWRUNNER_H_ +#define LONGBOWRUNNER_H_ + +#include <stdbool.h> + +struct LongBowTestRunner; +/** + * @typedef LongBowRunner + * @brief The LongBow Test Runner + */ +typedef struct LongBowTestRunner LongBowRunner; + +typedef struct LongBowTestRunner LongBowTestRunner; + +#include <LongBow/longBow_Config.h> +#include <LongBow/longBow_Status.h> +#include <LongBow/longBow_TestCase.h> +#include <LongBow/longBow_TestFixture.h> + +/** + * The function prototype for a LongBow Test Runner set-up function. + * + * @param testRunner A pointer to the associated LongBowTestRunner. + * @return A LongBowStatus value indicating the result of the set-up. + */ +typedef LongBowStatus (LongBowTestRunnerSetUp)(LongBowTestRunner *testRunner); + +/** + * The function prototype for a LongBow Test Runner function. + * + * @param testRunner A pointer to the associated LongBowTestRunner. + */ +typedef void (LongBowTestRunnerRun)(LongBowTestRunner *testRunner); + +/** + * The function prototype for a LongBow Test Runner tear-down function. + * + * @param testRunner A pointer to the associated LongBowTestRunner. + * @return A LongBowStatus value indicating the result of the tear-down. + */ +typedef LongBowStatus (LongBowTestRunnerTearDown)(LongBowTestRunner *testRunner); + +/** + * Allocate and initialise a LongBowTestRunner structure with the given parameters. + * + * See <code>longBowTestRunner_Destroy</code> to destroy the result. + * + * The parameters may be static values (ie. not allocated) supplied by the caller + * and they are not subject to free in <code>longBowTestRunner_Destroy</code>. + * + * @param [in] name The name of the LongBow test runner as a null-terminated string. + * @param [in] setup The setup function for the Test Runner + * @param [in] testRunner The function to call to execute the Test Runner. + * @param [in] tearDown The function to call to tear-down the Test Runner. + * @return An allocated LongBowTestRunner structure representing a Test Runner. + */ +LongBowTestRunner *longBowTestRunner_Create(const char *name, + LongBowTestRunnerSetUp *setup, + LongBowTestRunnerRun *testRunner, + LongBowTestRunnerTearDown *tearDown); + +/** + * Destroy a previously allocated LongBowTestRunner structure. + * + * @param [in,out] testRunnerPtr A pointer to a previously allocated LongBowTestRunner structure. + */ +void longBowTestRunner_Destroy(LongBowTestRunner **testRunnerPtr); + +/** + * Get the name of the given LongBowTestRunner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The name of the Test Runner. + */ +const char *longBowTestRunner_GetName(const LongBowTestRunner *testRunner); + +/** + * Get the `LongBowClipBoard` for the given LongBowTestRunner. + * + * Every LongBow test case has an associated "clipboard" that is specific to a test case + * and is shared between the fixture setup and tear down functions. + * Fixture setup may store things on the clipboard, + * the test case may access them and the tear down destroy them. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The LongBowClipBoard for the given LongBowTestCase. + */ +LongBowClipBoard *longBowTestRunner_GetClipBoard(const LongBowTestRunner *testRunner); + +/** + * Place a value on the Test Runner "clipboard" + * + * Every Test Runner has an associated "clipboard" which is shared between the Test Runner + * Setup and Test Runner Tear Down and is accessible to all Test Fixtures and Test Cases. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] shared The value to share on the clipboard. + * @return True if the value was set. + */ +bool longBowTestRunner_SetClipBoardData(const LongBowTestRunner *testRunner, void *shared); + +/** + * Get the clipboard data from the given `LongBowTestRunner`. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + */ +void *longBowTestRunner_GetClipBoardData(const LongBowTestRunner *testRunner); + +/** + * Execute a LongBow Test Runner. + * + * The Test Runner will have zero or more Test Fixtures executed in the order + * they are specified in the Test Runner function. + * See LONGBOW_TEST_RUNNER() + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The given LongBowTestRunner + */ +LongBowTestRunner *longBowTestRunner_Run(LongBowTestRunner *testRunner); + +/** + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return An allocated, nul-terminated C string that must be deallocated via free(3) + */ +char *longBowTestRunner_ToString(const LongBowTestRunner *testRunner); + +/** + * Add the supplied LongBowTestFixture to the list of Test Fixtures for the given Test Runner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] testFixture A pointer to a valid LongBowTestFixture instance. + */ +void longBowTestRunner_AddFixture(LongBowTestRunner *testRunner, LongBowTestFixture *testFixture); + +/** + * Get the number of Test Fixtures in the given Test Runner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return the number of Test Fixtures in the given Test Runner. + */ +size_t longBowTestRunner_GetFixtureCount(const LongBowTestRunner *testRunner); + +/** + * Get a pointer to the Test Fixture indexed by <code>index</code> in this Test Runner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] index The index of the LongBowTestFixture to get. + * @return The corresponding LongBowTestFixture. + */ +LongBowTestFixture *longBowTestRunner_GetFixture(const LongBowTestRunner *testRunner, size_t index); + +/** + * Get the status of the given LongBow Test Fixture. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The LongBowStatus of the given LongBowTestRunner + */ +LongBowStatus longBowTestRunner_GetStatus(const LongBowTestRunner *testRunner); + +/** + * Get a pointer to the LongBowConfig structure for the given Test Runner. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return A pointer to the LongBowConfig structure for the given runner. + */ +LongBowConfig *longBowTestRunner_GetConfiguration(const LongBowTestRunner *testRunner); + +/** + * Return `true` if the given Test Runner was successful. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return true if the status of the LongBowTestRunner was successful. + */ +bool longBowTestRunner_IsSuccessful(const LongBowTestRunner *testRunner); + +/** + * Return `true` if the given Test Runner was a failure. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return true if the status of the LongBowTestRunner is as a failure. + */ +bool longBowTestRunner_IsFailed(const LongBowTestCase *testCase); + +/** + * Return `true` if the given Test Runner was a warning. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return true if the status of the LongBowTestRunner was a warning. + */ +bool longBowTestRunner_IsWarning(const LongBowTestRunner *testRunner); + +/** + * Return `true` if the given Test Runner was incomplete. + * + * @param [in] testCase A pointer to a valid LongBowTestCase instance. + * @return true if the status of the LongBowTestRunner was incomplete. + */ +bool longBowTestRunner_IsIncomplete(const LongBowTestCase *testCase); + +/** + * Get the LongBowClipBoard for the given LongBowTestRunner. + * + * Every LongBow test runner has an associated "clipboard" that is specific to a test runner + * and is shared between the runner setup and tear down functions. + * The Test Runner setup may store things on the clipboard, + * the test fixtures and test cases may access them and the test runner tear down destroy them. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @return The LongBowClipBoard for the given LongBowTestRunner. + */ +LongBowClipBoard *longBowTestRunner_GetClipBoard(const LongBowTestRunner *testRunner); + +/** + * Set the configuration for the given LongBowTestRunner. + * + * The <code>LongBowConfig</code> pointed to by <code>configuration</code> is borrowed. + * If it is deallocated, reused, or overwritten results are unpredicable. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + * @param [in] configuration A pointer to a valid LongBowConfig instance. + */ +void longBowTestRunner_SetConfiguration(LongBowTestRunner *testRunner, LongBowConfig *configuration); + +/** + * Get the clipboard data from the given `LongBowTestRunner`. + * + * @param [in] testRunner A pointer to a valid LongBowTestRunner instance. + */ +void *longBowTestRunner_GetClipBoardData(const LongBowTestRunner *testRunner); + +/** + * Update the LongBowConfig instance with information indicated by @p parameter. + * + * @param [in] config A pointer to a valid LongBowConfig instance. + * @param [in] parameter A pointer to nul-terminated C string. + * + * @return true A valid parameter. + * @return false The value of @p parameter is invalid. + */ +bool longBowTestRunner_Config(LongBowConfig *config, const char *parameter); + +/** + * Print command line and configuration help applicable to a Long Bow Test Runner. + * + */ +void longBowTestRunner_ConfigHelp(void); +#endif /* LONGBOWRUNNER_H_ */ diff --git a/longbow/src/LongBow/longBow_UnitTest.h b/longbow/src/LongBow/longBow_UnitTest.h new file mode 100755 index 00000000..340c6fd1 --- /dev/null +++ b/longbow/src/LongBow/longBow_UnitTest.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_UnitTest.h + * @ingroup testing + * @brief Unit Testing Support. + * + */ +#ifndef __LongBow__longBow_UnitTest__ +#define __LongBow__longBow_UnitTest__ + +/** + * Compose the C function name prefix for a Test Runner. + * + * @param [in] _testRunnerName_ A valid identifier for the Test Runner. + */ +#define longBowUnitTest_RunnerName(_testRunnerName_) \ + LongBowTestRunner_ ## _testRunnerName_ + +/** + * Compose the C function name for a Test Runner Setup function. + * + * @param [in] _testRunnerName_ A valid identifier for the Test Runner. + */ +#define longBowUnitTest_RunnerSetupName(_testRunnerName_) \ + LongBowTestRunner_ ## _testRunnerName_ ## _Setup + +/** + * @brief Compose the C function name for a Test Runner Tear-Down function. + * + * @param [in] _testRunnerName_ A valid identifier for the Test Runner. + */ +#define longBowUnitTest_RunnerTearDownName(_testRunnerName_) \ + LongBowTestRunner_ ## _testRunnerName_ ## _TearDown + +/** + * @brief Compose the C function name for a Test Runner function. + * + * @param [in] _testRunnerName_ A valid identifier for the Test Runner. + */ +#define longBowUnitTest_RunnerRunName(_testRunnerName_) \ + LongBowTestRunner_ ## _testRunnerName_ ## _Run + +/** + * @defined longBowUnitTest_FixtureName + * @brief Compose a Test Fixture name. + * @param [in] _testFixtureName_ A valid identifier fragment for the Test Fixture. + */ +#define longBowUnitTest_FixtureName(_testFixtureName_) \ + LongBowTestFixture_ ## _testFixtureName_ + +/** + * @brief Compose the C function name for a Test Fixture function. + * + * @param [in] _testFixtureName_ A valid identifier for the Test Fixture. + */ +#define longBowUnitTest_FixtureRunName(_testFixtureName_) \ + LongBowTestFixture_ ## _testFixtureName_ ## _Run + +/** + * Compose the C function name for a Test Fixture Setup function. + * + * @param [in] _testFixtureName_ A valid identifier for the Test Fixture. + */ +#define longBowUnitTest_FixtureSetupName(_testFixtureName_) \ + LongBowTestFixture_ ## _testFixtureName_ ## _Setup + +/** + * @brief Compose the C function name for a Test Fixture Tear-Down function. + * + * @param [in] _testFixtureName_ A valid identifier for the Test Fixture. + */ +#define longBowUnitTest_FixtureTearDownName(_testFixtureName_) \ + LongBowTestFixture_ ## _testFixtureName_ ## _TearDown + +/** + * @brief Compose the C name for a Test Fixture Configuration structure. + * + * @param [in] _testFixtureName_ A valid identifier for the Test Fixture. + */ +#define longBowUnitTest_FixtureConfigName(_testFixtureName_) \ + LongBowTestFixture_ ## _testFixtureName_ ## _Config + +/** + * + */ +#define longBowUnitTest_CaseName(_testFixtureName_, _testCaseName_) \ + LongBowTestCase_ ## _testFixtureName_ ## _ ## _testCaseName_ + +#endif /* defined(__LongBow__longBow_UnitTest__) */ diff --git a/longbow/src/LongBow/longBow_UnitTesting.c b/longbow/src/LongBow/longBow_UnitTesting.c new file mode 100755 index 00000000..a33846ce --- /dev/null +++ b/longbow/src/LongBow/longBow_UnitTesting.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <inttypes.h> +#include <poll.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/param.h> + +#include <LongBow/private/longBow_ArrayList.h> +#include <LongBow/unit-test.h> + +#include <LongBow/longBow_UnitTesting.h> + +bool +longBowUnitTesting_AssertEqualsContract(bool (*equalsFunction)(void *a, void *b), void *x, void *y, void *z, ...) +{ + va_list ap; + va_start(ap, z); + + assertNotNull(x, "The value of x cannot be NULL."); + assertNotNull(y, "The value of y cannot be NULL."); + assertNotNull(z, "The value of z cannot be NULL."); + + assertFalse(x == y, "The value x cannot be the same as y"); + assertFalse(x == z, "The value x cannot be the same as z"); + assertFalse(y == z, "The value y cannot be the same as z"); + + assertTrue(equalsFunction(NULL, NULL), "Equality failed: Equals(NULL, NULL) must be true"); + + assertFalse(equalsFunction(x, NULL), "Equality failed: The value of x must not be Equal to NULL."); + assertFalse(equalsFunction(NULL, x), "Equality failed: NULL must not be equal to the value of x."); + + assertTrue(equalsFunction(x, x), + "Reflexive failed: for any non-null reference value x, equals(x, x) must return true."); + + assertTrue(equalsFunction(x, y), + "Equality failed: The values of x and y must be Equal."); + assertTrue(equalsFunction(x, z), + "Equality failed: The values of x and z must be Equal."); + + assertTrue(equalsFunction(x, y) == equalsFunction(y, x), + "Symmetric equality failed: equals(x, y) == equals(y, x) must true."); + + assertTrue((equalsFunction(x, y) == equalsFunction(y, z)) == equalsFunction(z, x), + "Transitive equality failed: equals(x, y) == equals(y, z) == equals(z, x) must true."); + + int index = 0; + for (void *value = va_arg(ap, void *); value != 0; value = va_arg(ap, void *)) { + assertFalse(equalsFunction(x, value), "Value %d (@%p) must not be equal to x", index, value); + assertTrue(equalsFunction(x, value) == equalsFunction(value, x), + "Symmetric equality failed: equals(x, value) == equals(value, x) must true."); + index++; + } + + va_end(ap); + return true; +} + +bool +longBowUnitTesting_AssertCompareToContract(int (*compareTo)(const void *a, const void *b), + void *exemplar, + void **equivalent, + void **lesser, + void **greater) +{ + assertNotNull(exemplar, "Parameter exemplar must not be NULL"); + assertNotNull(equivalent, "Parameter equivalent must not be NULL"); + assertNotNull(lesser, "Parameter less must not be NULL"); + assertNotNull(greater, "Parameter greater must not be NULL"); + + assertTrue(compareTo(NULL, NULL) == 0, + "Comparison of null values must be 0."); + + assertTrue(compareTo(exemplar, NULL) > 0, + "Comparison of a non-null value to a null value must be > 0."); + + assertTrue(compareTo(NULL, exemplar) < 0, + "Comparison of null value to a non-null value must be < 0."); + + assertTrue(compareTo(exemplar, exemplar) == 0, + "Comparison of a value to itself must == 0"); + + for (int i = 0; equivalent[i] != NULL; i++) { + assertTrue(compareTo(exemplar, equivalent[i]) == 0, + "Comparison of the value to equivalent[%d] must == 0", i); + assertTrue(compareTo(exemplar, equivalent[i]) == -compareTo(equivalent[i], exemplar), + "Requires sgn(compareTo(value, equivalent[%d])) == -sgn(equivalent[%d], value)", i, i); + } + for (int i = 0; lesser[i] != NULL; i++) { + assertTrue(compareTo(exemplar, lesser[i]) > 0, + "Compare of value to lesser[%d] must be > 0", i); + assertTrue(compareTo(exemplar, lesser[i]) == -compareTo(lesser[i], exemplar), + "Requires sgn(compareTo(value, lesser[%d])) == -sgn(lesser[%d], value)", i, i); + } + for (int i = 0; greater[i] != NULL; i++) { + assertTrue(compareTo(exemplar, greater[i]) < 0, + "Compare to greater[%d] must be > 0", i); + assertTrue(compareTo(exemplar, greater[i]) == -compareTo(greater[i], exemplar), + "Requires sgn(compareTo(value, greater[%d])) == -sgn(greater[%d], value)", i, i); + } + + return true; +} diff --git a/longbow/src/LongBow/longBow_UnitTesting.h b/longbow/src/LongBow/longBow_UnitTesting.h new file mode 100755 index 00000000..b03b2f88 --- /dev/null +++ b/longbow/src/LongBow/longBow_UnitTesting.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_UnitTesting.h + * @ingroup testing + * @brief Unit Testing Support. + * + */ +#ifndef LongBow_longBow_UnitTesting_h +#define LongBow_longBow_UnitTesting_h + +#include <stdbool.h> +#include <stdarg.h> + +/** + * Test a that a function implements the Equals contract. + * + * The equality function that this evaluates must implement the following equivalence relations on non-null instances: + * + * * It is reflexive: for any non-null reference value x, equals(x, x) must return true. + * + * * It is symmetric: for any non-null reference values x and y, equals(x, y) must return true if and only if + * equals(y x) returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * equals(x, y) returns true and + * equals(y, z) returns true, + * then equals(x, z) must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple invocations of equals(x, y) + * consistently return true or consistently return false. + * + * * For any non-null reference value x, equals(x, NULL)) must return false. + * + * @param [in] equalsFunction A pointer to a function that will be called to determine if it conforms to the Equals contract. + * @param [in] x A pointer to a value that will be used as the base comparision for remaining parameters. + * @param [in] y A pointer to a value that is known to be equal to @p x, but is not @p x. + * @param [in] z A pointer to a value that is known to be equal to @p x and to @p y, but is neither @p x nor @p y. + * @param [in] ... A NULL terminated list of pointers to values that are known to be not equal to @p x, @p y, or @p z. + * @return true if the function conforms to the Equals contract. + * @see assertEqualsContract() + */ +bool longBowUnitTesting_AssertEqualsContract(bool (*equalsFunction)(void *a, void *b), void *x, void *y, void *z, ...); + +/** + * Compares instance <code>a</code> with instance <code>b</code> for order. + * + * The comparison function that this evaluates <i>sgn(a - b)</i> required to return a negative integer, + * zero, or a positive integer as <code>a</code> is less than, + * equal to, or greater than <code>b</code>. + * + * The function must ensure that: + * <ul> + * <li>sgn(compareTo(a, b)) == -sgn(b, a) for all values of a and b.</li> + * <li>the relation is transitive: (compareTo(x, y)>0 && compareTo(y, z)>0) implies compareTo(x, z)>0.</li> + * <li>compareTo(x, y)== 0 implies that sgn(compareTo(x, z)) == sgn(compareTo(y, z)), for all values of z.</li> + * </ul> + * + * This also stipulates that + * <code>compareTo(NULL, NULL)) == 0</code>, + * <code>compareTo(not-NULL, NULL)) > 0</code>, + * <code>compareTo(NULL, not-NULL)) < 0</code>. + * + * It is strongly recommended, but not strictly required that relation(compareTo(x, y)==0) == equals(x, y)) is true. + * Any module that implements the compareTo function and violates this condition + * should clearly indicate this fact. + * For example, "Note: this implementation has a natural ordering that is inconsistent with equals." + * + * @param [in] compareTo A pointer to a function implementing the CompareTo function signature. + * @param [in] value The pivotal value under test. + * @param [in] equivalent A NULL terminated array of values that are all equivalent to <code>value</code>. + * @param [in] lesser A NULL terminated array of values that are all less than <code>value</code>. + * @param [in] greater A NULL terminated array of values that are all greater than <code>value</code>. + * @return <code>true</code> if the evalutation is successful. + * @see assertCompareToContract() + */ +bool longBowUnitTesting_AssertCompareToContract(int (*compareTo)(const void *a, const void *b), void *value, void **equivalent, void **lesser, void **greater); +#endif // LongBow_longBow_UnitTesting_h diff --git a/longbow/src/LongBow/private/longBow_ArrayList.c b/longbow/src/LongBow/private/longBow_ArrayList.c new file mode 100755 index 00000000..91cf02b9 --- /dev/null +++ b/longbow/src/LongBow/private/longBow_ArrayList.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdbool.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#include <LongBow/runtime.h> +#include <LongBow/private/longBow_ArrayList.h> +#include <LongBow/private/longBow_Memory.h> + +struct longbow_array_list { + void **array; + size_t numberOfElements; + size_t limit; + void (*destroyElement)(void **elementAddress); +}; + +static LongBowArrayList *_longBowArrayList_EnsureRemaining(LongBowArrayList *array, size_t remnant); +static LongBowArrayList *_longBowArrayList_EnsureCapacity(LongBowArrayList *array, size_t newCapacity); + +void +longBowArrayList_AssertValid(const LongBowArrayList *array) +{ + if (array == NULL) { + printf("Parameter must be a non-null pointer to a LongBowArrayList instance\n"); + abort(); + } +} + +LongBowArrayList * +longBowArrayList_Add(LongBowArrayList *array, const void *pointer) +{ + longBowArrayList_AssertValid(array); + + if (_longBowArrayList_EnsureRemaining(array, 1) == NULL) { + return NULL; + } + array->array[array->numberOfElements++] = (void *) pointer; + + return array; +} + +static size_t +_longBowArrayList_Remaining(const LongBowArrayList *array) +{ + longBowArrayList_AssertValid(array); + + return array->limit - array->numberOfElements; +} + +static LongBowArrayList * +_longBowArrayList_EnsureCapacity(LongBowArrayList *array, size_t newCapacity) +{ + longBowArrayList_AssertValid(array); + + void *newArray = longBowMemory_Reallocate(array->array, newCapacity * sizeof(void *)); + + if (newArray == NULL) { + return NULL; + } + array->array = newArray; + array->limit = newCapacity; + + return array; +} + +static LongBowArrayList * +_longBowArrayList_EnsureRemaining(LongBowArrayList *array, size_t remnant) +{ + longBowArrayList_AssertValid(array); + + if (_longBowArrayList_Remaining(array) < remnant) { + size_t newCapacity = longBowArrayList_Length(array) + remnant; + return _longBowArrayList_EnsureCapacity(array, newCapacity); + } + return array; +} + +bool +longBowArrayList_Equals(const LongBowArrayList *a, const LongBowArrayList *b) +{ + if (a != b) { + if (a == NULL || b == NULL) { + return false; + } + if (a->numberOfElements == b->numberOfElements) { + for (size_t i = 0; i < a->numberOfElements; i++) { + if (a->array[i] != b->array[i]) { + return false; + } + } + } + } + + return true; +} + +void * +longBowArrayList_Get(const LongBowArrayList *array, size_t index) +{ + longBowArrayList_AssertValid(array); + + assert(index < array->numberOfElements); + + return array->array[index]; +} + +size_t +longBowArrayList_Length(const LongBowArrayList *array) +{ + longBowArrayList_AssertValid(array); + + return array->numberOfElements; +} + +LongBowArrayList * +longBowArrayList_Create(void (*destroyElement)(void **elementAddress)) +{ + LongBowArrayList *result = longBowMemory_Allocate(sizeof(LongBowArrayList)); + + if (result != NULL) { + result->numberOfElements = 0; + result->limit = 0; + result->array = NULL; + result->destroyElement = destroyElement; + } + + return result; +} + +LongBowArrayList * +longBowArrayList_Create_Capacity(void (*destroyElement)(void **elementAddress), size_t size) +{ + LongBowArrayList *result = longBowArrayList_Create(destroyElement); + if (result != NULL) { + _longBowArrayList_EnsureRemaining(result, size); + } + + return result; +} + +void +longBowArrayList_Destroy(LongBowArrayList **arrayPtr) +{ + assertNotNull(arrayPtr, "Parameter must be a non-null pointer to a LongBow_ArrayList pointer."); + + LongBowArrayList *array = *arrayPtr; + + longBowArrayList_AssertValid(array); + + assertTrue(array->numberOfElements == 0 ? true : array->array != NULL, "LongBow_ArrayList is inconsistent."); + + if (array->destroyElement != NULL) { + for (size_t i = 0; i < array->numberOfElements; i++) { + array->destroyElement(&array->array[i]); + array->array[i] = NULL; + } + } + + if (array->array != NULL) { + longBowMemory_Deallocate((void **) &array->array); + } + + longBowMemory_Deallocate((void **) arrayPtr); +} + +void ** +longBowArrayList_GetArray(const LongBowArrayList *array) +{ + longBowArrayList_AssertValid(array); + return array->array; +} + +LongBowArrayList * +longBowArrayList_Copy(const LongBowArrayList *original) +{ + longBowArrayList_AssertValid(original); + + LongBowArrayList *result = longBowMemory_Allocate(sizeof(LongBowArrayList)); + + if (result != NULL) { + for (size_t i = 0; i < original->numberOfElements; i++) { + longBowArrayList_Add(result, original->array[i]); + } + } + + return result; +} + +void +longBowArrayList_StdlibFreeFunction(void **elementPtr) +{ + if (elementPtr != NULL) { + free(*elementPtr); + *elementPtr = 0; + } +} + +LongBowArrayList * +longBowArrayList_RemoveAtIndex(LongBowArrayList *array, size_t index) +{ + longBowArrayList_AssertValid(array); + + size_t length = longBowArrayList_Length(array); + assertTrue(index < length, "Index must be ( 0 <= index < %zd). Actual=%zd", length, index); + + if (index < length) { + // Destroy the element at the given index. + if (array->destroyElement != NULL) { + array->destroyElement(&array->array[index]); + } + + // Adjust the list to elide the element. + for (size_t i = index; i < length; i++) { + array->array[i] = array->array[i + 1]; + } + array->numberOfElements--; + } + + return array; +} + +LongBowArrayList * +longBowArrayList_Add_AtIndex(LongBowArrayList *array, const void *pointer, size_t index) +{ + longBowArrayList_AssertValid(array); + size_t length = longBowArrayList_Length(array); + + if (index > array->limit) { + // We need to grow the array to fit this element. + _longBowArrayList_EnsureCapacity(array, index + 1); + array->numberOfElements = index + 1; + } else { + // Create space and grow the array if needed + _longBowArrayList_EnsureRemaining(array, length + 1); + for (size_t i = index; i < length; i++) { + array->array[i + 1] = array->array[i]; + } + array->numberOfElements++; + } + + array->array[index] = (void *) pointer; + + + return array; +} + +bool +longBowArrayList_Replace(LongBowArrayList *array, const void *old, void *new) +{ + for (size_t i = 0; i < longBowArrayList_Length(array); i++) { + if (array->array[i] == old) { + array->array[i] = new; + return true; + } + } + return false; +} diff --git a/longbow/src/LongBow/private/longBow_ArrayList.h b/longbow/src/LongBow/private/longBow_ArrayList.h new file mode 100644 index 00000000..71eeb2b9 --- /dev/null +++ b/longbow/src/LongBow/private/longBow_ArrayList.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_ArrayList.h + * @ingroup internals + * @brief A simple, list implementation using a dynamic array. + * + */ +#ifndef LongBow_ARRAYLIST_H +#define LongBow_ARRAYLIST_H + +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> + +/** + * @struct longbow_array_list + * @brief A LongBow_ArrayList is a (dynamic) array of <code>void *</code> pointers; + */ +struct longbow_array_list; + +/** + * @typedef LongBowArrayList + * @brief The struct longbow_array_list + */ +typedef struct longbow_array_list LongBowArrayList; + +/** + * Assert that a LongBowArrayList instance is valid. + * + * @param [in] array A pointer to a valid LongBowArrayList instance. + * + */ +void longBowArrayList_AssertValid(const LongBowArrayList *array); +/** + * Add a pointer to an element to the given LongBowArrayList. + * + * If the list was constructed with a destroyer, + * the pointer will be destroyed when element is removed or the list is destroyed. + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @param [in] pointer An arbitrary value to store. + * + * @return The input array pointer. + */ +LongBowArrayList *longBowArrayList_Add(LongBowArrayList *array, const void *pointer); + +/** + * Remove an element at a specific index from an Array List. + * + * The element is destroyed via the function provided when calling <code>longBowArrayList_Create</code>. + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @param [in] index The index of the element to remove. + * + * @return A pointer to the modified LongBowArrayList. + */ +LongBowArrayList *longBowArrayList_RemoveAtIndex(LongBowArrayList *array, size_t index); + +/** + * Add an element at the index location. Elements will be moved up if required. + * If the index is higher than the current Length the Array will be grown to that size + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @param [in] pointer An arbitrary value to store. + * @param [in] index The position that the value will be stored after. + * @return A pointer to the modified LongBowArrayList. + */ +LongBowArrayList *longBowArrayList_Add_AtIndex(LongBowArrayList *array, const void *pointer, size_t index); + +/** + * Create an instance of an empty LongBowArrayList. + * + * @param [in] destroyElement + * A pointer to a function that will destroy (or equivalent) the element pointed to by <code>element</code> + * @return A pointer to a LongBowArrayList instance, or NULL if no memory could be allocated. + */ +LongBowArrayList *longBowArrayList_Create(void (*destroyElement)(void **elementAddress)); + +/** + * Create an instance of a LongBowArrayList pre-provisioned to contain the specified number of elements. + * + * @param [in] size + * The number of initial elements to provision for. + * @param [in] destroyElement + * A pointer to a function that will destroy (or equivalent) the element pointed to by <code>element</code> + * @return A pointer to a LongBowArrayList instance, or NULL if no memory could be allocated. + */ +LongBowArrayList *longBowArrayList_Create_Capacity(void (*destroyElement)(void **elementAddress), size_t size); + +/** + * Get an array of void * pointers. + * Return a pointer to an array of void * pointers contained in this Array List. + * The returned value may be the actual backing array for the Array List. + * + * @param [in] array The LongBow_ArrayList + * @return A pointer to an array of void * pointers contained in this Array List. + * + */ +void **longBowArrayList_GetArray(const LongBowArrayList *array); + +/** + * Copy a LongBowArrayList instance. + * Create a new LongBowArrayList instance with the same structure and content as the original. + * + * @param [in] array A pointer to a LongBowArrayList instance to copy. + * @return A pointer to a LongBowArrayList instance with a copy of the original, or NULL if no memory could be allocated. + */ +LongBowArrayList *longBowArrayList_Copy(const LongBowArrayList *array); + +/** + * Destroy a LongBowArrayList instance. + * + * Destroy the given LongBowArrayList by freeing all memory used by it. + * + * @param [in,out] arrayPtr A pointer to a LongBowArrayList pointer. + */ +void longBowArrayList_Destroy(LongBowArrayList **arrayPtr); + +/** + * Get an element from the given list at a specified index. + * The index must be 0 <= index < length. + * + * @return A pointer (void *) to the element in the list. + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @param [in] index The index of the required element. + */ +void *longBowArrayList_Get(const LongBowArrayList *array, size_t index); + +/** + * Return the number of elements in the given LongBowArrayList. + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @return A size_t of the number of elements in the given LongBowArrayList. + */ +size_t longBowArrayList_Length(const LongBowArrayList *array); + + +/** + * Determine if two LongBowArrayList instances are equal. + * + * Two LongBowArrayList instances are equal if, and only if, they both contain the same pointers in the same order. + * + * The following equivalence relations on non-null `LongBowArrayList` instances are maintained: + * + * * It is reflexive: for any non-null reference value x, `LongBowArrayList_Equals(x, x)` + * must return true. + * + * * It is symmetric: for any non-null reference values x and y, + * `longBowArrayList_Equals(x, y)` must return true if and only if + * `longBowArrayList_Equals(y, x)` returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * `longBowArrayList_Equals(x, y)` returns true and + * `longBowArrayList_Equals(y, z)` returns true, + * then `longBowArrayList_Equals(x, z)` must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple + * invocations of `longBowArrayList_Equals(x, y)` consistently return true or + * consistently return false. + * + * * For any non-null reference value x, `longBowArrayList_Equals(x, NULL)` must + * return false. + * + * @param a A pointer to a `LongBowArrayList` instance. + * @param b A pointer to a `LongBowArrayList` instance. + * @return true if the two `LongBowArrayList` instances are equal. + * + * Example: + * @code + * { + * LongBowArrayList *a = longBowArrayList_Create(); + * LongBowArrayList *b = longBowArrayList_Create(); + * + * if (longBowArrayList_Equals(a, b)) { + * // true + * } else { + * // false + * } + * } + * @endcode + */ + +bool longBowArrayList_Equals(const LongBowArrayList *a, const LongBowArrayList *b); + +/** + * Standard library free(3) wrapper for use as a destructor function for elements of a LongBowArrayList. + * + * The create functions for LongBowArrayList have an input parameter that is a pointer to a function that + * will be called for each element when the Array List is destroyed, and when an element is removed via longBowArrayList_RemoveAtIndex. + * This destroy function has a different calling signature than the standard library's free(3) function. + * This function is a wrapper providing the correct facade for the standard library free(3) function. + * + * @param [in,out] element A pointer to the pointer to an element to be destroyed. + */ +void longBowArrayList_StdlibFreeFunction(void **element); + +/** + * Replace the first occurance of an existing element in the given LongBowArrayList. + * + * Paragraphs Of Explanation + * + * @param [in] array A pointer to a LongBowArrayList instance. + * @param [in] old A pointer to an element in the list to replace. + * @param [in] new A pointer to an element that will replace old. + * + * @return true If the element was found and replaced. + * @return false If the element was not found. + */ +bool longBowArrayList_Replace(LongBowArrayList *array, const void *old, void *new); +#endif // LongBow_ARRAYLIST_H diff --git a/longbow/src/LongBow/private/longBow_Memory.c b/longbow/src/LongBow/private/longBow_Memory.c new file mode 100644 index 00000000..1c20101e --- /dev/null +++ b/longbow/src/LongBow/private/longBow_Memory.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <LongBow/private/longBow_Memory.h> + +#if HAVE_REALLOC == 0 +static void * +_LongBow_rplRealloc(void *oldAlloc, size_t newSize) +{ + if (newSize == 0) { + newSize = 1; + } + + char *newAlloc = malloc(newSize); + + if (oldAlloc != NULL) { + memcpy(newAlloc, oldAlloc, newSize); + free(oldAlloc); + } + return newAlloc; +} +#endif + +static uint64_t _outstandingAllocations; + +void * +longBowMemory_Allocate(const size_t size) +{ + _outstandingAllocations++; + return calloc(1, size); +} + +void * +longBowMemory_Reallocate(void *oldAllocation, const size_t newSize) +{ +#if HAVE_REALLOC + void *result = realloc(oldAllocation, newSize); +#else + void *result = _LongBow_rplRealloc(oldAllocation, newSize); +#endif + + if (oldAllocation == NULL) { + _outstandingAllocations++; + } + + return result; +} + +void +longBowMemory_Deallocate(void **pointerPointer) +{ + free(*pointerPointer); + _outstandingAllocations--; + *pointerPointer = NULL; +} + +uint64_t +longBowMemory_OutstandingAllocations(void) +{ + return _outstandingAllocations; +} + +char * +longBowMemory_StringCopy(const char *string) +{ + char *result = NULL; + + if (string != NULL) { + size_t length = strlen(string); + result = longBowMemory_Allocate(length + 1); + strcpy(result, string); + result[length] = 0; + } + return result; +} diff --git a/longbow/src/LongBow/private/longBow_Memory.h b/longbow/src/LongBow/private/longBow_Memory.h new file mode 100755 index 00000000..173491dc --- /dev/null +++ b/longbow/src/LongBow/private/longBow_Memory.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_Memory.c + * @ingroup internal + * @brief Memory allocation and deallocation support. + * + */ +#ifndef LongBow_longBow_Memory_h +#define LongBow_longBow_Memory_h + +#include <stdint.h> + +/** + * Allocate `size` bytes of memory. + * + * @param [in] size The number of bytes to allocate + * + * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate` + * @return NULL Memory could not be allocated. + * @see longBowMemory_Deallocate + */ +void *longBowMemory_Allocate(const size_t size); + +/** + * Reallocate memory adjusting to a new size. + * + * @param [in] oldAllocation A pointer to memory previously allocated by `longBowMemory_Allocate` or `longBowMemory_Reallocate` + * @param [in] newSize The number of bytes to allocate + * + * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate` + * @return NULL Memory could not be allocated. + * @see longBowMemory_Allocate + */ +void *longBowMemory_Reallocate(void *oldAllocation, const size_t newSize); + +/** + * Deallocate previously allocated memory. + * + * @param [in,out] pointerPointer A pointer to a pointer to allocated memory that will set to NULL. + * + * @see longBowMemory_Allocate + */ +void longBowMemory_Deallocate(void **pointerPointer); + +/** + * Duplicate a nul-terminated C string in allocated memory. + * + * @param [in] string The nul-terminated string to duplicate + * + * @return non-NULL A pointer to allocated memory that must be deallocated via `longBowMemory_Deallocate` + * @return NULL Memory could not be allocated. + * + * Example: + * @code + * { + * char *copy = longBowMemory_StringCopy("Hello World"); + * + * longBowMemory_Deallocate((void **) ©); + * } + * @endcode + * + * @see longBowMemory_Deallocate + */ +char *longBowMemory_StringCopy(const char *string); + +/** + * Get the count of outstanding memory allocations. + * + * @return The number of outstanding memory allocations. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + */ +uint64_t longBowMemory_OutstandingAllocations(void); +#endif diff --git a/longbow/src/LongBow/private/longBow_OpenFile.c b/longbow/src/LongBow/private/longBow_OpenFile.c new file mode 100644 index 00000000..6b82069f --- /dev/null +++ b/longbow/src/LongBow/private/longBow_OpenFile.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include <config.h> + +#include <stdio.h> +#include <inttypes.h> +#include <stdlib.h> +#include <poll.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/param.h> +#include <sys/resource.h> +#include <string.h> + +#include <LongBow/private/longBow_OpenFile.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/private/longBow_String.h> + +struct longbow_openfile { + char *fullPathName; + struct stat statbuf; + int fd; +}; + +#if defined(_WIN64) +static char * +_getFullPathNameFromFd(int fd) +{ + return strdup("./"); +} +#elif defined(_WIN32) +static char * +_getFullPathNameFromFd(int fd) +{ + return strdup("./"); +} +#elif defined(__APPLE__) +static char * +_getFullPathNameFromFd(int fd) +{ + char filePath[PATH_MAX]; + + if (fcntl(fd, F_GETPATH, filePath) != -1) { + return strdup(filePath); + } + return NULL; +} +#elif defined(__linux) +static char * +_getFullPathNameFromFd(int fd) +{ + return strdup("./"); +} +#elif defined(__unix) // all unices not caught above +static char * +_getFullPathNameFromFd(int fd) +{ + return strdup("./"); +} +#elif defined(__posix) +static char * +_getFullPathNameFromFd(int fd) +{ + return strdup("./"); +} +#endif + +LongBowOpenFile * +longBowOpenFile_Create(int fd) +{ + LongBowOpenFile *result = longBowMemory_Allocate(sizeof(LongBowOpenFile)); + if (result != NULL) { + result->fd = fd; + + if (fstat(fd, &result->statbuf) == 0) { + result->fullPathName = _getFullPathNameFromFd(fd); + } + } + return result; +} + +void +longBowOpenFile_Destroy(LongBowOpenFile **openFilePtr) +{ + longBowMemory_Deallocate((void **) openFilePtr); +} + +char * +longBowOpenFile_StructStatToString(const struct stat *statbuf) +{ + LongBowString *string = longBowString_CreateFormat("0x%" PRIx16 " %3ld %10d %10d %6lld", + statbuf->st_mode, + (long) statbuf->st_nlink, + statbuf->st_uid, + statbuf->st_gid, + (long long) statbuf->st_size); + char *result = longBowString_ToString(string); + + return result; +} + +char * +longBowOpenFile_ToString(LongBowOpenFile *openFile) +{ + char *statString = longBowOpenFile_StructStatToString(&(openFile->statbuf)); + LongBowString *string = longBowString_CreateFormat("%d %s %s", openFile->fd, statString, openFile->fullPathName); + free(statString); + char *result = longBowString_ToString(string); + + return result; +} + +LongBowArrayList * +longBowOpenFile_CurrentlyOpen(void) +{ + struct rlimit rlimit; + + bool success = getrlimit(RLIMIT_NOFILE, &rlimit) == 0; + if (!success) { + return NULL; + } + // Here is a potential problem: struct rlimit specifies rlim_cur as a 64 bit value (rlim_t), but poll only takes an + // unsigned int's worth of file descriptors. + + LongBowArrayList *list = longBowArrayList_Create(longBowArrayList_StdlibFreeFunction); + + for (nfds_t i = 0; i < (nfds_t) rlimit.rlim_cur; i++) { + int flags = fcntl((int) i, F_GETFD); + if (flags != -1) { + LongBowOpenFile *openFile = longBowOpenFile_Create((int) i); + longBowArrayList_Add(list, openFile); + } + } + + return list; +} diff --git a/longbow/src/LongBow/private/longBow_OpenFile.h b/longbow/src/LongBow/private/longBow_OpenFile.h new file mode 100755 index 00000000..10756ba5 --- /dev/null +++ b/longbow/src/LongBow/private/longBow_OpenFile.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_OpenFile.h + * @ingroup testing + * @brief LongBow support for files and file descriptors. + * + */ +#ifndef LongBow_longBow_Files_h +#define LongBow_longBow_Files_h + +#include <sys/stat.h> + +#include <LongBow/private/longBow_ArrayList.h> + +struct longbow_openfile; +/** + * @typedef LongBowOpenFile + * @brief A representation of an open file. + */ +typedef struct longbow_openfile LongBowOpenFile; + +/** + * @param [in] fd The file descriptor. + * @return An allocated LongBowOpenFile instance that must be destroyed via longBowOpenFile_Destroy(). + */ +LongBowOpenFile *longBowOpenFile_Create(int fd); + +/** + * + * @param [in,out] openFilePtr A pointer to a pointer to a valid LongBowOpenFile instance. + */ +void longBowOpenFile_Destroy(LongBowOpenFile **openFilePtr); + +/** + * + * @param [in] openFile A pointer to a valid LongBowOpenFile instance. + * @return A nul-terminate C string that must be freed via free(3). + */ +char *longBowOpenFile_ToString(LongBowOpenFile *openFile); + +/** + * Create a list of the currently open files. + * + * @return A list of LongBowOpenFile instances for each open file. + */ +LongBowArrayList *longBowOpenFile_CurrentlyOpen(void); + +/** + * Return a nul-terminated C string representing the given `struct stat` pointed to by @p statbuf. + * + * @param [in] statbuf A pointer to a valid `struct stat` instance. + * + * @return non-NULL A nul-terminated C string that must be deallocated via longBowMemory_Deallocate. + */ +char *longBowOpenFile_StructStatToString(const struct stat *statbuf); +#endif diff --git a/longbow/src/LongBow/private/longBow_String.c b/longbow/src/LongBow/private/longBow_String.c new file mode 100644 index 00000000..1def87a1 --- /dev/null +++ b/longbow/src/LongBow/private/longBow_String.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include <LongBow/private/longBow_String.h> +#include <LongBow/private/longBow_Memory.h> + +struct longbow_string { + char *buffer; + size_t cursor; // always the index of the nul terminating byte of the stored string. + size_t end; // always the index of the very last byte in buffer; +}; + +static size_t +_longBowString_RemainingSpace(const LongBowString *string) +{ + size_t result = string->end - string->cursor; + + return result; +} + +LongBowString * +longBowString_Create(const size_t initialSize) +{ + LongBowString *result = longBowMemory_Allocate(sizeof(LongBowString)); + result->end = initialSize; + result->buffer = longBowMemory_Allocate(initialSize); + result->cursor = 0; + + return result; +} + +LongBowString * +longBowString_CreateString(const char *string) +{ + LongBowString *result = longBowMemory_Allocate(sizeof(LongBowString)); + result->end = strlen(string) + 1; + result->buffer = longBowMemory_StringCopy(string); + result->cursor = result->end - 1; + result->buffer[result->cursor] = 0; + + return result; +} + +LongBowString * +longBowString_CreateFormat(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + char *cString; + if (vasprintf(&cString, format, ap) == -1) { + return NULL; + } + va_end(ap); + + LongBowString *string = longBowString_CreateString(cString); + + free(cString); + + return string; +} + +void +longBowString_Destroy(LongBowString **stringPtr) +{ + LongBowString *string = *stringPtr; + if (string != NULL) { + longBowMemory_Deallocate((void **) &string->buffer); + longBowMemory_Deallocate((void **) stringPtr); + } +} + +LongBowString * +longBowString_Append(LongBowString *string, const char *value) +{ + size_t length = strlen(value) + 1; + + if (_longBowString_RemainingSpace(string) < length) { + size_t size = string->end + length; + string->buffer = longBowMemory_Reallocate(string->buffer, size); + string->end = size - 1; + } + strcpy(&string->buffer[string->cursor], value); + string->cursor += (length - 1); + string->buffer[string->cursor] = 0; + + return string; +} + +LongBowString * +longBowString_Format(LongBowString *string, const char *format, ...) +{ + LongBowString *result = NULL; + + va_list ap; + va_start(ap, format); + + char *cString; + int status = vasprintf(&cString, format, ap); + va_end(ap); + if (status != -1) { + result = longBowString_Append(string, cString); + free(cString); + } else { + result = NULL; + } + + return result; +} + +char * +longBowString_ToString(const LongBowString *string) +{ + char *result = strndup(string->buffer, string->end); + return result; +} + +bool +longBowString_StartsWith(const char *string, const char *prefix) +{ + bool result = strncmp(string, prefix, strlen(prefix)) == 0; + return result; +} + +bool +longBowString_Equals(const char *string, const char *other) +{ + return strcmp(string, other) == 0; +} + +bool +longBowString_Write(const LongBowString *string, FILE *fp) +{ + bool result = false; + size_t nwrite = string->end; + + if (fwrite(string->buffer, sizeof(char), string->end, fp) == nwrite) { + result = true; + } + + return result; +} + +LongBowArrayList * +longBowString_Tokenise(const char *string, const char *separators) +{ + LongBowArrayList *result = longBowArrayList_Create(longBowMemory_Deallocate); + if (string != NULL) { + char *workingCopy = longBowMemory_StringCopy(string); + + char *p = strtok(workingCopy, separators); + while (p) { + longBowArrayList_Add(result, longBowMemory_StringCopy(p)); + p = strtok(NULL, separators); + } + + longBowMemory_Deallocate((void **) &workingCopy); + } + + return result; +} diff --git a/longbow/src/LongBow/private/longBow_String.h b/longbow/src/LongBow/private/longBow_String.h new file mode 100755 index 00000000..463dfbd8 --- /dev/null +++ b/longbow/src/LongBow/private/longBow_String.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file longBow_String.h + * @brief <#Brief Description#> + * + * <#Detailed Description#> + * + */ +#ifndef __LongBow__longBow_String__ +#define __LongBow__longBow_String__ + +#include <stdbool.h> +#include <stdio.h> + +#include <LongBow/private/longBow_ArrayList.h> + +struct longbow_String; +typedef struct longbow_string LongBowString; + +/** + * Create a LongBowString + * + * <#Paragraphs Of Explanation#> + * + * @param [in] initialSize The initial buffer size to allocate for the string. + * + * @return non-NULL A pointer to a valid LongBowString instance. + * @return NULL Memory could not be allocated. + * + */ +LongBowString *longBowString_Create(const size_t initialSize); + +/** + * Create a `LongBowString` instance containing the formatted result of the given format string and parameters. + * + * @param [in] format A pointer to a valid LongBowString instance. + * + * @return The a LongBowString instance that must be deallocated via longBowString_Deallocate. + */ +LongBowString *longBowString_CreateFormat(const char *format, ...) __attribute__((format(printf, 1, 2))); + +/** + * Destroy a LongBowString instance. + * + * The pointer will be set to zero on return. + * + * @param [in,out] stringPtr A pointer to a valid LongBowString instance. + */ +void longBowString_Destroy(LongBowString **stringPtr); + +/** + * Append to the given LongBowString instance the formatted result of the given format string and parameters. + * + * @param [in] string A pointer to a valid LongBowString instance. + * + * @return The value of @p string + */ +LongBowString *longBowString_Format(LongBowString *string, const char *format, ...) __attribute__((format(printf, 2, 3))); + +/** + * Determine if a string begins with a specific prefix. + * + * @param [in] string A nul-terminated C string. + * @param [in] prefix A nul-terminated C string. + * + * @return true The value of @p string starts with @p prefix. + * @return false The value of @p string does not start with @p prefix. + * + * Example: + * @code + * { + * bool result = longBowString_StartsWith("Hello World", "Hello"); + * } + * @endcode + */ +bool longBowString_StartsWith(const char *string, const char *prefix); + +/** + * Determine if a nul-terminated C string is equal to another. + * + * @param [in] string A nul-terminated C string. + * @param [in] other A nul-terminated C string. + * + * @return true The value of @p string starts with @p prefix. + * @return false The value of @p string does not start with @p prefix. + * + * Example: + * @code + * { + * bool result = longBowString_StartsWith("Hello World", "Hello"); + * } + * @endcode + */ +bool longBowString_Equals(const char *string, const char *other); + +/** + * Produce a LongBowArrayList containing the tokens for the given @p string + * where each token is separated by characters in the string @p separators. + * + * @param [in] string A nul-terminated C string. + * @param [in] separators A nul-terminated C string containing the characters that separate the tokens. + * + * @return non-NULL A valid LongBowArrayList containing the tokens of the string. + * @return NULL Memory could not be allocated. + * + * Example: + * @code + * { + * LongBowArrayList *result = longBowString_Tokenise("Hello World", " "); + * .... + * longBowArrayList_Destroy(&result); + * } + * @endcode + */ +LongBowArrayList *longBowString_Tokenise(const char *string, const char *separators); + +/** + * Produce a nul-terminated C string from the given LongBowString instance. + * + * @param [in] string A pointer to a valid LongBowString instance. + * + * @return non-NULL A pointer to a nul-terminated C string that must be deallocated via free(3). + */ +char *longBowString_ToString(const LongBowString *string); + +/** + * Write the contents of the given LongBowString instance to the specified FILE output stream. + * + * @param [in] string A pointer to a valid LongBowString instance. + * @param [in] fp A pointer to a valid FILE instance. + * + * @return true All of the string was successfully written. + * @return false All of the string was not successfully written. + */ +bool longBowString_Write(const LongBowString *string, FILE *fp); + +#endif /* defined(__LongBow__longBow_String__) */ diff --git a/longbow/src/LongBow/runtime.h b/longbow/src/LongBow/runtime.h new file mode 100644 index 00000000..5acd790d --- /dev/null +++ b/longbow/src/LongBow/runtime.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file runtime.h + * @ingroup runtime + * @brief LongBow Runtime Support + * + */ +#ifndef LongBow_runtime_h +#define LongBow_runtime_h + +#include <signal.h> + +#include <LongBow/longBow_Runtime.h> + +/** + * @def longBowIsFalse + * @brief Indicate true if a condition is false. + * + * @param [in] condition The condition to test. + */ +#if __GNUC__ +# define longBowIsFalse(condition) __builtin_expect(!(condition), 0) +#else +# define longBowIsFalse(condition) (!(condition)) +#endif + +#if __STDC_VERSION__ < 199901L +# define __func__ ((const char *) 0) +#endif + +/** + * @def longBowEvent + * @brief If the condition is true record the given event and abort the running programme. + * + * @param [in] eventPointer + * @param [in] condition A boolean value that is expected to be true. + * @param [in] location A pointer to a LongBowLocation instance. + * @param [in] ... A printf format string following corresponding parameters. + */ +#ifdef LongBow_DISABLE_ASSERTIONS +#define longBowEvent(eventPointer, condition, location, ...) if (0 && condition) for (; false; ) +#else +#define longBowEvent(eventPointer, condition, location, ...) \ + if (longBowRuntime_EventEvaluation(eventPointer) && longBowIsFalse(condition) && \ + longBowRuntime_EventTrigger(eventPointer, location, #condition, __VA_ARGS__)) \ + for (; true; longBowRuntime_Abort(), kill(0, SIGTRAP)) +#endif + +/** + * @def longBowAssert + * @brief Assert a condition, abort the running programme recording the given event if the condition is false. + * + * @param [in] eventPointer + * @param [in] condition A boolean value that is expected to be true. + * @param [in] ... A printf format string following corresponding parameters. + */ + +# define longBowAssert(eventPointer, condition, ...) \ + longBowEvent(eventPointer, condition, longBowLocation_Create(__FILE__, __func__, __LINE__), __VA_ARGS__) + +/** + * @def longBowTrap + * @brief Abort the running programme recording the given trap. + * + * @param [in] eventPointer + * @param [in] ... A printf format string following corresponding parameters. + */ +#define longBowTrap(eventPointer, ...) \ + longBowRuntime_EventEvaluation(eventPointer); \ + if (longBowRuntime_EventTrigger(eventPointer, \ + longBowLocation_Create(__FILE__, __func__, __LINE__), longBowEventType_GetName(eventPointer), __VA_ARGS__), true) \ + for (; true; abort()) + + +#define longBowTrapIf(eventPointer, condition, ...) \ + longBowEvent(eventPointer, (!(condition)), longBowLocation_Create(__FILE__, __func__, __LINE__), __VA_ARGS__) + +/** + * @def longBowTest + * @brief Terminate a LongBow Test Case signaling the given event if the condition is false. + * + * @param [in] testEventPointer + * @param [in] ... A printf format string following corresponding parameters. + */ +# define longBowTest(testEventPointer, ...) do { \ + longBowRuntime_EventEvaluation(testEventPointer); \ + longBowRuntime_EventTrigger(testEventPointer, \ + longBowLocation_Create(__FILE__, __func__, __LINE__), \ + "Test", __VA_ARGS__); \ + longjmp(longBowTestCaseAbort, SIGABRT); \ +} while (0) + +#include <LongBow/assertions.h> +#include <LongBow/debugging.h> +#include <LongBow/traps.h> +#endif // LongBow_runtime_h diff --git a/longbow/src/LongBow/stubs/execinfo.h b/longbow/src/LongBow/stubs/execinfo.h new file mode 100755 index 00000000..a6d6d407 --- /dev/null +++ b/longbow/src/LongBow/stubs/execinfo.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#ifndef LongBow_execinfo_h +#define LongBow_execinfo_h + +#define backtrace(...) (1) +#define backtrace_symbols(...) 0 +#define backtrace_symbols_fd(...) ((void) 0) + +#endif // LongBow_execinfo_h diff --git a/longbow/src/LongBow/test/.gitignore b/longbow/src/LongBow/test/.gitignore new file mode 100644 index 00000000..182506bc --- /dev/null +++ b/longbow/src/LongBow/test/.gitignore @@ -0,0 +1,30 @@ +*.gcda +*.gcno +*.gcov +*.longbow +*.log +test_longBow_ArrayList +test_longBow_Backtrace +test_longBow_Config +test_longBow_Debug +test_longBow_Fixture +test_longBow_Memory +test_longBow_Main +test_longBow_OpenFile +test_longBow_Report +test_longBow_Runner +test_longBow_Runtime +test_longBow_Status +test_longBow_TestCase +test_longBow_TestCaseClipBoard +test_longBow_Properties +test_longBow_UnitTesting +test_longBow_Empty +test_longBow_File +test_longBow_String +test_longBow_Thread +test_longBow_CommandLineOptions +test_longBow_Expected +test_assertions +test_longBow_Properties +test_longBow_MeasureTime diff --git a/longbow/src/LongBow/test/CMakeLists.txt b/longbow/src/LongBow/test/CMakeLists.txt new file mode 100644 index 00000000..5eba0444 --- /dev/null +++ b/longbow/src/LongBow/test/CMakeLists.txt @@ -0,0 +1,52 @@ +# Enable gcov output for the tests +add_definitions(--coverage) +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage") + + +macro(AddTest testFile) + add_executable(${ARGV0} ${ARGV0}.c) + target_link_libraries(${ARGV0} longbow longbow-ansiterm) + add_test(${ARGV0} ${ARGV0}) + set_target_properties(${ARGV0} PROPERTIES FOLDER Test) +endmacro(AddTest) + +set(TestsExpectedToFail + test_longBow_Expected; +) + +# test_assertions; + +set(TestsExpectedToPass + test_MemoryLeaks; + test_longBow_ArrayList; + test_longBow_Config; + test_longBow_Fixture; + test_longBow_Memory; + test_longBow_Location; + test_fixtureConfiguration; + test_longBow_Backtrace; + test_longBow_CommandLineOptions; + test_longBow_Debug; + test_longBow_Main; + test_longBow_MeasureTime; + test_longBow_OpenFile; + test_longBow_Properties; + test_longBow_Runner; + test_longBow_Runtime; + test_longBow_Status; + test_longBow_String; + test_longBow_TestCase; + test_longBow_TestCaseClipBoard; + test_longBow_UnitTesting + ) + +foreach(test ${TestsExpectedToPass}) + AddTest(${test}) +endforeach() + +foreach(test ${TestsExpectedToFail}) + AddTest(${test}) + set_tests_properties(${test} PROPERTIES WILL_FAIL TRUE) +endforeach() + + diff --git a/longbow/src/LongBow/test/test_MemoryLeaks.c b/longbow/src/LongBow/test/test_MemoryLeaks.c new file mode 100755 index 00000000..f5eb4160 --- /dev/null +++ b/longbow/src/LongBow/test/test_MemoryLeaks.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** * + */ +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <inttypes.h> + +#include "../private/longBow_Memory.h" + +LONGBOW_TEST_RUNNER(test_MemoryLeaks) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_MemoryLeaks) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_MemoryLeaks) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +// LONGBOW_RUN_TEST_CASE(Global, myTest); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, myTest) +{ +} + +int +main(int argc, char *argv[argc]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_MemoryLeaks); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + assertTrue(longBowMemory_OutstandingAllocations() == 0, "Memory leaks %" PRId64, longBowMemory_OutstandingAllocations()); + + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_assertions.c b/longbow/src/LongBow/test/test_assertions.c new file mode 100755 index 00000000..f20d0e5b --- /dev/null +++ b/longbow/src/LongBow/test/test_assertions.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/runtime.h> +#include <stdbool.h> + +int +main(int argc, char *argv[argc]) +{ + assertTrue(false, "Must fail."); +} diff --git a/longbow/src/LongBow/test/test_fixtureConfiguration.c b/longbow/src/LongBow/test/test_fixtureConfiguration.c new file mode 100755 index 00000000..92023f48 --- /dev/null +++ b/longbow/src/LongBow/test/test_fixtureConfiguration.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** * + */ +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(test_fixtureConfiguration) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_fixtureConfiguration) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_fixtureConfiguration) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_OPTIONS(Global, .enabled = false) +{ + LONGBOW_RUN_TEST_CASE(Global, myTest); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, myTest) +{ +} + +int +main(int argc, char *argv[argc]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_fixtureConfiguration); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_ArrayList.c b/longbow/src/LongBow/test/test_longBow_ArrayList.c new file mode 100644 index 00000000..5ce70885 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_ArrayList.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +#include <stdio.h> +#include <stdint.h> +#include <inttypes.h> + +#include "../private/longBow_ArrayList.h" +#include "../private/longBow_Memory.h" + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +LONGBOW_TEST_RUNNER(longBow_ArrayList) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_ArrayList) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_ArrayList) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, CreateDestroy); + LONGBOW_RUN_TEST_CASE(Global, longBowArrayList_Add); +} + +uint64_t _setupAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _setupAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint64_t leaks = longBowMemory_OutstandingAllocations() - _setupAllocations; + if (leaks != 0) { + printf("leaks %" PRId64 " allocations.\n", leaks); + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, CreateDestroy) +{ + LongBowArrayList *list = longBowArrayList_Create((void (*)(void **))longBowMemory_Deallocate); + + longBowArrayList_Destroy(&list); +} + +LONGBOW_TEST_CASE(Global, longBowArrayList_Add) +{ + LongBowArrayList *list = longBowArrayList_Create((void (*)(void **))longBowMemory_Deallocate); + + char *thing = longBowMemory_StringCopy("name"); + longBowArrayList_Add(list, thing); + + longBowArrayList_Destroy(&list); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_ArrayList); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Backtrace.c b/longbow/src/LongBow/test/test_longBow_Backtrace.c new file mode 100755 index 00000000..40582b85 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Backtrace.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../longBow_Backtrace.h" + +#include <stdio.h> +#include "../testing.h" +#include <LongBow/private/longBow_Memory.h> + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +LONGBOW_TEST_RUNNER(longBow_Backtrace) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Backtrace) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Backtrace) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, LongBowBacktrace_ToString); + LONGBOW_RUN_TEST_CASE(Global, longBowBacktrace_Create); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, LongBowBacktrace_ToString) +{ + LongBowBacktrace *backtrace = longBowBacktrace_Create(100, 0); + char *result = longBowBacktrace_ToString(backtrace); + + assertNotNull(result, "Expected non-null result from LongBowBacktrace_ToString()"); + + longBowMemory_Deallocate((void **) &result); + longBowBacktrace_Destroy(&backtrace); +} + +LONGBOW_TEST_CASE(Global, longBowBacktrace_Create) +{ + LongBowBacktrace *backtrace = longBowBacktrace_Create(100, 0); + assertNotNull(backtrace, "Expected non-null result from longBowBacktrace_Create()"); + longBowBacktrace_Destroy(&backtrace); + assertNull(backtrace, "Expected LongBowBacktrace_Destroy() to set the pointer to null"); + + backtrace = longBowBacktrace_Create(100, 1); + longBowBacktrace_Destroy(&backtrace); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Backtrace); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_CommandLineOptions.c b/longbow/src/LongBow/test/test_longBow_CommandLineOptions.c new file mode 100755 index 00000000..b63375fe --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_CommandLineOptions.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** * + */ +#include <stdio.h> + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(test_longBow_CommandLineOptions) +{ + printf("test_longBow_CommandLineOptions\n"); + + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(testFixture); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_longBow_CommandLineOptions) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_longBow_CommandLineOptions) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(testFixture) +{ + printf(" testFixture\n"); + LONGBOW_RUN_TEST_CASE(testFixture, testCase); +} + +LONGBOW_TEST_FIXTURE_SETUP(testFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(testFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(testFixture, testCase) +{ + printf(" testCase\n"); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_longBow_CommandLineOptions); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Config.c b/longbow/src/LongBow/test/test_longBow_Config.c new file mode 100755 index 00000000..98589d32 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Config.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +#include <stdio.h> +#include <inttypes.h> + +#include <LongBow/longBow_Config.h> +#include "../private/longBow_Memory.h" + +LONGBOW_TEST_RUNNER(longBow_Config) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Config) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Config) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, CreateDestroy); +} + +uint64_t _setupAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _setupAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint64_t leaks = longBowMemory_OutstandingAllocations() - _setupAllocations; + if (leaks != 0) { + printf("leaks %" PRId64 " allocations.\n", leaks); + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, CreateDestroy) +{ + LongBowConfig *config = longBowConfig_Create(0, NULL, NULL); + + longBowConfig_Destroy(&config); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Config); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + if (longBowMemory_OutstandingAllocations() != 0) { + printf("%" PRId64 " allocation leaks.", longBowMemory_OutstandingAllocations()); + } + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Debug.c b/longbow/src/LongBow/test/test_longBow_Debug.c new file mode 100755 index 00000000..30805d4a --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Debug.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +LONGBOW_TEST_RUNNER(longBow_Debug) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Debug) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Debug) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Debug); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Expected.c b/longbow/src/LongBow/test/test_longBow_Expected.c new file mode 100755 index 00000000..7b49cb89 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Expected.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Expected) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Expected) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Expected) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ExpectFailure); + LONGBOW_RUN_TEST_CASE(Global, ExpectSuccess); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ExpectSuccess, .event = &LongBowAssertEvent) +{ + assertTrue(false, "This must be successful by failing."); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, ExpectFailure, .event = &LongBowAssertEvent) +{ + assertNull(NULL, "This must fail to fail."); +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Expected); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Fixture.c b/longbow/src/LongBow/test/test_longBow_Fixture.c new file mode 100644 index 00000000..599b4be5 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Fixture.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <stdio.h> +#include <inttypes.h> +#include <LongBow/testing.h> +#include <LongBow/private/longBow_Memory.h> + +LONGBOW_TEST_RUNNER(longBow_Fixture) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(CreateDestroy); + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Fixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Fixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(CreateDestroy) +{ + LONGBOW_RUN_TEST_CASE(CreateDestroy, LongBowTestFixture_Create_Destroy); +} + +LONGBOW_TEST_FIXTURE_SETUP(CreateDestroy) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(CreateDestroy) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(CreateDestroy, LongBowTestFixture_Create_Destroy) +{ + uint64_t allocations = longBowMemory_OutstandingAllocations(); + LongBowTestRunner *runner = longBowTestRunner_Create("runner", NULL, NULL, NULL); + + LongBowTestFixture *fixture = longBowTestFixture_Create(runner, "fixture", NULL, NULL, NULL); + assertNotNull(fixture, "Expected non-null result from LongBowTestFixture_Create"); + longBowTestFixture_Destroy(&fixture); + longBowTestRunner_Destroy(&runner); + assertTrue(longBowMemory_OutstandingAllocations() == allocations, + "Memory leaks %" PRId64, longBowMemory_OutstandingAllocations()); +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowTestFixture_GetRunner); + LONGBOW_RUN_TEST_CASE(Global, longBowTestFixture_GetClipBoard); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + LongBowTestRunner *runner = longBowTestRunner_Create("testRunner", NULL, NULL, NULL); + LongBowTestFixture *fixture = longBowTestFixture_Create(runner, "testFixture", NULL, NULL, NULL); + + longBowClipBoard_Set(testClipBoard, "runner", runner); + longBowClipBoard_Set(testClipBoard, "fixture", fixture); + longBowTestCase_SetClipBoardData(testCase, fixture); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + LongBowTestFixture *fixture = longBowTestCase_GetClipBoardData(testCase); + + LongBowTestRunner *runner = longBowTestFixture_GetRunner(fixture); + + longBowTestRunner_Destroy(&runner); + longBowTestFixture_Destroy(&fixture); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowTestFixture_GetRunner) +{ + LongBowTestRunner *xrunner = longBowClipBoard_Get(testClipBoard, "runner"); + LongBowTestFixture *xfixture = longBowClipBoard_Get(testClipBoard, "fixture"); + LongBowTestFixture *fixture = longBowTestCase_GetClipBoardData(testCase); + LongBowTestRunner *runner = longBowTestFixture_GetRunner(fixture); + + assertTrue(xrunner == runner, "Expected runner to be equal."); + assertTrue(xfixture == fixture, "Expected runner to be equal."); + + assertNotNull(runner, "Expected the test runner to not be null"); +} + +LONGBOW_TEST_CASE(Global, longBowTestFixture_GetClipBoard) +{ + LongBowTestFixture *fixture = longBowTestCase_GetClipBoardData(testCase); + LongBowClipBoard *clipboard = longBowTestFixture_GetClipBoard(fixture); + assertNotNull(clipboard, "Expected non-null result from longBowTestFixture_GetClipBoard"); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Fixture); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Location.c b/longbow/src/LongBow/test/test_longBow_Location.c new file mode 100755 index 00000000..9ed77079 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Location.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Location) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Location) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Location) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Location); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Main.c b/longbow/src/LongBow/test/test_longBow_Main.c new file mode 100755 index 00000000..f8be93ed --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Main.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <stdio.h> +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Main) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Main) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Main) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowMain); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowMain) +{ + LongBowStatus expected = LONGBOW_STATUS_SUCCEEDED; + + int actual = longBowMain(0, NULL, NULL); + assertTrue(expected == actual, "Expected %d, actual %d", expected, actual); +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Main); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_MeasureTime.c b/longbow/src/LongBow/test/test_longBow_MeasureTime.c new file mode 100644 index 00000000..294c7c60 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_MeasureTime.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Runner. +#include "../longBow_MeasureTime.c" + +#include <stdint.h> +#include <inttypes.h> +#include <LongBow/private/longBow_Memory.h> +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(longBow_MeasureTime) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified here, but every test must be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Static); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_MeasureTime) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_MeasureTime) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime_CountDown); + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime_Report); + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime_Start); + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime_Stop); + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime_Destroy); + LONGBOW_RUN_TEST_CASE(Global, longBowMeasureTime); +} + +uint64_t _setupAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _setupAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint64_t leaks = longBowMemory_OutstandingAllocations() - _setupAllocations; + if (leaks != 0) { + printf("%s leaks %" PRId64 " allocations.\n", longBowTestCase_GetFullName(testCase), leaks); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime_CountDown) +{ + LongBowMeasureTime *measure = longBowMeasureTime_Start(1); + assertTrue(measure->iterations == 1, "Expected iterations to be 1, actual %d", measure->iterations); + + longBowMeasureTime_CountDown(measure); + assertTrue(measure->iterations == 0, "Expected iterations to be 0, actual %d", measure->iterations); + + longBowMeasureTime_Destroy(&measure); +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime_Report) +{ + LongBowMeasureTime *measure = longBowMeasureTime_Start(1); + assertTrue(measure->iterations == 1, "Expected iterations to be 1, actual %d", measure->iterations); + + longBowMeasureTime_Report(measure, __FILE__, __func__, __LINE__); + + longBowMeasureTime_Destroy(&measure); +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime_Start) +{ + LongBowMeasureTime *measure = longBowMeasureTime_Start(1); + assertNotNull(measure, "Expected longBowMeasureTime_Start to return non-NULL result."); + + longBowMeasureTime_Destroy(&measure); +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime_Stop) +{ + LongBowMeasureTime *measure = longBowMeasureTime_Start(1); + assertNotNull(measure, "Expected longBowMeasureTime_Start to return non-NULL result."); + sleep(2); + longBowMeasureTime_Stop(measure); + + uint64_t nanos = longBowMeasureTime_GetNanoseconds(measure); + assertTrue(nanos >= 1000000000ULL, "Expected more than 1,000,000 ns to have elapsed."); + + longBowMeasureTime_Destroy(&measure); +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime_Destroy) +{ + LongBowMeasureTime *measure = longBowMeasureTime_Start(1); + assertNotNull(measure, "Expected longBowMeasureTime_Start to return non-NULL result."); + + longBowMeasureTime_Destroy(&measure); + assertNull(measure, "Expected longBowMeasureTime_Destroy to NULL the pointer."); +} + +LONGBOW_TEST_CASE(Global, longBowMeasureTime) +{ + longBowMeasureTime(1) + { + sleep(2); + } +} + +LONGBOW_TEST_FIXTURE(Static) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_MeasureTime); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Memory.c b/longbow/src/LongBow/test/test_longBow_Memory.c new file mode 100755 index 00000000..d1943860 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Memory.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ +#include "../private/longBow_Memory.c" + +#include <LongBow/unit-test.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(test_longBow_Memory) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_longBow_Memory) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_longBow_Memory) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowMemory_Allocate); + LONGBOW_RUN_TEST_CASE(Global, longBowMemory_Reallocate); + LONGBOW_RUN_TEST_CASE(Global, longBowMemory_StringCopy); +} + +static uint64_t _setupAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _setupAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (longBowMemory_OutstandingAllocations() != _setupAllocations) { + printf("%s Memory leak\n", longBowTestCase_GetFullName(testCase)); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowMemory_Allocate) +{ + void *memory = longBowMemory_Allocate(10); + assertNotNull(memory, "Return value from longBowMemory_Allocate(10) cannot be NULL."); + longBowMemory_Deallocate((void **) &memory); + assertNull(memory, "longBowMemory_Deallocated must NULL the pointer."); +} + +LONGBOW_TEST_CASE(Global, longBowMemory_Reallocate) +{ + void *memory = longBowMemory_Allocate(10); + assertNotNull(memory, "Return value from longBowMemory_Allocate(10) cannot be NULL."); + + memory = longBowMemory_Reallocate(memory, 100); + assertNotNull(memory, "Return value from longBowMemory_Reallocate cannot be NULL."); + + longBowMemory_Deallocate((void **) &memory); + assertNull(memory, "longBowMemory_Deallocated must NULL the pointer."); +} + +LONGBOW_TEST_CASE(Global, longBowMemory_Reallocate_NULL) +{ + void *memory = longBowMemory_Reallocate(NULL, 100); + assertNotNull(memory, "Return value from longBowMemory_Reallocate cannot be NULL."); + + longBowMemory_Deallocate((void **) &memory); + assertNull(memory, "longBowMemory_Deallocated must NULL the pointer."); +} + +LONGBOW_TEST_CASE(Global, longBowMemory_StringCopy) +{ + char *expected = "Hello World"; + + char *actual = longBowMemory_StringCopy(expected); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + longBowMemory_Deallocate((void **) &actual); +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_longBow_Memory); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_OpenFile.c b/longbow/src/LongBow/test/test_longBow_OpenFile.c new file mode 100755 index 00000000..2a881fdb --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_OpenFile.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> +#include "../private/longBow_ArrayList.h" +#include "../private/longBow_OpenFile.h" + +LONGBOW_TEST_RUNNER(longBow_Files) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Files) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Files) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBow_OpenFiles); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBow_OpenFiles) +{ + LongBowArrayList *list = longBowOpenFile_CurrentlyOpen(); + assertTrue(longBowArrayList_Length(list) > 0, "Expected the number of open files to be > 0"); + + longBowArrayList_Destroy(&list); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Files); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Properties.c b/longbow/src/LongBow/test/test_longBow_Properties.c new file mode 100755 index 00000000..736a8141 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Properties.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** * + */ +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +#include <stdio.h> +#include <inttypes.h> + +#include <LongBow/longBow_Properties.h> +#include "../private/longBow_Memory.h" + +LONGBOW_TEST_RUNNER(test_longBow_Properties) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_longBow_Properties) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_longBow_Properties) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, CreateDestroy); + LONGBOW_RUN_TEST_CASE(Global, longBowProperties_Set); + LONGBOW_RUN_TEST_CASE(Global, longBowProperties_Get); + LONGBOW_RUN_TEST_CASE(Global, longBowProperties_Length); + LONGBOW_RUN_TEST_CASE(Global, longBowProperties_Exists); +} + +static uint64_t _setupAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _setupAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + uint64_t leaks = longBowMemory_OutstandingAllocations() - _setupAllocations; + if (leaks != 0) { + printf("%s leaks %" PRId64 " allocations.\n", longBowTestCase_GetFullName(testCase), leaks); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, CreateDestroy) +{ + LongBowProperties *properties = longBowProperties_Create(); + longBowProperties_Destroy(&properties); +} + +LONGBOW_TEST_CASE(Global, longBowProperties_Set) +{ + LongBowProperties *properties = longBowProperties_Create(); + longBowProperties_Set(properties, "name", "value"); + longBowProperties_Destroy(&properties); +} + +LONGBOW_TEST_CASE(Global, longBowProperties_Get) +{ + LongBowProperties *properties = longBowProperties_Create(); + char *expected = "value"; + longBowProperties_Set(properties, "name", expected); + + const char *actual = longBowProperties_Get(properties, "name"); + + assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual); + longBowProperties_Destroy(&properties); +} + +LONGBOW_TEST_CASE(Global, longBowProperties_Length) +{ + LongBowProperties *properties = longBowProperties_Create(); + assertTrue(longBowProperties_Length(properties) == 0, "Expected empty longBowProperties to be 0 length"); + + char *expected = "value"; + longBowProperties_Set(properties, "name", expected); + assertTrue(longBowProperties_Length(properties) == 1, "Expected longBowProperties to be 1 length"); + + const char *actual = longBowProperties_Get(properties, "name"); + + assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual); + longBowProperties_Destroy(&properties); +} + +LONGBOW_TEST_CASE(Global, longBowProperties_Exists) +{ + char *expected = "value"; + + LongBowProperties *properties = longBowProperties_Create(); + assertFalse(longBowProperties_Exists(properties, expected), "Expected longBowProperties_Exists to be false"); + + longBowProperties_Set(properties, "name", expected); + assertTrue(longBowProperties_Exists(properties, "name"), "Expected longBowProperties_Exists to be true"); + + longBowProperties_Destroy(&properties); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_longBow_Properties); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Runner.c b/longbow/src/LongBow/test/test_longBow_Runner.c new file mode 100755 index 00000000..7d7492e9 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Runner.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Runner) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Runner) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Runner) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Runner); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Runtime.c b/longbow/src/LongBow/test/test_longBow_Runtime.c new file mode 100755 index 00000000..b9d963e9 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Runtime.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Runtime) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Runtime) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Runtime) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowRuntime_StackTrace); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowRuntime_StackTrace) +{ + longBowRuntime_StackTrace(1); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Runtime); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_Status.c b/longbow/src/LongBow/test/test_longBow_Status.c new file mode 100755 index 00000000..a1c01eb2 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_Status.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_Status) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_Status) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_Status) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowStatus_ToString); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowStatus_ToString) +{ + char *expected; + char *actual; + + expected = "Succeeded"; + actual = longBowStatus_ToString(LONGBOW_STATUS_SUCCEEDED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Warning"; + actual = longBowStatus_ToString(LongBowStatus_WARNED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Tear Down Warning"; + actual = longBowStatus_ToString(LongBowStatus_TEARDOWN_WARNED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Skipped"; + actual = longBowStatus_ToString(LONGBOW_STATUS_SKIPPED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Unimplemented"; + actual = longBowStatus_ToString(LongBowStatus_UNIMPLEMENTED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Impotent"; + actual = longBowStatus_ToString(LongBowStatus_IMPOTENT); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Failed"; + actual = longBowStatus_ToString(LONGBOW_STATUS_FAILED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Stopped"; + actual = longBowStatus_ToString(LongBowStatus_STOPPED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Tear Down Failed"; + actual = longBowStatus_ToString(LONGBOW_STATUS_TEARDOWN_FAILED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Setup Failed"; + actual = longBowStatus_ToString(LONGBOW_STATUS_SETUP_FAILED); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + expected = "Memory Leak"; + actual = longBowStatus_ToString(LONGBOW_STATUS_MEMORYLEAK); + assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual); + free(actual); + + actual = longBowStatus_ToString(LongBowStatus_SIGNALLED + 1); + assertNotNull(actual, "Expected longBowStatus_ToString to return non-null value"); + free(actual); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_Status); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_String.c b/longbow/src/LongBow/test/test_longBow_String.c new file mode 100755 index 00000000..96750706 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_String.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + + +// Include the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Runner. +#include <stdio.h> +#include <inttypes.h> + +#include "../private/longBow_String.c" + +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(longBow_String) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified here, but every test must be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Static); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_String) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_String) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowString_Create); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Append); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Append_Append); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Format); + + LONGBOW_RUN_TEST_CASE(Global, longBowString_StartsWith_True); + LONGBOW_RUN_TEST_CASE(Global, longBowString_StartsWith_False); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Tokenise); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Tokenise_empty); + LONGBOW_RUN_TEST_CASE(Global, longBowString_Tokenise_NULL); + LONGBOW_RUN_TEST_CASE(Global, longBowString_CoreDump); +} + +static uint64_t _outstandingAllocations; + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + _outstandingAllocations = longBowMemory_OutstandingAllocations(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + if (longBowMemory_OutstandingAllocations() > _outstandingAllocations) { + printf("%s: memory leak\n", longBowTestCase_GetName(testCase)); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowString_Create) +{ + LongBowString *string = longBowString_Create(128); + assertNotNull(string, "Expected non-NULL result from longBowString_Create"); + + longBowString_Destroy(&string); + assertNull(string, "Expected the instance pointer to be NULL after longBowString_Destroy"); +} + +LONGBOW_TEST_CASE(Global, longBowString_Append) +{ + char *expected = "Hello World"; + LongBowString *string = longBowString_Create(0); + longBowString_Append(string, expected); + + assertTrue(strcmp(expected, string->buffer) == 0, + "Expected buffer to contain '%s', actual '%s'", expected, string->buffer); + longBowString_Destroy(&string); +} + +LONGBOW_TEST_CASE(Global, longBowString_Append_Append) +{ + char *expected = "Hello World"; + LongBowString *string = longBowString_Create(0); + longBowString_Append(string, "Hello"); + longBowString_Append(string, " "); + longBowString_Append(string, "World"); + + assertTrue(strcmp(expected, string->buffer) == 0, + "Expected buffer to contain '%s', actual '%s'", expected, string->buffer); + longBowString_Destroy(&string); +} + +LONGBOW_TEST_CASE(Global, longBowString_Format) +{ + char *expected = "Hello World"; + LongBowString *string = longBowString_Create(0); + longBowString_Format(string, "%s", expected); + + assertTrue(strcmp(expected, string->buffer) == 0, + "Expected buffer to contain '%s', actual '%s'", expected, string->buffer); + longBowString_Destroy(&string); +} + +LONGBOW_TEST_CASE(Global, longBowString_StartsWith_True) +{ + bool actual = longBowString_StartsWith("abcde", "abc"); + assertTrue(actual, "Expected true"); +} + +LONGBOW_TEST_CASE(Global, longBowString_StartsWith_False) +{ + bool actual = longBowString_StartsWith("abcde", "ayz"); + + assertFalse(actual, "Expected false"); +} + +LONGBOW_TEST_CASE(Global, longBowString_Tokenise) +{ + LongBowArrayList *actual = longBowString_Tokenise("--t.x=10", "-="); + + assertTrue(strcmp("t.x", longBowArrayList_Get(actual, 0)) == 0, + "Expected first token to be t.x, actual %s", (char *) longBowArrayList_Get(actual, 0)); + assertTrue(strcmp("10", longBowArrayList_Get(actual, 1)) == 0, + "Expected first token to be 10, actual %s", (char *) longBowArrayList_Get(actual, 1)); + + longBowArrayList_Destroy(&actual); +} + +LONGBOW_TEST_CASE(Global, longBowString_Tokenise_empty) +{ + LongBowArrayList *actual = longBowString_Tokenise("", "-="); + + assertTrue(longBowArrayList_Length(actual) == 0, "Expected zero length LongBowArrayList, actual %zd", longBowArrayList_Length(actual)); + + longBowArrayList_Destroy(&actual); +} + +LONGBOW_TEST_CASE(Global, longBowString_Tokenise_NULL) +{ + LongBowArrayList *actual = longBowString_Tokenise(NULL, "-="); + + assertTrue(longBowArrayList_Length(actual) == 0, "Expected zero length LongBowArrayList, actual %zd", longBowArrayList_Length(actual)); + + longBowArrayList_Destroy(&actual); +} + +LONGBOW_TEST_CASE(Global, longBowString_CoreDump) +{ + //assertFalse(true, "foo"); +} + +LONGBOW_TEST_FIXTURE(Static) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_String); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_TestCase.c b/longbow/src/LongBow/test/test_longBow_TestCase.c new file mode 100755 index 00000000..3fe6c8e1 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_TestCase.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/testing.h> + +LONGBOW_TEST_RUNNER(longBow_TestCase) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_TestCase) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_TestCase) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, ExpectEvent); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, ExpectEvent) +{ +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_TestCase); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_TestCaseClipBoard.c b/longbow/src/LongBow/test/test_longBow_TestCaseClipBoard.c new file mode 100755 index 00000000..521a817b --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_TestCaseClipBoard.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <inttypes.h> +#include <LongBow/testing.h> +#include <LongBow/private/longBow_Memory.h> + +LONGBOW_TEST_RUNNER(longBow_TestCaseClipBoard) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_TestCaseClipBoard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_TestCaseClipBoard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowTestCaseClipBoard_CreateDestroy); + LONGBOW_RUN_TEST_CASE(Global, longBowTestCaseClipBoard_Get); + LONGBOW_RUN_TEST_CASE(Global, longBowTestCaseClipBoard_Set); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, longBowTestCaseClipBoard_CreateDestroy) +{ + uint64_t allocations = longBowMemory_OutstandingAllocations(); + char *shared = longBowMemory_StringCopy("shared data"); + + LongBowTestCaseClipBoard *clipboard = longBowTestCaseClipBoard_Create(shared); + assertNotNull(clipboard, "Expected non-null result from longBowTestCaseClipBoard_Create"); + + longBowTestCaseClipBoard_Destroy(&clipboard); + longBowMemory_Deallocate((void **) &shared); + + assertTrue(longBowMemory_OutstandingAllocations() == allocations, + "Memory leaks %" PRId64, longBowMemory_OutstandingAllocations()); +} + +LONGBOW_TEST_CASE(Global, longBowTestCaseClipBoard_Get) +{ + char *shared = longBowMemory_StringCopy("shared data"); + + LongBowTestCaseClipBoard *clipboard = longBowTestCaseClipBoard_Create(shared); + + char *actual = longBowTestCaseClipBoard_Get(clipboard); + assertTrue(strcmp(shared, actual) == 0, "Expected %s, actual %s", shared, actual); + + longBowTestCaseClipBoard_Destroy(&clipboard); + longBowMemory_Deallocate((void **) &shared); +} + +LONGBOW_TEST_CASE(Global, longBowTestCaseClipBoard_Set) +{ + char *shared = longBowMemory_StringCopy("shared data"); + + LongBowTestCaseClipBoard *clipboard = longBowTestCaseClipBoard_Create(shared); + + char *expected = longBowMemory_StringCopy("expected"); + + longBowTestCaseClipBoard_Set(clipboard, expected); + char *actual = longBowTestCaseClipBoard_Get(clipboard); + assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual); + + longBowTestCaseClipBoard_Destroy(&clipboard); + longBowMemory_Deallocate((void **) &shared); + longBowMemory_Deallocate((void **) &expected); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_TestCaseClipBoard); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/test/test_longBow_UnitTesting.c b/longbow/src/LongBow/test/test_longBow_UnitTesting.c new file mode 100755 index 00000000..de0f9c56 --- /dev/null +++ b/longbow/src/LongBow/test/test_longBow_UnitTesting.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../testing.h" + +LONGBOW_TEST_RUNNER(longBow_UnitTesting) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(longBow_UnitTesting) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(longBow_UnitTesting) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, longBowUnitTesting_AssertCompareToContract); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +static int +compareTo(const void *a, const void *b) +{ + if (a == NULL) { + if (b == NULL) { + return 0; + } + return -1; + } else { + if (b == NULL) { + return 1; + } + } + + return strcmp(a, b); +} + +LONGBOW_TEST_CASE(Global, longBowUnitTesting_AssertCompareToContract) +{ + char *exemplar = "exemplar"; + void *equivalent[] = { + "exemplar", + NULL, + }; + void *lesser[] = { + "exempla", + NULL, + }; + void *greater[] = { + "exemplarr", + "fexemplarr", + NULL, + }; + + bool expected = true; + bool actual = longBowUnitTesting_AssertCompareToContract(compareTo, exemplar, equivalent, lesser, greater); + + assertTrue(expected == actual, "Expected %d, actual %d", expected, actual); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(longBow_UnitTesting); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/LongBow/testing.h b/longbow/src/LongBow/testing.h new file mode 100755 index 00000000..d789094c --- /dev/null +++ b/longbow/src/LongBow/testing.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file testing.h + * @ingroup testing + * @brief LongBow testing functionality. + * + */ +#ifndef LongBow_testing_h +#define LongBow_testing_h + +#include <LongBow/longBow_Compiler.h> +#include <LongBow/longBow_ClipBoard.h> +#include <LongBow/longBow_Properties.h> +#include <LongBow/unit-test.h> +#endif // LongBow_testing_h diff --git a/longbow/src/LongBow/tests.h b/longbow/src/LongBow/tests.h new file mode 100644 index 00000000..24146d4c --- /dev/null +++ b/longbow/src/LongBow/tests.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file tests.h + * @brief LongBow Utility Tests + * + * + */ +#ifndef LongBow_tests_h +#define LongBow_tests_h + +#include <stdbool.h> +#include <stdlib.h> + +/** + * Test if an address is aligned. + * + * Return true of the given address is aligned according to alignment. + * The value for alignment must be a power of 2. + * + * @param [in] address The adddress to test. + * @param [in] alignment A power of 2 greater than or equal to sizeof(void *). + * + * @return true if the address is aligned. + * @return false if the address is not aligned. + */ +bool longBowRuntime_TestAddressIsAligned(const void *address, size_t alignment); + +/** + * Induce a core-dump + * + */ +void longBowRuntime_CoreDump(void); +#endif // LongBow_tests_h diff --git a/longbow/src/LongBow/traps.h b/longbow/src/LongBow/traps.h new file mode 100755 index 00000000..e6c68d65 --- /dev/null +++ b/longbow/src/LongBow/traps.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file traps.h + * @ingroup runtime + * @brief Runtime and Test Traps + * + */ +#ifndef LongBow_traps_h +#define LongBow_traps_h + +/** + * @def trapUnrecoverableState + * @brief Lay a trap to report an unrecoverable state in program execution. + * + * @param ... A printf(3) format string of explanitory text and values + */ +#define trapUnrecoverableState(...) \ + longBowTrap(&LongBowTrapUnrecoverableState, "Unrecoverable State: " __VA_ARGS__) + +/** + * @def trapNotImplemented + * @brief Lay a trap to report and abort an unimplemented capability. + * + * @param ... A printf(3) format string of explanitory text and values + */ +#define trapNotImplemented(...) \ + longBowTrap(&LongBowTrapNotImplemented, "Feature not implemented: " __VA_ARGS__) + +/** + * @def trapIllegalValue + * @brief Trap an illegal value. + * + * To used for capturing parameter validation, for example. + * + * @param [in] argumentName A name that is displayed in the report message. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapIllegalValue(argumentName, ...) \ + longBowTrap(&LongBowTrapIllegalValue, "Illegal value for '" #argumentName "': " __VA_ARGS__) + +/** + * @def trapIllegalValueIf + * @brief Trap an illegal value if a condition is met. + * + * To used for the case where the value is valid + * (eg. it is the correct type) but is an illegal value to be used in the context in which it was attempted to be applied. + * + * @param [in] condition A logical expression that if true, induces this trap. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapIllegalValueIf(condition, ...) \ + longBowTrapIf(&LongBowTrapIllegalValue, condition, "Illegal value: " __VA_ARGS__) + +/** + * @def trapInvalidValueIf + * @brief Trap an invalid value if a condition is met. + * + * Used for capturing parameter validation. + * For example, a composite value (C struct) has an internally invalid state for example. + * + * @param [in] condition A logical expression that if true, induces this trap. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapInvalidValueIf(condition, ...) \ + longBowTrapIf(&LongBowTrapInvalidValue, condition, "Invalid value: " __VA_ARGS__) + +/** + * @def trapOutOfBounds + * @brief Trap an out-of-bounds condition on an index. + * + * @param [in] index The index that is out of bounds. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapOutOfBounds(index, ...) \ + longBowTrap(&LongBowTrapOutOfBounds, "Element out of bounds, " #index ": " __VA_ARGS__) + +/** + * @def trapOutOfBoundsIf + * @brief Trap an out-of-bounds condition for a specific value. + * + * @param [in] condition A logical expression that if true, induces this trap. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapOutOfBoundsIf(condition, ...) \ + longBowTrapIf(&LongBowTrapOutOfBounds, condition, "Out of bounds: " __VA_ARGS__) + +/** + * @def trapOutOfMemory + * @brief Signal that no more memory could be allocated. + * + * @param ... A printf format string and accompanying parameters. + */ +#define trapOutOfMemory(...) \ + longBowTrap(&LongBowTrapOutOfMemoryEvent, "Out of memory. " __VA_ARGS__) + +/** + * @def trapOutOfMemoryIf + * @brief Signal that no more memory could be allocated. + * + * @param [in] condition A logical expression that if true, induces this trap. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapOutOfMemoryIf(condition, ...) \ + longBowTrapIf(&LongBowTrapOutOfMemoryEvent, condition, "Out of memory. " __VA_ARGS__) + +/** + * @def trapUnexpectedState + * @brief Signal that an unexpected or inconsistent state was encountered. + * + * @param ... A printf format string and accompanying parameters. + */ +#define trapUnexpectedState(...) \ + longBowTrap(&LongBowTrapUnexpectedStateEvent, "Unexpected state. " __VA_ARGS__) + +/** + * @def trapUnexpectedStateIf + * @brief If the given condition is true, signal that an unexpected state was encountered . + * + * @param [in] condition A logical expression that if true, induces this trap. + * @param [in] ... A printf format string and associated parameters. + */ +#define trapUnexpectedStateIf(condition, ...) \ + longBowTrapIf(&LongBowTrapUnexpectedStateEvent, condition, "Unexpected state: " __VA_ARGS__) + +/** + * @def trapCoreDump + * @brief Send a SIGTRAP to the current process. + */ +#define trapCoreDump() \ + kill(0, SIGTRAP); + +/** + * @def trapCannotObtainLock + * @brief Signal that a lock could not be obtained. + * + * @param ... A printf format string and accompanying parameters. + */ +#define trapCannotObtainLock(...) \ + longBowTrap(&LongBowTrapCannotObtainLockEvent, "Cannot obtain lock " __VA_ARGS__) + +/** + * @def trapCannotObtainLock + * @brief Signal that a lock could not be obtained. + * + * @param ... A printf format string and accompanying parameters. + */ +#define trapCannotObtainLockIf(condition, ...) \ + longBowTrapIf(&LongBowTrapCannotObtainLockEvent, condition, "Cannot obtain lock " __VA_ARGS__) + +#endif diff --git a/longbow/src/LongBow/unit-test.h b/longbow/src/LongBow/unit-test.h new file mode 100644 index 00000000..3f282671 --- /dev/null +++ b/longbow/src/LongBow/unit-test.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * @file unit-test.h + * @ingroup testing + * @brief LongBow Unit Test Support. + * + * Every LongBow Test module must include this file as the first included file <em>after</em> + * including the files necessary for the functions under test. + * + */ +#ifndef UNIT_TEST_H_ +#define UNIT_TEST_H_ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <setjmp.h> +#include <unistd.h> + +#include <LongBow/runtime.h> + +#include <LongBow/longBow_Compiler.h> +#include <LongBow/longBow_UnitTest.h> +#include <LongBow/longBow_Status.h> +#include <LongBow/longBow_Config.h> +#include <LongBow/longBow_UnitTesting.h> +#include <LongBow/longBow_Runtime.h> +#include <LongBow/longBow_Main.h> +#include <LongBow/longBow_TestRunner.h> +#include <LongBow/longBow_TestFixture.h> +#include <LongBow/longBow_TestCase.h> +#include <LongBow/longBow_SubProcess.h> +#include <LongBow/longBow_TestCaseMetaData.h> +#include <LongBow/Reporting/longBowReport_Testing.h> + +#define longBowUnused(declaration) declaration __attribute__((unused)) + +/** + * Test Runner setup function called before the invocation of the Test Fixtures associated with this Test Runner. + * + * Every Test Runner has a set-up and tear-down function that are invoked + * just before and just after the execution of each test case function. + * This function performs setup common for all fixtures to use. + * If this function must return a valid `LongBowStatus` value. + * + * @param [in] runnerName A valid identifier for the Test Runner. + * + * @return A LongBowStatus indicating the status of the setup. + * + * Example: + * @code + * // An example of a minimal Test Runner Setup function. + * + * LONGBOW_TEST_RUNNER_SETUP(LongBow) + * { + * return LONGBOW_STATUS_SUCCEEDED; + * } + * @endcode + * + * @see LONGBOW_TEST_RUNNER_TEARDOWN + */ +#define LONGBOW_TEST_RUNNER_SETUP(runnerName) \ + LongBowStatus longBowUnitTest_RunnerSetupName(runnerName) (LongBowTestRunner * testRunner); \ + LongBowStatus longBowUnitTest_RunnerSetupName(runnerName) (longBowUnused(LongBowTestRunner * testRunner)) + +/** + * @brief The post-processing for a Test Runner called after all fixtures have been run. + * + * The Test Runner calls this function once after all the Test Fixtures are run. + * + * This function is responsible for resetting or restoring external resources previously setup by the + * Test Runner Setup function and which may have been modified by any test fixture or test case. + * If this function must return a valid LongBowStatus value. + * + * @see LONGBOW_TEST_RUNNER_SETUP + * @param [in] longBowRunnerName A valid identifier for the Test Runner. + */ +#define LONGBOW_TEST_RUNNER_TEARDOWN(longBowRunnerName) \ + LongBowStatus longBowUnitTest_RunnerTearDownName(longBowRunnerName) (LongBowTestRunner * testRunner); \ + LongBowStatus longBowUnitTest_RunnerTearDownName(longBowRunnerName) (longBowUnused(LongBowTestRunner * testRunner)) + +/** + * @brief Define a Test Case Runner with the given name. + * The name must be valid syntax for a C identifier and will be used to compose a longer C function name. + * + * The resulting function that this macro defines specifies the parameter `LongBowTestRunner *testRunner` + * which is a pointer to a LongBowTestRunner instance for the Test Runner. + * + * @param [in] testRunnerName A valid identifier for the Test Runner. + */ +#define LONGBOW_TEST_RUNNER(testRunnerName) \ + void longBowUnitTest_RunnerName(testRunnerName) (const LongBowTestRunner * testRunner); \ + void longBowUnitTest_RunnerName(testRunnerName) (const LongBowTestRunner * testRunner) + +/** + * @brief Create an allocated instance of a LongBowTestRunner that must be destroyed via `longBowTestRunner_Destroy` + * + * @param [in] testRunnerName A valid identifier for the Test Runner. (see LONGBOW_TEST_RUNNER) + * @return The return value from longBowTestRunner_Create + */ +#define LONGBOW_TEST_RUNNER_CREATE(testRunnerName) \ + longBowTestRunner_Create(#testRunnerName, \ + longBowUnitTest_RunnerSetupName(testRunnerName), \ + (LongBowTestRunnerRun *) longBowUnitTest_RunnerName(testRunnerName), \ + longBowUnitTest_RunnerTearDownName(testRunnerName)) + +#define LongBowTestRunner_Create(_runnerName_) \ + longBowTestRunner_Create(#_runnerName_, longBowUnitTest_RunnerSetupName(_runnerName_), \ + longBowUnitTest_RunnerName(_runnerName_), longBowUnitTest_RunnerTearDownName(_runnerName_)) + +/** + * @brief Run the LongBow test fixture with the specified `fixtureName`. + * + * @param [in] LongBowTestFixtureName A valid C identifier + * @see LONGBOW_TEST_FIXTURE(fixtureName) + */ +#define LONGBOW_RUN_TEST_FIXTURE(LongBowTestFixtureName) \ + do { \ + extern LONGBOW_TEST_FIXTURE_SETUP(LongBowTestFixtureName); \ + extern LONGBOW_TEST_FIXTURE_TEARDOWN(LongBowTestFixtureName); \ + extern LongBowUnitTest_FixtureDeclaration(LongBowTestFixtureName); \ + extern LongBowTestFixtureConfig longBowUnitTest_FixtureConfigName(LongBowTestFixtureName); \ + longBowTestFixture_Run(testRunner, \ + #LongBowTestFixtureName, \ + &longBowUnitTest_FixtureConfigName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureSetupName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureTearDownName(LongBowTestFixtureName)); \ + } while (0) + + + +/** + * @brief Define a test fixture with the given `fixtureName`. + * + * The value for `fixtureName` must be a valid syntax for a C identifier. + * + * @param [in] fixtureName A valid syntax for a C identifier. + */ +#define LongBowUnitTest_FixtureDeclaration(_fixtureName_) \ + void longBowUnitTest_FixtureName(_fixtureName_)(longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture)) + +/** + * @brief The default value for the expected result of a LongBow Fixture. + */ +#define LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT .enabled = true + +/** + * @brief Define a test fixture with the given `fixtureName`. + * + * The value for `fixtureName` must be valid syntax for a C identifier. + * + * The resulting function that this macro defines specifies the parameter `LongBowTestFixture *LongBowTestFixture` + * which is a pointer to a `LongBowTestFixture` instance for the Test Fixture. + * + * @param [in] fixtureName + */ +#define LONGBOW_TEST_FIXTURE(fixtureName) \ + LONGBOW_TEST_FIXTURE_OPTIONS(fixtureName, LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT) + +#define LONGBOW_TEST_FIXTURE_OPTIONS(fixtureName, ...) \ + LongBowCompiler_IgnoreInitializerOverrides \ + LongBowTestFixtureConfig longBowUnitTest_FixtureConfigName(fixtureName) = { LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT, __VA_ARGS__ }; \ + LongBowCompiler_WarnInitializerOverrides \ + extern LONGBOW_TEST_FIXTURE_SETUP(fixtureName); \ + extern LONGBOW_TEST_FIXTURE_TEARDOWN(fixtureName); \ + LongBowUnitTest_FixtureDeclaration(fixtureName); \ + LongBowUnitTest_FixtureDeclaration(fixtureName) + + +/** + * The pre-processing for a test fixture called before each invocation of a test case in the same fixture. + * + * This function is responsible for setting up the common programmatic state for each test case in the same fixture. + * If this function returns `false` the corresponding test case is skipped. + * + * The resulting function that this macro defines specifies the parameters + * `LongBowTestFixture *testFixture` and `LongBowTestCase *testCase` + * + * @param [in] fixtureName + * + * @see LONGBOW_TEST_FIXTURE_TEARDOWN + */ +#define LONGBOW_TEST_FIXTURE_SETUP(fixtureName) \ + LongBowStatus longBowUnitTest_FixtureSetupName(fixtureName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(LongBowClipBoard * testClipBoard)) + +/** + * The post-processing for a test fixture called after each invocation of a test case in the same fixture. + * + * This function is responsible for resetting the common programmatic state for each test case in the same fixture. + * If this function returns `false` the corresponding test case is considered passed, but warned. + * + * The resulting function that this macro defines specifies the parameters + * `LongBowTestFixture *testFixture` and `LongBowTestCase *testCase` + * + * @param [in] fixtureName + * + * @see `LONGBOW_TEST_FIXTURE_SETUP` + */ +#define LONGBOW_TEST_FIXTURE_TEARDOWN(fixtureName) \ + LongBowStatus longBowUnitTest_FixtureTearDownName(fixtureName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(LongBowClipBoard * testClipBoard)) + +/** + * @brief Defines the canonical name of a LongBow Test Case meta data. + * + * @param fixtureName The name of the Test Fixture that the Test Case belongs to. + * @param testCaseName The name of the Test Case. + */ +#define longBowTestCase_MetaDataDeclaration(_testFixtureName_, _testCaseName_) \ + TestCase ## _testFixtureName_ ## _testCaseName_ ## MetaData + +/** + * @brief Forward declare a LongBow Test Case. + * + * @param fixtureName The name of the Test Fixture that the Test Case belongs to. + * @param testCaseName The name of the Test Case. + */ +#define longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName) \ + void longBowUnitTest_CaseName(fixtureName, testCaseName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(const LongBowClipBoard * testClipBoard), longBowUnused(jmp_buf longBowTestCaseAbort)) + +/** + * @brief The default value for the expected result of a LongBow Test Case. + */ +#define LongBowUnitTest_TestCaseDefaultExpectedResult .event = NULL, .status = LongBowStatus_DONTCARE + +/** + * Define a test case with the given `fixtureName` and `testCaseName`. + * + * The `fixtureName` must be the name of a defined fixture, see `LONGBOW_TEST_FIXTURE`. + * The `testCaseName` must be valid syntax for a C identifier. + * + * @param fixtureName + * @param testCaseName + * + * @code + * LONGBOW_TEST_CASE(MyFixture, MyTestCase) + * { + * assertTrue(true, "It lied to me!"); + * } + */ +#define LONGBOW_TEST_CASE(fixtureName, testCaseName) \ + LONGBOW_TEST_CASE_EXPECTS(fixtureName, testCaseName, LongBowUnitTest_TestCaseDefaultExpectedResult) + +/** + * Define a test case with the given `fixtureName` and `testCaseName` with an explictly specified status. + * + * The `fixtureName` must be the name of a defined fixture, see `LONGBOW_TEST_FIXTURE`. + * The `testCaseName` is the name of the Test Case and must be valid syntax for a C identifier. + * The variable number of subsequent arguments are a comma separated list of structure initialisers for the + * LongBowRuntimeResult structure. + * + * For example, the construct + * @code + * LONGBOW_TEST_CASE_EXPECTS(MyFixture, alwaysWarn, .event = &LongBowAssertEvent) + * @endcode + * defines the Long Bow Test case `alwaysWarn` that is within the Test Fixture named `MyFixture`. + * The expected termination is expected to be a `LongBowAssertEvent`, which means an assertion was triggered. + * + * If the termination status of the test must is equal to the specified status, + * the test will be signaled as `LONGBOW_STATUS_SUCCESS, otherwise it will be LONGBOW_STATUS_FAILED. + * + * @param fixtureName + * @param testCaseName + */ +#define LONGBOW_TEST_CASE_EXPECTS(fixtureName, testCaseName, ...) \ + LongBowCompiler_IgnoreInitializerOverrides \ + LongBowTestCaseMetaData longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName) = \ + { .fileName = __FILE__, .functionName = #testCaseName, .lineNumber = __LINE__, \ + .expectedResult = { LongBowUnitTest_TestCaseDefaultExpectedResult, __VA_ARGS__ } }; \ + LongBowCompiler_WarnInitializerOverrides \ + longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName); \ + longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName) + + +/** + * @brief Run a test case defined for the named <code>fixtureName</code> and <code>testCaseName</code>. + * + * This is executed within a LongBow test fixture function and references the function's + * <code>LongBowTestFixture</code> parameter. + * + * @param [in] fixtureName + * @param [in] testCaseName + * + * @see LONGBOW_TEST_CASE + */ +#define LONGBOW_RUN_TEST_CASE(fixtureName, testCaseName) \ + extern longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName); \ + extern LongBowTestCaseMetaData longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName); \ + longBowTestCase_Run(#testCaseName, testFixture, longBowUnitTest_CaseName(fixtureName, testCaseName), \ + &longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName)) + +/** + * @brief Configure and run a set of LongBowTestRunner instances + * + * @param [in] argc The number of elements in the @p argv array. + * @param [in] argv An array of nul-terminated C-strings. + * + * Example Usage: + * @code + * int + * main(int argc, char *argv[argc]) + * { + * LongBowTestRunner *testRunner1 = LONGBOW_TEST_RUNNER_CREATE(MyTestRunner); + * LongBowTestRunner *testRunner2 = LONGBOW_TEST_RUNNER_CREATE(MyOtherTestRunner); + * + * int exitStatus = longBowMain(argc, argv, testRunner, testRunner2); + * + * longBowTestRunner_Destroy(&testRunner1); + * longBowTestRunner_Destroy(&testRunner2); + * exit(exitStatus); + * } + * @endcode + */ +#ifdef LongBow_DISABLE_ASSERTIONS +/* 77 is the exit status for a skipped test when run with automake generated Makefiles */ +# define longBowMain(argc, argv, ...) \ + 77 +#else +# define longBowMain(argc, argv, ...) \ + longBowMain_Impl(argc, argv, __VA_ARGS__, NULL) +#endif + +/** + * @brief Configure and run a set of `LongBowTestRunner` instances + * + * @param [in] argc The number of elements in the @p argv array. + * @param [in] argv An NULL terminated list of pointers to `LongBowTestRunner` instances. + * + * Example Usage: + * @code + * int + * main(int argc, char *argv[argc]) + * { + * LongBowTestRunner *testRunner1 = LONGBOW_TEST_RUNNER_CREATE(MyTestRunner); + * LongBowTestRunner *testRunner2 = LONGBOW_TEST_RUNNER_CREATE(MyOtherTestRunner); + * + * int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner, testRunner2); + * + * longBowTestRunner_Destroy(&testRunner1); + * longBowTestRunner_Destroy(&testRunner2); + * exit(exitStatus); + * } + * @endcode + */ +#define LONGBOW_TEST_MAIN(argc, argv, ...) \ + longBowMain(argc, argv, __VA_ARGS__, NULL) + +/** + * @brief Skip this test case + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testSkip(...) do { \ + longBowTest(&LongBowTestSkippedEvent, "Skipped " __VA_ARGS__); \ +} while (0) + +/** + * @brief Terminate the test indicating that the test is unimplemented. + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testUnimplemented(...) do { \ + longBowTest(&LongBowTestUnimplementedEvent, "Unimplemented test " __VA_ARGS__); \ +} while (0) + +/** + * @brief Issue a warning and terminate with the `LONGBOW_TESTCASE_WARNED` code. + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testWarn(...) \ + do { longBowTest(&LongBowTestEvent, "Warning " __VA_ARGS__); } while (0) + +/** + * @brief assert the Equals Contract for the given function. + * + * @param [in] function The function under test. + * @param [in] x The pivotal value which must not be NULL. + * @param [in] y A value that must be perfectly equal to x and z, but neither x nor z. + * @param [in] z A value that must be perfectly equal to x and y, but neither x nor y. + * @param [in] ... A variable number of values that are unequal to x. + */ +#define assertEqualsContract(function, x, y, z, ...) \ + assertTrue(longBowUnitTesting_AssertEqualsContract((bool (*)(void *, void *))function, x, y, z, __VA_ARGS__, NULL), "Failed Equals Contract"); + +/** + * @brief assert the Compare To Contract for the given function. + * + * @param [in] function The function under test. + * @param [in] value The pivotal value under test. + * @param [in] equality A NULL terminated array of values that are all equivalent to `value`. + * @param [in] lesser A NULL terminated array of values that are all less than `value`. + * @param [in] greater A NULL terminated array of values that are all greater than `value`. + * @return `true` if the evalutation is successful. + * @see assertCompareToContract() + */ +#define assertCompareToContract(function, value, equality, lesser, greater) \ + assertTrue(longBowUnitTesting_AssertCompareToContract((int (*)(const void *, const void *))function, value, (void *) equality, (void *) lesser, (void *) greater), "Failed CompareTo Contract"); +#endif // UNIT_TEST_H_ diff --git a/longbow/src/examples/.gitignore b/longbow/src/examples/.gitignore new file mode 100644 index 00000000..1b4775c8 --- /dev/null +++ b/longbow/src/examples/.gitignore @@ -0,0 +1,5 @@ +*.gcno +*.gcda +*.dSYM +*.gcov +testLongBow diff --git a/longbow/src/examples/example1.c b/longbow/src/examples/example1.c new file mode 100755 index 00000000..31bbadbf --- /dev/null +++ b/longbow/src/examples/example1.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/* + * example1.c + * + */ + +#include <unistd.h> +#include <stdbool.h> +#include <signal.h> + +int +alwaysTrue() +{ + return true; +} + +int +alwaysFalse() +{ + return false; +} + +int +alwaysSignalled() +{ + kill(getpid(), SIGTERM); + return true; +} diff --git a/longbow/src/examples/minimal.c b/longbow/src/examples/minimal.c new file mode 100755 index 00000000..47f7e7fe --- /dev/null +++ b/longbow/src/examples/minimal.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/* + * minimal.c + * + */ + +int +alwaysSucceed() +{ + return 1; +} diff --git a/longbow/src/examples/pointer.c b/longbow/src/examples/pointer.c new file mode 100755 index 00000000..0a0fef95 --- /dev/null +++ b/longbow/src/examples/pointer.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <LongBow/runtime.h> +#include <unistd.h> +#include <string.h> + +void +function(char *pointer) +{ + assertNotNull(pointer, "The pointer cannot be NULL."); + + write(1, pointer, strlen(pointer)); +} + +int +main(int argc, char *argv[]) +{ + function(0); +} diff --git a/longbow/src/examples/require.c b/longbow/src/examples/require.c new file mode 100755 index 00000000..31055aa8 --- /dev/null +++ b/longbow/src/examples/require.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <stdio.h> +#include "../runtime.h" + +# define longBowAssert(eventPointer, condition, ...) \ + longBowRuntime_EventEvaluation(eventPointer); \ + if (longBowIsFalse(condition) && \ + (longBowRuntime_EventTrigger(eventPointer, longBowLocation_Create(__FILE__, longBow_function, __LINE__), #condition, __VA_ARGS__), true)) \ + for (; true; abort()) + + +int +main(int argc, char *argv[argc]) +{ + int condition = 1; + + longBowAssert(&LongBowAssertEvent, condition == 1, "Message %d", 2) + { + printf("Should not have Triggered\n"); + }; + longBowAssert(&LongBowAssertEvent, condition == 0, "Message %d", 2) + { + printf("Triggered\n"); + }; + + longBowAssert(&LongBowAssertEvent, condition == 0, "Message %d", 2); +} diff --git a/longbow/src/examples/testAssertion.c b/longbow/src/examples/testAssertion.c new file mode 100755 index 00000000..eb60db91 --- /dev/null +++ b/longbow/src/examples/testAssertion.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../runtime.h" + +int +main(int argc, char *argv[]) +{ + assertTrue(0, "Force this assertion."); +} diff --git a/longbow/src/examples/testClipboard.c b/longbow/src/examples/testClipboard.c new file mode 100755 index 00000000..1e6a5b94 --- /dev/null +++ b/longbow/src/examples/testClipboard.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * + */ +#include <stdio.h> +#include <string.h> + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(testClipboard) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(testClipboard) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, testClipboard); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + char *testData = strdup("Hello World"); + longBowTestCase_SetClipBoardData(testCase, testData, free); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, testClipboard) +{ + char *testData = longBowTestCase_GetClipBoardData(testCase); + printf("Shared state '%s'\n", testData); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(testClipboard); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/examples/testExample1.c b/longbow/src/examples/testExample1.c new file mode 100755 index 00000000..d26294a1 --- /dev/null +++ b/longbow/src/examples/testExample1.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <stdio.h> +#include "../unit-test.h" + +#include "example1.c" + +LONGBOW_TEST_RUNNER(example1) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); + LONGBOW_RUN_TEST_FIXTURE(Local); +} + +LONGBOW_TEST_RUNNER_SETUP(example1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(example1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, strlen); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); + LONGBOW_RUN_TEST_CASE(Global, alwaysSignalled); + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + assertTrue(alwaysFalse(), "This test must always fail.") + { + printf("And this is extra code that is executed when the assertion fails"); + } +} + +LONGBOW_TEST_CASE(Global, alwaysSignalled) +{ + kill(getpid(), SIGTERM); +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + assertTrue(alwaysTrue(), "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, strlen) +{ + assertNotNull(NULL, "Parameter must be a non-null char pointer."); +} + +LONGBOW_TEST_FIXTURE(Local) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Local) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(example1); + exit(longBowMain(argc, argv, testRunner, NULL)); +} diff --git a/longbow/src/examples/testLongBow.c b/longbow/src/examples/testLongBow.c new file mode 100755 index 00000000..7c1fd949 --- /dev/null +++ b/longbow/src/examples/testLongBow.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/* + * test_LongBow.c + * + */ + +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +#include <sys/errno.h> + +#include "../unit-test.h" + + +LONGBOW_TEST_RUNNER(LongBow) +{ + LONGBOW_RUN_TEST_FIXTURE(LongBowFixture); +} + +LONGBOW_TEST_RUNNER_SETUP(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(LongBow) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(LongBowFixture) +{ + LONGBOW_RUN_TEST_CASE(LongBowFixture, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(LongBowFixture, alwaysUnimplemented); + LONGBOW_RUN_TEST_CASE(LongBowFixture, alwaysImpotent); +} + +LONGBOW_TEST_FIXTURE_SETUP(LongBowFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(LongBowFixture) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(LongBowFixture, testErrno) +{ + errno = ENOENT; + assertTrue(0, "Errno test"); +} + +LONGBOW_TEST_CASE(LongBowFixture, alwaysSucceed) +{ + assertTrue(1, "alwaysSucceed"); +} + +LONGBOW_TEST_CASE(LongBowFixture, alwaysImpotent) +{ +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, testEvent, .event = &LongBowAssertEvent) +{ + assertTrue(0, "testEvent"); +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, alwaysFail, .status = LONGBOW_STATUS_FAILED, .event = &LongBowAssertEvent) +{ + assertTrue(0, "alwaysFail"); +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, alwaysSigTERM, .status = LONGBOW_STATUS_SIGNAL(SIGTERM)) +{ + kill(getpid(), SIGTERM); +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, alwaysSEGV, .event = &LongBowEventSIGSEGV) +{ + int *p = 0; + int i = *p; + printf("not used %d\n", i); +} + +LONGBOW_TEST_CASE(LongBowFixture, alwaysUnimplemented) +{ + testUnimplemented("alwaysUnimplemented"); +} + +LONGBOW_TEST_CASE(LongBowFixture, alwaysWarn) +{ + testWarn("alwaysWarn"); +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, alwaysSkip, .event = &LongBowTestSkippedEvent) +{ + testSkip("alwaysSkip"); +} + +LONGBOW_TEST_CASE_EXPECTS(LongBowFixture, alwaysTrap, .status = LONGBOW_STATUS_FAILED) +{ + trapNotImplemented("alwaysTrap"); +} + +LONGBOW_TEST_FIXTURE(TestTearDownWarning) +{ + LONGBOW_RUN_TEST_CASE(TestTearDownWarning, alwaysFail); + LONGBOW_RUN_TEST_CASE(TestTearDownWarning, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(TestTearDownWarning) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(TestTearDownWarning) +{ + return LONGBOW_STATUS_TEARDOWN_WARNED; +} + +LONGBOW_TEST_CASE(TestTearDownWarning, alwaysFail) +{ + assertTrue(0, "alwaysFail"); +} + +LONGBOW_TEST_CASE(TestTearDownWarning, alwaysSucceed) +{ + assertTrue(1, "alwaysSucceed"); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(LongBow); + int status = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + + exit(status); +} diff --git a/longbow/src/examples/testRunnerSkipped.c b/longbow/src/examples/testRunnerSkipped.c new file mode 100755 index 00000000..f071678d --- /dev/null +++ b/longbow/src/examples/testRunnerSkipped.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + */ + +#include <stdio.h> + +#include <LongBow/unit-test.h> + +LONGBOW_TEST_RUNNER(Example1) +{ + LONGBOW_RUN_TEST_FIXTURE(FixtureA); +} + +LONGBOW_TEST_RUNNER_SETUP(Example1) +{ + return LONGBOW_STATUS_SETUP_SKIPTESTS; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(Example1) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(FixtureA) +{ + LONGBOW_RUN_TEST_CASE(FixtureA, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(FixtureA) +{ + assertTrue(0, "This should have been skipped and never be called."); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(FixtureA) +{ + assertTrue(0, "This should have been skipped and never be called."); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(FixtureA, alwaysSucceed) +{ + assertTrue(0, "This should have been skipped and never be called."); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(Example1); + int status = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + + exit(status); +} diff --git a/longbow/src/examples/testTearDown.c b/longbow/src/examples/testTearDown.c new file mode 100755 index 00000000..183563d9 --- /dev/null +++ b/longbow/src/examples/testTearDown.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +/** + * + */ +#include <stdio.h> +#include <string.h> + +#include <LongBow/testing.h> +#include <LongBow/debugging.h> + +LONGBOW_TEST_RUNNER(testTearDown) +{ + LONGBOW_RUN_TEST_FIXTURE(Succeeded); + LONGBOW_RUN_TEST_FIXTURE(Warned); +} + +LONGBOW_TEST_RUNNER_SETUP(testTearDown) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(testTearDown) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Succeeded) +{ + LONGBOW_RUN_TEST_CASE(Succeeded, testTearDown); +} + +LONGBOW_TEST_FIXTURE_SETUP(Succeeded) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Succeeded) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Succeeded, testTearDown) +{ + assertTrue(true, ""); +} + + +LONGBOW_TEST_FIXTURE(Warned) +{ + LONGBOW_RUN_TEST_CASE(Warned, alwaysWarn); +} + +LONGBOW_TEST_FIXTURE_SETUP(Warned) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Warned) +{ + return LONGBOW_STATUS_TEARDOWN_WARNED; +} + +LONGBOW_TEST_CASE(Warned, alwaysWarn) +{ + assertTrue(true, ""); +} + + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(testTearDown); + int exitStatus = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/longbow/src/examples/testUnimplemented.c b/longbow/src/examples/testUnimplemented.c new file mode 100755 index 00000000..3ccf18d1 --- /dev/null +++ b/longbow/src/examples/testUnimplemented.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../unit-test.h" + +LONGBOW_TEST_RUNNER(Unimplemented) +{ + LONGBOW_RUN_TEST_FIXTURE(Unimplemented); +} + +LONGBOW_TEST_RUNNER_SETUP(Unimplemented) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(Unimplemented) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Unimplemented) +{ + LONGBOW_RUN_TEST_CASE(Unimplemented, Unimplemented); +} + +LONGBOW_TEST_FIXTURE_SETUP(Unimplemented) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Unimplemented) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Unimplemented, Unimplemented) +{ + testUnimplemented("Unimplemented"); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(Unimplemented); + int status = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + + exit(status); +} diff --git a/longbow/src/examples/test_minimal.c b/longbow/src/examples/test_minimal.c new file mode 100755 index 00000000..5089071c --- /dev/null +++ b/longbow/src/examples/test_minimal.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include "../unit-test.h" + +#include "minimal.c" + +LONGBOW_TEST_RUNNER(Example1) +{ + LONGBOW_RUN_TEST_FIXTURE(FixtureA); +} + +LONGBOW_TEST_RUNNER_SETUP(Example1) +{ + return true; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(Example1) +{ + return true; +} + +LONGBOW_TEST_FIXTURE(FixtureA) +{ + LONGBOW_RUN_TEST_CASE(FixtureA, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(FixtureA) +{ + return true; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(FixtureA) +{ + return true; +} + +LONGBOW_TEST_CASE(FixtureA, alwaysSucceed) +{ + assertTrue(alwaysSucceed(), "This must always succeed."); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(Example1); + int status = longBowMain(argc, argv, testRunner, NULL); + longBowTestRunner_Destroy(&testRunner); + + exit(status); +} diff --git a/longbow/src/examples/tutorial/.gitignore b/longbow/src/examples/tutorial/.gitignore new file mode 100644 index 00000000..fb63b40b --- /dev/null +++ b/longbow/src/examples/tutorial/.gitignore @@ -0,0 +1,3 @@ +test_tutorial11 +test_tutorial12 +test_tutorial13 diff --git a/longbow/src/examples/tutorial/test_tutorial1.c b/longbow/src/examples/tutorial/test_tutorial1.c new file mode 100644 index 00000000..311b5357 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial1.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" diff --git a/longbow/src/examples/tutorial/test_tutorial10.c b/longbow/src/examples/tutorial/test_tutorial10.c new file mode 100644 index 00000000..2eb62dc4 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial10.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTestRunner_Destroy(&testRunner); + exit(status); +} diff --git a/longbow/src/examples/tutorial/test_tutorial11.c b/longbow/src/examples/tutorial/test_tutorial11.c new file mode 100644 index 00000000..58d44ed4 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial11.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + bool result = alwaysFail(); + + assertTrue(result, "This test will fail."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTestRunner_Destroy(&testRunner); + exit(status); +} diff --git a/longbow/src/examples/tutorial/test_tutorial12.c b/longbow/src/examples/tutorial/test_tutorial12.c new file mode 100644 index 00000000..63a2dc52 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial12.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Static); + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + bool result = alwaysFail(); + + assertTrue(result, "This test will fail."); +} + + +LONGBOW_TEST_FIXTURE(Static) +{ + LONGBOW_RUN_TEST_CASE(Static, _privateFunction); +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Static, _privateFunction) +{ + bool result = _privateFunction(); + + assertTrue(result, "This test must always succeed."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTestRunner_Destroy(&testRunner); + exit(status); +} diff --git a/longbow/src/examples/tutorial/test_tutorial13.c b/longbow/src/examples/tutorial/test_tutorial13.c new file mode 100644 index 00000000..6d35c9b6 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial13.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Static); + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); + LONGBOW_RUN_TEST_CASE(Global, alwaysFail); + LONGBOW_RUN_TEST_CASE(Global, blowUp); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} + +LONGBOW_TEST_CASE(Global, alwaysFail) +{ + bool result = alwaysFail(); + + assertTrue(result, "This test will fail."); +} + +LONGBOW_TEST_CASE_EXPECTS(Global, blowUp, .event = &LongBowEventSIGSEGV) +{ + blowUp(); + + assertTrue(false, "This will not be executed"); +} + + +LONGBOW_TEST_FIXTURE(Static) +{ + LONGBOW_RUN_TEST_CASE(Static, _privateFunction); +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Static, _privateFunction) +{ + bool result = _privateFunction(); + + assertTrue(result, "This test must always succeed."); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(myTutorialTest); + int status = LONGBOW_TEST_MAIN(argc, argv, testRunner); + + longBowTestRunner_Destroy(&testRunner); + exit(status); +} diff --git a/longbow/src/examples/tutorial/test_tutorial2.c b/longbow/src/examples/tutorial/test_tutorial2.c new file mode 100644 index 00000000..68e1d39a --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial2.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> diff --git a/longbow/src/examples/tutorial/test_tutorial3.c b/longbow/src/examples/tutorial/test_tutorial3.c new file mode 100644 index 00000000..fb635846 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial3.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ +} diff --git a/longbow/src/examples/tutorial/test_tutorial4.c b/longbow/src/examples/tutorial/test_tutorial4.c new file mode 100644 index 00000000..b8461fe4 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial4.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} diff --git a/longbow/src/examples/tutorial/test_tutorial5.c b/longbow/src/examples/tutorial/test_tutorial5.c new file mode 100644 index 00000000..c51ba7ac --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial5.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} diff --git a/longbow/src/examples/tutorial/test_tutorial6.c b/longbow/src/examples/tutorial/test_tutorial6.c new file mode 100644 index 00000000..a87c2466 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial6.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} diff --git a/longbow/src/examples/tutorial/test_tutorial7.c b/longbow/src/examples/tutorial/test_tutorial7.c new file mode 100644 index 00000000..25601997 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial7.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} diff --git a/longbow/src/examples/tutorial/test_tutorial8.c b/longbow/src/examples/tutorial/test_tutorial8.c new file mode 100644 index 00000000..35fad611 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial8.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + diff --git a/longbow/src/examples/tutorial/test_tutorial9.c b/longbow/src/examples/tutorial/test_tutorial9.c new file mode 100644 index 00000000..c92fc459 --- /dev/null +++ b/longbow/src/examples/tutorial/test_tutorial9.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +* / + +#include "tutorial.c" + +#include <LongBow/unit-test.h> + + +LONGBOW_TEST_RUNNER(myTutorialTest) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +LONGBOW_TEST_RUNNER_SETUP(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_RUNNER_TEARDOWN(myTutorialTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, alwaysSucceed); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, alwaysSucceed) +{ + bool result = alwaysSucceed(); + + assertTrue(result, "This test must always succeed."); +} diff --git a/longbow/src/examples/tutorial/tutorial.c b/longbow/src/examples/tutorial/tutorial.c new file mode 100755 index 00000000..ff296423 --- /dev/null +++ b/longbow/src/examples/tutorial/tutorial.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * 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. + */ + +#include <unistd.h> +#include <stdbool.h> +#include <signal.h> + +static bool +_privateFunction() +{ + return true; +} + +bool +alwaysSucceed() +{ + return _privateFunction(); +} + +bool +alwaysFail() +{ + return false; +} + +bool +blowUp() +{ + char *p = 0; + *p = 0; + + return true; +} diff --git a/longbow/src/python/.gitignore b/longbow/src/python/.gitignore new file mode 100644 index 00000000..34921562 --- /dev/null +++ b/longbow/src/python/.gitignore @@ -0,0 +1,3 @@ +longbow-generate-about +longbow-code +longbow-preprocess diff --git a/longbow/src/python/.project b/longbow/src/python/.project new file mode 100644 index 00000000..fd327b61 --- /dev/null +++ b/longbow/src/python/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>LongBow-Python</name> + <comment></comment> + <projects> + <project>Longbow</project> + </projects> + <buildSpec> + <buildCommand> + <name>org.python.pydev.PyDevBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.python.pydev.pythonNature</nature> + </natures> +</projectDescription> diff --git a/longbow/src/python/.pydevproject b/longbow/src/python/.pydevproject new file mode 100644 index 00000000..f4a65975 --- /dev/null +++ b/longbow/src/python/.pydevproject @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?eclipse-pydev version="1.0"?> + +<pydev_project> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> +</pydev_project> diff --git a/longbow/src/python/CMakeLists.txt b/longbow/src/python/CMakeLists.txt new file mode 100644 index 00000000..157cda21 --- /dev/null +++ b/longbow/src/python/CMakeLists.txt @@ -0,0 +1,29 @@ +add_subdirectory(site-packages) + +install( FILES parc_uncrustify.cfg DESTINATION ${CMAKE_INSTALL_PREFIX}/etc ) + +macro(AddLongBowPythonScript scriptFile) + configure_file(${ARGV0}.py ${ARGV0} @ONLY) + install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${ARGV0} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +endmacro(AddLongBowPythonScript) + +set(ScriptList + longbow-doxygen-report + longbow-generate-about + longbow-preprocess + longbow-code + longbow-complexity-report + longbow-coverage-report + longbow-bytearray + longbow-ansigcov + longbow-name-report + longbow-size-report + longbow-style-report + longbow-test-run + longbow-test-suite + longbow-vocabulary-report + ) + +foreach(script ${ScriptList}) + AddLongBowPythonScript(${script}) +endforeach() diff --git a/longbow/src/python/longbow-ansigcov.py b/longbow/src/python/longbow-ansigcov.py new file mode 100755 index 00000000..c677ab2c --- /dev/null +++ b/longbow/src/python/longbow-ansigcov.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +import os +import subprocess +''' +This programme takes a previously generated LongBow production (see longbow-preprocess.py) as input +and generates corresponding C code as a template for a complete test runner for that production. +''' + +ansiRed = "\x1b[31m"; +ansiGreen = "\x1b[32m"; +ansiYellow = "\x1b[33;1m"; +ansiOrange = "\x1b[33m"; +ansiReset = "\x1b[0m"; + + +def ANSITerminal_printchars(color, chars): + if color == "red": + return ansiRed + chars + ansiReset + if color == "green": + return ansiGreen + chars + ansiReset + if color == "yellow": + return ansiYellow + chars + ansiReset + if color == "orange": + return ansiOrange + chars + ansiReset + return chars + + +class LongBowAnsi: + def __init__(self, input=sys.stdin): + self.input = input + return + + def tokenise(self, line): + fields = line.split(":", 2) + fields[0] = fields[0].strip() + return fields + + def colourise(self): + lines = self.input.read().splitlines() + for line in lines: + fields = self.tokenise(line) + if len(fields) == 3: + if fields[0] == "#####": + print ANSITerminal_printchars("red", fields[1]), ANSITerminal_printchars("red", fields[2]) + pass + elif fields[0] == "$$$$$": + print ANSITerminal_printchars("yellow", fields[1]), ANSITerminal_printchars("yellow", fields[2]) + pass + else: + print ANSITerminal_printchars("green", fields[1]), ANSITerminal_printchars("green", fields[2]) + pass + pass + pass + return + + +if __name__ == '__main__': + outputFileName = None + + if len(sys.argv) != 2: + print "Usage: longbow-ansigov.py file.gcov" + sys.exit(1) + + with open(sys.argv[1], 'r') as f: + longBowAnsi = LongBowAnsi(f) + longBowAnsi.colourise() + f.close() + + pass diff --git a/longbow/src/python/longbow-bytearray.py b/longbow/src/python/longbow-bytearray.py new file mode 100755 index 00000000..30adfda3 --- /dev/null +++ b/longbow/src/python/longbow-bytearray.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +import os + +def indent(count): + for i in range(0, count/2): + print " ", + return + +def print_interstitialspace(index): + if ((index + 1) % 8) == 0: + print " ", + if ((index + 1) % 16) == 0: + print "" + indent(4) + pass + +def printarray(array): + i = 0 + for c in array: + print "0x%02x," % (c), + print_interstitialspace(i) + i = i + 1 + pass + + return + +if __name__ == '__main__': + with open(sys.argv[1], 'r') as f: + + bytes = bytearray(f.read()) + print len(bytes) + print "unsigned char bytes[] = {" + indent(4) + printarray(bytes) + print "\n};"; + pass + + f.close() diff --git a/longbow/src/python/longbow-code.py b/longbow/src/python/longbow-code.py new file mode 100755 index 00000000..8d5a72b6 --- /dev/null +++ b/longbow/src/python/longbow-code.py @@ -0,0 +1,208 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +import os +import subprocess +''' +This programme takes a previously generated LongBow production (see longbow-preprocess.py) as input +and generates corresponding C code as a template for a complete test runner for that production. +''' + +def sourceFileNameToShortName(sourceFileName): + ''' + Given a path to a source file, return the name without any path components or suffix after the first '.' (inclusive). + ''' + name = os.path.basename(sourceFileName) + return name.split(".")[0] + +def canonicalizeFunctionName(functionName): + ''' + Given a function name that contains the initial '_' character, + strip it and return a canonicalised form of the same name suitable for invoking from a C source file. + + This used to translate the typical function name mangling by the C compiler, + where foo() becomes _foo in the object file symbol table. + ''' + if functionName[0] == "_": + functionName = functionName[1:] + return functionName + +class LongBowTestGenerator: + def __init__(self, output=sys.stdout): + self.output = output + return + + def generateCode(self, testProduction): + testRunnerName = testProduction["name"] + sourceFileName = testProduction["files"]["sourceFile"] + objectFileName = testProduction["files"]["objectFile"] + + self.filePrologue() + self.testRunnerPrologue(sourceFileName, objectFileName, testRunnerName, testProduction["testFixtures"]) + + for testFixture in testProduction["testFixtures"]: + fixtures = self.generateTestFixture(testProduction, testFixture) + pass + + self.testRunnerEpilogue(sourceFileName, objectFileName, testRunnerName, testProduction["testFixtures"]) + return + + def filePrologue(self): + self.output.write("/*\n") + self.output.write(" *\n") + self.output.write(" */\n") + self.output.write("\n") + return + + def testRunnerPrologue(self, sourceFileName, objectFileName, testRunnerName, testFixtures): + self.output.write("// Include the file(s) containing the functions to be tested.\n") + self.output.write("// This permits internal static functions to be visible to this Test Runner.\n") + self.output.write("#include \"%s\"\n" % (sourceFileName)) + self.output.write("\n") + self.output.write("#include <LongBow/unit-test.h>\n") + self.output.write("\n") + self.output.write("LONGBOW_TEST_RUNNER(%s)\n" % (testRunnerName)) + self.output.write("{\n") + self.output.write(" // The following Test Fixtures will run their corresponding Test Cases.\n") + self.output.write(" // Test Fixtures are run in the order specified here, but every test must be idempotent.\n") + self.output.write(" // Never rely on the execution order of tests or share state between them.\n") + for testFixture in testFixtures: + self.output.write(" LONGBOW_RUN_TEST_FIXTURE(%s);\n" % (testFixture["name"])) + pass + self.output.write("}\n") + self.output.write("\n" ) + self.output.write("// The Test Runner calls this function once before any Test Fixtures are run.\n") + self.output.write("LONGBOW_TEST_RUNNER_SETUP(%s)\n" % (testRunnerName)) + self.output.write("{\n") + self.output.write(" return LONGBOW_STATUS_SUCCEEDED;\n") + self.output.write("}\n") + self.output.write("\n") + self.output.write("// The Test Runner calls this function once after all the Test Fixtures are run.\n") + self.output.write("LONGBOW_TEST_RUNNER_TEARDOWN(%s)\n" % (testRunnerName)) + self.output.write("{\n") + self.output.write(" return LONGBOW_STATUS_SUCCEEDED;\n") + self.output.write("}\n") + self.output.write("\n") + return + + def testRunnerEpilogue(self, sourceFileName, objectFileName, testRunnerName, testFixtures): + self.output.write("int\n") + self.output.write("main(int argc, char *argv[])\n") + self.output.write("{\n") + self.output.write(" LongBowTestRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(%s);\n" % (testRunnerName)) + self.output.write(" int exitStatus = longBowMain(argc, argv, testRunner, NULL);\n"); + self.output.write(" longBowTestRunner_Destroy(&testRunner);\n"); + self.output.write(" exit(exitStatus);\n"); + self.output.write("}\n") + return + + def generateTestFixture(self, testProduction, testFixture): + testFixtureName = testFixture["name"] + + sourceFileName = testProduction["files"]["sourceFile"] + objectFileName = testProduction["files"]["objectFile"] + + self.testFixturePrologue(sourceFileName, objectFileName, testFixtureName, testFixture["testSuites"]) + + for testSuite in testFixture["testSuites"]: + self.generateTestSuite(testProduction, testFixture, testSuite) + pass + + self.testFixtureEpilogue(testProduction, testFixture, testSuite) + return [ testFixtureName ] + + def testFixturePrologue(self, sourceFileName, objectFileName, testFixtureName, testSuites): + self.output.write("LONGBOW_TEST_FIXTURE(%s)\n" % (testFixtureName)) + self.output.write("{\n") + for testSuite in testSuites: + for testCase in testSuite["testCases"]: + self.output.write(" LONGBOW_RUN_TEST_CASE(%s, %s);\n" % (testFixtureName, testCase)) + pass + pass + self.output.write("}\n") + self.output.write("\n") + self.output.write("LONGBOW_TEST_FIXTURE_SETUP(%s)\n" % (testFixtureName)) + self.output.write("{\n") + self.output.write(" return LONGBOW_STATUS_SUCCEEDED;\n") + self.output.write("}\n") + self.output.write("\n") + self.output.write( "LONGBOW_TEST_FIXTURE_TEARDOWN(%s)\n" % (testFixtureName)) + self.output.write("{\n") + self.output.write(" return LONGBOW_STATUS_SUCCEEDED;\n") + self.output.write("}\n") + self.output.write("\n") + return + + def testFixtureEpilogue(self, testProduction, testFixture, testSuite): + return + + def generateTestSuite(self, testProduction, testFixture, testSuite): + for testCase in testSuite["testCases"]: + self.generateTestCase(testProduction, testFixture, testCase) + return + + def generateTestCase(self, testProduction, testFixture, testCase): + self.output.write("LONGBOW_TEST_CASE(%s, %s)\n" % (testFixture["name"], testCase)) + self.output.write("{\n") + self.output.write(" testUnimplemented(\"\");\n") + self.output.write("}\n") + self.output.write("\n") + return + +def getProductionSchema(fileName): + ''' + Get the "production" schema produced by the preprocessor. + ''' + f = open(fileName, "r") + text = f.read() + f.close() + return eval(text) + +def canonicalOutputFileName(production): + outputFileName = "test_" + sourceFileNameToShortName(production["files"]["sourceFile"]) + ".c" + return outputFileName + +def canonicalOutput(outputFileName): + if outputFileName == None: + return sys.stdout + open(outputFileName) + +if __name__ == '__main__': + ''' +@(#) longbow-code @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. + ''' + outputFileName = None + + if len(sys.argv) != 2: + print "Usage: longbow-code file.longbow" + sys.exit(1) + + production = getProductionSchema(sys.argv[1]) + + if outputFileName == None: + outputFileName = canonicalOutputFileName(production) + + if os.path.exists(outputFileName): + print "Refusing to overwrite the existing '%s'." % (outputFileName) + sys.exit(1) + + outputFile = open(outputFileName, 'w') + + generator = LongBowTestGenerator(outputFile) + generator.generateCode(production) + pass diff --git a/longbow/src/python/longbow-complexity-report.py b/longbow/src/python/longbow-complexity-report.py new file mode 100755 index 00000000..81ddcf72 --- /dev/null +++ b/longbow/src/python/longbow-complexity-report.py @@ -0,0 +1,213 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import argparse +import itertools +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +import LongBow +try: + import hfcca +except ImportError: + print "HFCCA not found. You need to download hfcca.py and place it in a location" + print "where this script (python) can find it." + print "You can find a compatible version of hfcca at: " + print " https://headerfile-free-cyclomatic-complexity-analyzer.googlecode.com/files/hfcca.py" + print "And place it at: @INSTALL_PYTHON_DIR@" + print + print "... however, you should have run the ccnx-post-install script" + print " (from the ccnx distribution you got this from)" + sys.exit(1) + +def computeComplexityScore(complexity): + score = min(100.0 * abs(1.0 - float(complexity - 5) / 50.0), 100.0) + return score + +def csvFunctionResult(file, function): + score = computeComplexityScore(function.cyclomatic_complexity) + string = "complexity,%s,%s,%d,%d,%.2f" % (file.filename, function.name, function.start_line, function.cyclomatic_complexity, score) + + LongBow.scorePrinter([90, 80], score, string) + return function.cyclomatic_complexity + +def csvFileComplexity(file): + score = computeComplexityScore(file.average_CCN) + string = "complexity,%s,,,%.2f,%.2f" % (file.filename, file.average_CCN, score) + LongBow.scorePrinter([90, 80], score, string) + return + +def csvFunction(fileInformationList): + for fileInformation in fileInformationList: + complexities = map(lambda function: csvFunctionResult(fileInformation, function), fileInformation) + return + +def csvSummary(fileInformationList): + map(lambda file: csvFileComplexity(file), fileInformationList) + return + + +def textFunctionResult(file, function, maxFileNameLength, maxFunctionNameLength): + score = computeComplexityScore(function.cyclomatic_complexity) + format = "%-" + str(maxFileNameLength) + "s %-" + str(maxFunctionNameLength) + "s %6d %2d %6.2f" + string = format % (file.filename, function.name, function.start_line, function.cyclomatic_complexity, score) + + LongBow.scorePrinter([90, 80], score, string) + return function.cyclomatic_complexity + +def textFileComplexity(file, maxFileNameLength): + score = computeComplexityScore(file.average_CCN) + string = ("%-" + str(maxFileNameLength) + "s %6.2f %6.2f") % (file.filename, file.average_CCN, score) + LongBow.scorePrinter([90, 80], score, string) + return + +def computeMaxFileNameLength(fileInformationList): + result = 0 + for fileInformation in fileInformationList: + if len(fileInformation.filename) > result: + result = len(fileInformation.filename) + return result + +def computeMaxFunctionNameLength(fileInformationList): + result = 0 + for fileInformation in fileInformationList: + if len(fileInformation.filename) > result: + result = len(fileInformation.filename) + return result + +def textFunction(fileInformationList): + maxFileNameLength = max(map(lambda fileInformation: len(fileInformation.filename), fileInformationList)) + maxFunctionNameLength = max(map(lambda fileInformation: max(map(lambda function: len(function.name), fileInformation)), fileInformationList)) + + for fileInformation in fileInformationList: + complexities = map(lambda function: textFunctionResult(fileInformation, function, maxFileNameLength, maxFunctionNameLength), fileInformation) + return + +def textSummary(fileInformationList): + maxFileNameLength = max(map(lambda fileInformation: len(fileInformation.filename), fileInformationList)) + map(lambda file: textFileComplexity(file, maxFileNameLength), fileInformationList) + return +# +# Recompute the file's average complexity as a floating point number. +def recomputeFileComplexity(fileInformation): + complexities = map(lambda function: function.cyclomatic_complexity, fileInformation) + if len(complexities) > 0: + sum = reduce(lambda sum, complex: sum + complex, complexities) + fileInformation.average_CCN = float(sum) / len(fileInformation) + else: + fileInformation.average_CCN = 0 + return fileInformation.average_CCN + +def recomputeFilesComplexity(fileInformationList): + return map(lambda fileInformation: recomputeFileComplexity(fileInformation), fileInformationList) + +def computeAverage(fileInformationList): + cyclomaticComplexity = map(lambda fileInformation : fileInformation.average_CCN, fileInformationList) + sum = reduce(lambda sum, x: sum + x, cyclomaticComplexity) + return float(sum) / float(len(cyclomaticComplexity)) + +def main(argv): + desc = '''longbow-complexity-report @VERSION@ @DATE@ + All Rights Reserved. Use is subject to license terms. + +Print the cyclomatic complexity of functions and files. + +The option --function displays the file name, function name, +line number of the function, the cyclomatic complexity and a score ranging from 0 to 100. + +The default option --summary displays the file name, +the average cyclomatic complexity of all functions in the file and +a score ranging from 0 to 100. + +Input is either from a list of files supplied as command line parameters, +or as a list of newline separated file names read from standard input. +Output is a plain text (default) or comma-separated-value (CSV). + +Examples: + +% longbow-complexity-report *.[ch] + +Report conformance of the .c and .h files specified as command line parameters. + +% longbow-complexity-report - +Report conformance of the .c and .h files read from standard input, one line per file. + +$ longbow-complexity-report parc_JSON.c +parc_JSON.c 2.27 100.00 +$ +$ echo parc_JSON.c | longbow-complexity-report -o csv - +complexity,parc_JSON.c,,,2.27,100.00 +$ +''' + + parser = argparse.ArgumentParser(prog='longbow-complexity-report', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + parser.add_argument('-s', '--summary', default=False, action="store_true", help="print the average complexity of each target file.") + parser.add_argument('-f', '--function', default=False, action="store_true", help="print the complexity of each function in each target file.") + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, help="read the list of files from standard input rather than the command line.") + parser.add_argument('-a', '--average', default=False, action="store_true", required=False, help="display only the simple average of the average complexity of each target file.") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="the output format: \"text\" or \"csv\"") + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + targets = [] + + if args.stdin: + for line in sys.stdin: + t = line.strip() + if (len(t) > 0): + targets.append(t) + else: + targets = args.files + + if (len(targets) == 0): + print >> sys.stderr, "Error: No files to analyze. See %s -h" % (sys.argv[0]) + sys.exit(1) + + # If nothing was specified, print the summary as a default + if args.summary == False and args.function == False and args.average == False: + args.summary = True + + options, arguments = hfcca.createHfccaCommandLineParser().parse_args(args=[argv[0]]) + result = hfcca.analyze(targets, options) + + # Convert from that iterator to a simple list... + fileInformationList = map(lambda x : x, result) + + recomputeFilesComplexity(fileInformationList) + + if args.function: + if args.output == "text": + textFunction(fileInformationList) + else: + csvFunction(fileInformationList) + + if args.summary: + if args.output == "text": + textSummary(fileInformationList) + else: + csvSummary(fileInformationList) + + if args.average: + print "%.2f" % computeAverage(fileInformationList) + +if __name__ == "__main__": + ''' +@(#) longbow-complexity-report @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. +''' + main(sys.argv) diff --git a/longbow/src/python/longbow-coverage-report.py b/longbow/src/python/longbow-coverage-report.py new file mode 100755 index 00000000..4a0a86ab --- /dev/null +++ b/longbow/src/python/longbow-coverage-report.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +import argparse + +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +sys.path.append("../site-packages/longbow/") +import CoverageReport + + +if __name__ == '__main__': + ''' +@(#) longbow-coverage-report @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. +''' + description = ''' +longbow-coverage-report @VERSION@ @DATE@ +All Rights Reserved. Use is subject to license terms. + +Report on the code coverage of tests. + +The source files or executables to analyse are supplied as command line parameters, +or as a list of newline separated file names read from standard input. + +Output is plain-text (default --output text) or a CSV file (--output csv) +reporting the results. + +Results are: + An average of all files specified (--average) + A one line summary of all files specified (--summary) + A listing of the original source file, colorized showing tested and non-tested lines. + ''' + parser = argparse.ArgumentParser(prog='longbow-coverage-report', + formatter_class=argparse.RawDescriptionHelpFormatter, + description=description) + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, + help="Read the list of files from standard input.") + parser.add_argument('-s', '--summary', default=False, action="store_true", required=False, + help="Display the score for each file (excluding test source files).") + parser.add_argument('-a', '--average', default=False, action="store_true", required=False, + help="Display the average score for all C source files (excluding test source files).") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, + help="Set the output format: \"text\" or \"csv\"") + parser.add_argument('-v', '--visual', default=False, action="store_true", required=False, + help="Colorize the original source code showing coverage") + parser.add_argument('-x', '--explain', default=False, action="store_true", required=False, + help="Display information about the collection of coverage information (guru mode).") + parser.add_argument('-d', '--distribution', default="[95, 90]", action="store", required=False, type=str, + help="A list containing the score distributions for pretty-printing. Default [95, 90]") + parser.add_argument('-T', '--includeTestSources', default=False, action="store_true", required=False, + help="Include analysis of the test sources. Default False") + parser.add_argument('-t', '--testDir', default="", action="store", required=False, type=str, + help="Directory hint for locating test files.") + + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + if not args.summary and not args.average and not args.visual and not args.explain: + args.summary = True + + fileNames = [] + + if args.stdin: + for line in sys.stdin: + t = line.strip() + if len(t) > 0: + fileNames.append(t) + else: + fileNames = args.files + + CoverageReport.commandLineMain(args, fileNames, args.testDir) diff --git a/longbow/src/python/longbow-doxygen-report.py b/longbow/src/python/longbow-doxygen-report.py new file mode 100755 index 00000000..1b303f91 --- /dev/null +++ b/longbow/src/python/longbow-doxygen-report.py @@ -0,0 +1,166 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import pprint +import subprocess +import difflib +import csv +import argparse +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +import LongBow + +def concatenateContinuationLines(lines): + ''' + Parse doxygen log lines. + Lines that are indented by a space are continutations of the previous line. + ''' + result = list() + accumulator = "" + for line in lines: + line = line.rstrip() + if line.startswith(" ") == False and line.startswith(" ") == False: + if len(accumulator) > 0: + result.append(accumulator) + accumulator = line + else: + accumulator = accumulator + " " + line.lstrip() + + result.append(accumulator) + + return result + +def parseLine(line): + result = None + if not line.startswith("<"): + fields = line.split(":") + if len(fields) >= 4: + result = { "fileName" : fields[0].strip(), + "lineNumber" : int(fields[1].strip()), + "type" : "documentation", + "severity" : fields[2].strip(), + "message" : " ".join(fields[3:]).strip()} + elif line.startswith("error"): + print line + elif len(line) > 0: + print "Consider using doxygen -s:", line + + return result + +def canonicalize(lines): + lines = concatenateContinuationLines(lines) + parsedLines = map(lambda line: parseLine(line), lines) + parsedLines = filter(lambda line: line != None, parsedLines) + return parsedLines + +def organize(entries): + result = dict() + + for entry in entries: + if not entry["fileName"] in result: + result[entry["fileName"]] = dict() + + entryByFile = result[entry["fileName"]] + + if not str(entry["lineNumber"]) in entryByFile: + entryByFile[str(entry["lineNumber"])] = list() + if not entry in entryByFile[str(entry["lineNumber"])]: + entryByFile[str(entry["lineNumber"])].append(entry) + + return result + +def textualSummary(distribution, documentation): + maxWidth = 0 + for entry in documentation: + if len(entry) > maxWidth: + maxWidth = len(entry) + + formatString ="%-" + str(maxWidth) + "s %8d %8d %.2f%%" + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + LongBow.scorePrinter(distribution, score, formatString % (entry, totalLines, badLines, score)) + return + +def textualAverage(distribution, documentation, format): + sum = 0.0 + + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + sum = sum + score + + if len(documentation) == 0: + averageScore = 100.0 + else: + averageScore = sum / float(len(documentation)) + + LongBow.scorePrinter(distribution, averageScore, format % averageScore) + +def csvSummary(distribution, documentation): + formatString ="documentation,%s,%d,%d,%.2f%%" + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + LongBow.scorePrinter(distribution, score, formatString % (entry, totalLines, badLines, score)) + return + +def main(argv): + parser = argparse.ArgumentParser(prog='longbow-doxygen-report', formatter_class=argparse.RawDescriptionHelpFormatter, description="") + parser.add_argument('-l', '--doxygenlog', default=False, action="store", required=True, type=str, help="The doxygen output log to use.") + parser.add_argument('-s', '--summary', default=False, action="store_true", required=False, help="Produce the score for each file") + parser.add_argument('-a', '--average', default=False, action="store_true", required=False, help="Produce the simple average of all scores.") + parser.add_argument('-d', '--distribution', default="[100, 95]", action="store", required=False, type=str, help="A list containing the score distributions for pretty-printing") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="The required output format. text, csv") + + args = parser.parse_args() + + if not args.summary and not args.average: + args.summary = True + + with open(args.doxygenlog, 'r') as f: + lines = f.readlines() + + lines = canonicalize(lines) + + result = organize(lines) + + pp = pprint.PrettyPrinter(indent=4) + #pp.pprint(result) + + distribution = eval(args.distribution) + if args.summary: + if args.output == "text": + textualSummary(distribution, result) + else: + csvSummary(distribution, result) + + if args.average: + textualAverage(distribution, result, "%.2f") + + +if __name__ == '__main__': + ''' +@(#) longbow-doxygen-report @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. + ''' + main(sys.argv) diff --git a/longbow/src/python/longbow-generate-about.py b/longbow/src/python/longbow-generate-about.py new file mode 100755 index 00000000..437102a3 --- /dev/null +++ b/longbow/src/python/longbow-generate-about.py @@ -0,0 +1,289 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import sys +import string +import datetime +import argparse +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +import FileUtil + +whatLineToken = "@(#)" + +def translateCCharacter(character): + result = character + + if character == '\t': + result = "\\t" + elif character == "\n": + result = "\\n" + elif character == "\"": + result = "\\\"" + elif character == "\'": + result = "\\'" + + return result + + +def makeWhatLine(line): + return "@(#)" + line + +def createCString(string): + if string is None: + result = "None" + else: + result = "".join(map(lambda character: translateCCharacter(character), string)) + return result + +def createQuotedCString(string): + return "\"%s\"" % createCString(string) + +def cIdentifier(name): + translation = string.maketrans("-!@#$%^&*()_-+=[]{}|;:<>,./?", "____________________________") + return name.translate(translation) + + +def validateArgument(arg): + ''' + If the given parameter is equal to '-' return None, otherwise return the parameter. + ''' + if arg == "-": + return None + return arg + + +class LongBowGenerateAboutHFile: + def __init__(self, prefix): + self.prefix = prefix + return + + def headerdocFunction(self, functionName, OneLineDescription, returns): + result = "/**\n" + result += " * %s\n" % OneLineDescription + result += " *\n" + result += " * @return %s\n" % returns + result += " */\n" + return result + + def FileName(self): + return self.prefix + "_About.h" + + def Name(self): + functionName = "%sAbout_Name" % self.prefix + result = self.headerdocFunction(functionName, "Return the name as a C string.", "The name as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def Version(self): + functionName = "%sAbout_Version" % self.prefix + result = self.headerdocFunction(functionName, "Return the version as a C string.", "The version as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def About(self): + functionName = "%sAbout_About" % self.prefix + result = self.headerdocFunction(functionName, "Return the About text as a C string.", "The About text as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def MiniNotice(self): + functionName = "%sAbout_MiniNotice" % self.prefix + result = self.headerdocFunction(functionName, + "Return the minimum copyright notice as a C string.", + "The minimum copyright notice as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def ShortNotice(self): + functionName = "%sAbout_ShortNotice" % self.prefix + result = self.headerdocFunction(functionName, + "Return the short copyright notice as a C string.", + "The short copyright notice as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def LongNotice(self): + functionName = "%sAbout_LongNotice" % self.prefix + result = self.headerdocFunction(functionName, + "Return the long copyright notice as a C string.", + "The long copyright notice as a C string.") + result += "const char *%s(void);\n" % functionName + return result + + def WhatString(self): + result = "/**\n" + result += " * Embedded string containing information for the what(1) command.\n" + result += " *\n" + result += " */\n" + result += "extern const char *%s_What;\n" % (self.prefix) + return result + + def __str__(self): + result = "// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED.\n" + result += "// longbow-generate-about @VERSION@ @DATE@\n\n" + result += "#ifndef %s_About_h\n" % (self.prefix) + result += "#define %s_About_h\n" % (cIdentifier(self.prefix)) + result += self.WhatString() + "\n" + result += self.Name() + "\n" + result += self.Version() + "\n" + result += self.About() + "\n" + result += self.MiniNotice() + "\n" + result += self.ShortNotice() + "\n" + result += self.LongNotice() + "\n" + result += "#endif // %s_About_h\n" % (cIdentifier(self.prefix)) + return result + + def writeFile(self): + with open(self.FileName(), "w") as myfile: + myfile.write(str(self)) + return + +class LongBowGenerateAboutCFile: + def __init__(self, args): + self.prefix = args.prefix + self.name = args.name + self.version = validateArgument(args.version) + self.miniNotice = "" + self.shortNotice = "" + self.longNotice = "" + self.about = None + self.what = None + + self.args = args + + self.miniNotice = FileUtil.readFileString(args.miniNotice) + self.shortNotice = FileUtil.readFileString(args.shortNotice) + self.longNotice = FileUtil.readFileString(args.longNotice) + + self.buildDate = datetime.datetime.utcnow().isoformat() + + if self.version == None: + self.version = " RELEASE_VERSION " + + if self.about == None: + self.about = createQuotedCString("%s " % (self.name)) + \ + self.version + \ + createQuotedCString(" %s" % (self.buildDate)) + " " + \ + createQuotedCString("\n%s" % (self.miniNotice)) + + if self.what == None: + if self.miniNotice != None: + notice = "\n".join(map(lambda line: "\t" + line, self.miniNotice.split("\n")[:-1])) + else: + notice = "" + self.what = createQuotedCString(whatLineToken) + " " + \ + createQuotedCString(self.name + " ") + " " + \ + self.version + " " + \ + createQuotedCString(" " + self.buildDate) + "\n" + \ + createQuotedCString(whatLineToken) + " " + \ + createQuotedCString(notice) + return + + def FileName(self): + return self.prefix + "_About.c" + + def Name(self): + functionName = "%sAbout_Name" % self.prefix + return self.boilerPlateFunction(functionName, createQuotedCString(self.name)) + + def Version(self): + functionName = "%sAbout_Version" % self.prefix + return self.boilerPlateFunction(functionName, self.version) + + def About(self): + functionName = "%sAbout_About" % self.prefix + return self.boilerPlateFunction(functionName, self.about) + + def MiniNotice(self): + functionName = "%sAbout_MiniNotice" % self.prefix + return self.boilerPlateFunction(functionName, createQuotedCString(self.miniNotice)) + + def ShortNotice(self): + functionName = "%sAbout_ShortNotice" % self.prefix + return self.boilerPlateFunction(functionName, createQuotedCString(self.shortNotice)) + + def LongNotice(self): + functionName = "%sAbout_LongNotice" % self.prefix + return self.boilerPlateFunction(functionName, createQuotedCString(self.longNotice)) + + def WhatString(self): + return "const char *%s_What = %s;\n" % (self.prefix, self.what) + + def boilerPlateFunction(self, functionName, string): + result = "const char *\n%s(void)\n" % functionName + result += "{\n" + result += " return %s;\n" % string + result += "}\n" + return result + + def __str__(self): + result = "// DO NOT EDIT THIS FILE. IT IS AUTOMATICALLY GENERATED.\n" + result += "// longbow-generate-about @VERSION@ @DATE@\n\n" + result += "#include \"%s_About.h\"\n\n" % self.prefix + result += self.WhatString() + "\n" + result += self.Name() + "\n" + result += self.Version() + "\n" + result += self.About() + "\n" + result += self.MiniNotice() + "\n" + result += self.ShortNotice() + "\n" + result += self.LongNotice() + "\n" + return result + + def writeFile(self): + with open(self.FileName(), "w") as myfile: + myfile.write(str(self)) + return + +if __name__ == '__main__': + desc = ''' +@(#) longbow-generate-about @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. + +Generate C code conforming to the About contract. + +Create a .c and .h file pair with the specified prefix. +For the prefix 'xyzzy', the file names are 'xyzzy_About.c' and 'xyzzy_About.h' respectively. + +The functions defined are: + +const char *xyzzyAbout_Name(void) +const char *xyzzyAbout_Version(void) +const char *xyzzyAbout_About(void) +const char *xyzzyAbout_MiniNotice(void) +const char *xyzzyAbout_ShortNotice(void) +const char *xyzzyAbout_LongNotice(void) + +And the constant string const char *xyzzy_What; + ''' + + parser = argparse.ArgumentParser(prog='longbow-generate-about', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + + parser.add_argument("prefix", help="The file name and function name prefix.") + parser.add_argument("name", help="The name of the entity this is about.") + parser.add_argument("version", help="The version of the entity this is about.") + parser.add_argument("miniNotice", help="The name of the file containing the smallest copyright or attribution notice.") + parser.add_argument("shortNotice", help="The name of the file containing a short copyright or attribution notice.") + parser.add_argument("longNotice", help="The name of the file containing a full copyright or attribution notice.") + + args = parser.parse_args() + + hfile = LongBowGenerateAboutHFile(args.prefix) + hfile.writeFile() + + cfile = LongBowGenerateAboutCFile(args) + cfile.writeFile() diff --git a/longbow/src/python/longbow-name-report.py b/longbow/src/python/longbow-name-report.py new file mode 100755 index 00000000..3daca949 --- /dev/null +++ b/longbow/src/python/longbow-name-report.py @@ -0,0 +1,91 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import os +import sys +import argparse + +sys.path.append("../site-packages/longbow/") +sys.path.append("@INSTALL_PYTHON_DIR@") +import NameReport + +if __name__ == '__main__': + ''' + @(#) name-report @VERSION@ @DATE@ + @(#) All Rights Reserved. Use is subject to license terms. + ''' + desc = ''' +Print a score representing the percentage of compliance with the naming conventions for one or more C source and object files. + +$ ./longbow-name-report parc_Object.c +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-names 100.00 enum-names 100.0 typedef-names 100.0 +$ +$ echo parc_Object.c | ./parc-name-grade - +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-names 100.00 enum-names 100.0 typedef-names 100.0 +$ + +Default Output (--summary): +namespace, module-name[, topic, score] + +namespace: Namespace of the file, like `parc` +module-name: The name of the file, like `parc_ArrayList.c` +topic: The name of the topic: valid-name, function-name-conformance, or enum-name-conformance +score: A context-sensitive value related to the topic (valid-name: True/False, function/enum-name-conformance: 0-100) + +Finegrain Output (--finegrain): +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-names 100.00 enum-names 100.0 typedef-names 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Acquire 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_AssertValid 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Compare 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Copy 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Create 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Display 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Equals 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_GetReferenceCount 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_HashCode 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_Release 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_TestAcquireContractRaw 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object function-name parcObject_ToJSON 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/LibpgetEnumerationsFromFilesarc/parc/algol parc_Object function-name parcObject_ToString 100.0 +/Users/cwood/Projects/DistilleryBranches/Case1073/Libparc/parc/algol parc_Object typedef-name _ObjectHeader 100.0 +''' + + parser = argparse.ArgumentParser(prog='longbow-name-report', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + parser.add_argument('-a', '--average', default=False, action="store_true", help="Print an average summary of the naming conformance results for all modules") + parser.add_argument('-s', '--summary', default=False, action="store_true", help="Print a summary of the naming conformance results for each module") + parser.add_argument('-f', '--finegrain', default=False, action="store_true", help="Print the individual results for each function, typedef, and enumeration in each module.") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="the output format: \"text\" or \"csv\"") + parser.add_argument('-d', '--distribution', default="[99, 90]", action="store", required=False, type=str, help="a list containing the score distributions for pretty-printing. Default [99, 90]") + parser.add_argument('-t', '--trace', default=False, action="store_true", help="Turn on exception tracing to debug an issue with the tool.") + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, help="Read the list of files from standard input.") + parser.add_argument('-p', '--opath', default="", action="store", required=False, type=str, help="Specify the path for object files, can be a path to a static library.") + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + targets = [] + if args.stdin: + for line in sys.stdin: + targets.append(line.strip()) + else: + targets = args.files + + if (len(targets) == 0): + parser.print_usage() + sys.exit(1) + + NameReport.commandLineMain(args, targets, args.opath) diff --git a/longbow/src/python/longbow-preprocess.py b/longbow/src/python/longbow-preprocess.py new file mode 100755 index 00000000..12c01c2a --- /dev/null +++ b/longbow/src/python/longbow-preprocess.py @@ -0,0 +1,153 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import subprocess +import pprint + +def sourceFileNameToName(sourceFileName): + ''' + Given the path to a source file, return the name without any path components or trailing suffix. + ''' + name = os.path.basename(sourceFileName) + return name.split(".")[0] + +def canonicalizeFunctionName(functionName): + ''' + Given a function name that contains the initial '_' character, + strip it and return a canonicalised form of the same name suitable for a source file. + ''' + if functionName[0] == "_": + functionName = functionName[1:] + return functionName + +def isReservedName(functionName): + ''' + Given a canonicalized name, determine if it is a reserved name according to ISO/IEC 9899:2011 and ANSI Sec. 4.1.2.1, + identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. + ''' + if functionName[0] == '_' and functionName[1] == '_': + return True + elif functionName[0] == '_' and functionName[1].isupper(): + return True + + return False + + +def getDarwinTestableFunctions(sourceFileName, objectFileName): + ''' + ''' + command = [ "/usr/bin/nm", "-Um", objectFileName ] + + output = subprocess.check_output(command) + lines = output.splitlines() + + external = [] + internal = [] + for line in lines: + fields = line.split(" ") + if fields[1] == "(__TEXT,__text)": + functionName = canonicalizeFunctionName(fields[3]) + + if isReservedName(functionName): + print "Ignoring function with a ISO/IEC 9899:2011 and ANSI Sec. 4.1.2.1 reserved name: ", functionName + else: + if fields[2] == "external": + external.append( ( functionName ) ) + else: + internal.append( ( functionName ) ) + pass + pass + pass + + external.sort() + internal.sort() + return { "Static": internal, "Global" : external } + +def testCases(functionList): + ''' + ''' + return { "testCases" : functionList } + +def testSuite(testCases): + ''' + A Test Suite is comprised of one or more Test Cases + ''' + if testCases == None or len(testCases) == 0: + return None + return [ testCases ] + +def testFixture(testFixtureName, testSuites): + ''' + A Test Fixture contains an initial setup function, one or more Test Suites, and a final tear-down function. + ''' + if testSuites == None: + return None + return { "name" : testFixtureName, "testSuites" : testSuites } + +def testRunner(testRunnerName, files, testFixtures): + ''' + A Test Runner contains one or more Test Fixtures. + ''' + testFixtures = [x for x in testFixtures if x is not None] + return { "name" : testRunnerName, "files" : files, "testFixtures" : testFixtures } + +def computeFileNames(argv): + """ Given an argument list, compute the file names to use for code generation. + + + """ + if (argv[1].endswith(".c")): + return (argv[1], argv[2], sourceFileNameToName(argv[1]) + ".longbow") + + return (argv[1]+".c", argv[1]+".o", sourceFileNameToName(argv[1]) + ".longbow") + +if __name__ == '__main__': + ''' + @(#) longbow-preprocess @VERSION@ @DATE@ + @(#) All Rights Reserved. Use is subject to license terms. +''' + if len(sys.argv) <= 1: + print "Usage: longbow-preprocess (sourceFileName objectFileName) | (fileNamePrefix)" + print + print "Generate a plain-text intermediate form for a LongBow test case generated from" + print "a specified source and object file. Use longbow-code to produce a LongBow" + print "test runner based upon the intermediate form." + sys.exit(1) + + fileNames = computeFileNames(sys.argv) + + sourceFileName = fileNames[0] + objectFileName = fileNames[1] + outputFileName = fileNames[2] + + functionDictionary = getDarwinTestableFunctions(sourceFileName, objectFileName) + + testRunnerName = sourceFileNameToName(sourceFileName) + + testFixtures = map(lambda(fixtureType): + testFixture(fixtureType, testSuite(testCases(functionDictionary[fixtureType]))), functionDictionary) + + files = { "sourceFile" : sourceFileName, "objectFile" : objectFileName } + result = testRunner(testRunnerName, files, testFixtures) + + out = open(outputFileName, "w") + pp = pprint.PrettyPrinter(indent=4, width=132, depth=None, stream=out) + pp.pprint(result) + out.close() + pass diff --git a/longbow/src/python/longbow-size-report.py b/longbow/src/python/longbow-size-report.py new file mode 100755 index 00000000..fd4ae76c --- /dev/null +++ b/longbow/src/python/longbow-size-report.py @@ -0,0 +1,131 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import subprocess +import difflib +import csv +import argparse +sys.path.append("@INSTALL_PYTHON_DIR@") +import LongBow +from pprint import pprint + +def textOutputFile(file, maximumFileNameLength): + format = "%-" + str(maximumFileNameLength) + "s %6d" + print format % (file[0], file[1]) + return + +def textSummary(files): + maximumFileNameLength = max(map(lambda file: len(file[0]), files)) + map(lambda file: textOutputFile(file, maximumFileNameLength), files) + return + +def csvOutputFile(file): + format = "size,%s,%d" + print format % (file[0], file[1]) + return + +def csvSummary(files): + map(lambda file: csvOutputFile(file), files) + return + +def textTotal(files): + total = sum(map(lambda file: file[1], files)) + print total + return + +def csvTotal(files): + total = sum(map(lambda file: file[1], files)) + print total + return + +def main(): + desc = ''' +Report on number of lines of one or more C source or header files. + +Input is either from a list of files supplied as command line parameters, +or as a list of newline separated file names read from standard input. +Output is a plain text (default) or a CSV file reporting +the file name and the total number of lines in the file. + +Usage: + +% longbow-size-report *.[ch] + +Report the number of lines in .c and .h files specified as command line parameters. + +% longbow-size-report - +Read the lists of files from standard input, one file per line. + +$ longbow-size-report parc_JSON.c +parc_JSON.c 239 +$ +$ +$ echo parc_JSON.c | longbow-size-report -o csv - +parc_JSON.c,239 +$ +''' + + parser = argparse.ArgumentParser(prog='longbow-size-report', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, help="read the list of files from standard input.") + parser.add_argument('-s', '--summary', default=False, action="store_true", required=False, help="display the number of lines for each file") + parser.add_argument('-t', '--total', default=False, action="store_true", required=False, help="display the total number of lines for all files") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="the output format: \"text\" or \"csv\"") + + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + if args.summary == False and args.total == False: + args.summary = True + + targets = [] + + if args.stdin: + for line in sys.stdin: + t = line.strip() + if len(t) > 0: + targets.append(t) + else: + targets = args.files + + if len(targets) == 0: + parser.print_usage() + sys.exit(1) + + files = map(lambda fileName: [ fileName, LongBow.countLines(fileName)], targets) + total = sum(map(lambda element: element[1], files)) + + if args.summary: + if args.output == "text": + textSummary(files) + else: + csvSummary(files) + + if args.total: + if args.output == "text": + textTotal(files) + else: + csvTotal(files) + +if __name__ == '__main__': + ''' + @(#) longbow-size-report @VERSION@ @DATE@ + @(#) All Rights Reserved. Use is subject to license terms. + ''' + main() diff --git a/longbow/src/python/longbow-style-report.py b/longbow/src/python/longbow-style-report.py new file mode 100755 index 00000000..05b8fbde --- /dev/null +++ b/longbow/src/python/longbow-style-report.py @@ -0,0 +1,99 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import argparse + +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +sys.path.append("../site-packages/longbow/") +import StyleReport + +if __name__ == '__main__': + ''' +@(#) longbow-code @VERSION@ @DATE@ + @(#) All Rights Reserved. Use is subject to license terms. +''' + desc = ''' +Report on style conformance for one or more C source or header files. + +Input is either from a list of files supplied as command line parameters, +or as a list of newline separated file names read from standard input. +Reports are: +--summary A one line per file report of the file name, number of lines, number of non-compliant lines, and a score. +--average A single line output of the average of all scores. +--total A single line of output of the percentage of all compliant lines to the total number of lines in all files. +--visual A visual representation of the style check. + +For each of these reports, the output format is specified by: +--output text Display text on standard output +--output csv Display a list of comma-separated values on standard output. +--output gui Use a graphical user interface if possible. + +The visual report displays either a colorized, line by line output of +the differences between the original source file it's exemplar (-o text), +or displays a file-merge application for interactive use ()-o gui) + +Example: + +% longbow-style-report *.[ch] + +Report conformance of the .c and .h files specified as command line parameters. + +% longbow-style-report - +Report conformance of the .c and .h files read from standard input, one line per file. + +$ longbow-style-report parc_JSON.c +parc_JSON.c 239 0 100.00$ +$ +$ echo parc_JSON.c | longbow-style-report - +parc_JSON.c,239,0,100.00 +$ +''' + + parser = argparse.ArgumentParser(prog='longbow-style-report', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, help="read the list of files from standard input only.") + parser.add_argument('-s', '--summary', default=False, action="store_true", required=False, help="Display the score for each file.") + parser.add_argument('-a', '--average', default=False, action="store_true", required=False, help="Display the simple average of all scores.") + parser.add_argument('-t', '--total', default=False, action="store_true", required=False, help="Display the percentage of all compliant lines to the total number of lines in all files.") + parser.add_argument('-d', '--distribution', default="[95, 90]", action="store", required=False, type=str, help="a list containing the score distributions for pretty-printing. Default '[95, 90]' (green >= 95, yellow >= 90, red < 90).") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="the output format: 'text', 'csv', or 'gui'.") + parser.add_argument('-v', '--visual', default=False, action="store_true", required=False, help="Display a visual representation of the style check.") + parser.add_argument('-k', '--key', default="name", action="store", required=False, type=str, help="The sort key: Type '--key help' for the list.") + parser.add_argument('-e', '--exclude', default="", action="store", required=False, type=str, help="Exclude a comma separated set of one or more of: 'red', 'yellow', 'green'.") + + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + if args.summary == False and args.average == False and args.total == False and args.visual == False: + args.summary = True + + targets = [] + + if args.stdin: + for line in sys.stdin: + t = line.strip() + if len(t) > 0: + targets.append(t) + else: + targets = args.files + + UNCRUSTIFY = "@UNCRUSTIFY_BIN@" + UNCRUSTIFY_CONFIG = "@UNCRUSTIFY_CONFIG@" + + StyleReport.commandLineMain(args, targets, UNCRUSTIFY, UNCRUSTIFY_CONFIG) diff --git a/longbow/src/python/longbow-test-run.py b/longbow/src/python/longbow-test-run.py new file mode 100755 index 00000000..77ed1f98 --- /dev/null +++ b/longbow/src/python/longbow-test-run.py @@ -0,0 +1,172 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import sys +import re +import pprint +import subprocess +import argparse +import json + +class TokenParser: + def __init__(self, tokens=[]): + self.index = 0 + self.tokens = tokens + + def nextToken(self): + result = self.tokens[self.index] + self.index = self.index + 1 + return result + + def previousToken(self): + self.index = self.index - 1 + result = self.tokens[self.index - 1] + return result + + def expectedToken(self, expected): + token = self.nextToken() + if token == expected: + return True + self.index = self.index - 1 + print "expectedToken(%s) is not the actual %s" % (expected, token) + return False + + def end(self): + if self.index == len(self.tokens): + return True + return False + +class LongBowCodeCoverage: + def __init__(self): + return + + def run(self, executableFile): + lines = subprocess.check_output([ "gcov", "-f", executableFile ]) + token = map(lambda x : x.strip("'"), re.split("[ :\n]+", lines)) + return self.parse(token) + + def parseFunction(self, parser): + functionName = parser.nextToken() + parser.expectedToken("Lines") + parser.expectedToken("executed") + coverage = parser.nextToken() + return { "function" : functionName, "coverage" : coverage } + + def parseFile(self, parser): + fileName = parser.nextToken() + parser.expectedToken("Lines") + parser.expectedToken("executed") + coverage = parser.nextToken() + return { "file" : fileName, "coverage" : coverage } + + def parse(self, tokens): + parser = TokenParser(tokens) + functions = [ ] + + while not parser.end(): + token = parser.nextToken() + if (token == "Function"): + function = self.parseFunction(parser) + functions.append(function) + elif (token == "File"): + file = self.parseFile(parser) + pass + + self.detailCoverage = { "file" : file, "functions" : functions } + return self.detailCoverage + + def getCoverage(self): + result["file"]["coverage"] + + def getDetailCoverage(self): + return self.detailCoverage + + +class LongBowTestRun: + def __init__(self, options=[]): + self.options = options + self.mainFileName = None + self.exitStatus = 0 + return + + def setOptions(self, options=[]): + self.options = options + return + + def getMainFileName(self): + return self.mainFileName + + def run(self, testRunner): + self.mainFileName = testRunner + self.exitStatus = 0 + + try: + try: + os.remove(testRunner + ".gcda") + except: + pass + lines = subprocess.check_output([ testRunner ]) + lines = re.split("[ :]+", lines) + self.exitStatus = 0 + except subprocess.CalledProcessError, e: + self.exitStatus = e.returncode + + return self.exitStatus + + def report(self, detailedOutput=False, jsonOutput=False): + result = "" + if self.exitStatus == 0: + coverage = LongBowCodeCoverage() + result = coverage.run(testRunner.getMainFileName()) + + if detailedOutput: + if jsonOutput: + result = json.dumps(result, sort_keys=False, indent=4, separators=(',', ': ')) + else: + pp = str(result) + pass + else: + if jsonOutput: + result = json.dumps(result["file"], sort_keys=False, indent=4, separators=(',', ': ')) + else: + result = "PASS " + result["file"]["file"] + " " + result["file"]["coverage"] + else: + result = "FAIL " + args.testRunner + pass + + return result + + +if __name__ == '__main__': + testRunners = [] + if len(sys.argv) < 2: + print "Usage: longbow-test-run.py testExecutable" + print "Run a LongBow test" + sys.exit(1) + + parser = argparse.ArgumentParser(description='Run a LongBow Test') + parser.add_argument("--json", help="Produce JSON output instead of a Python dictionary.", action="store_true") + parser.add_argument("--detailed", help="Produce detailed output.", action="store_true") + parser.add_argument("testRunner", help="The name of the test executable.", nargs='+') + args = parser.parse_args() + + testRunner = LongBowTestRun([ "--run-nonforked" ]) + + for test in args.testRunner: + exitStatus = testRunner.run(test) + print testRunner.report(args.detailed, args.json) + diff --git a/longbow/src/python/longbow-test-suite.py b/longbow/src/python/longbow-test-suite.py new file mode 100755 index 00000000..5a6d67e5 --- /dev/null +++ b/longbow/src/python/longbow-test-suite.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +from subprocess import call + +class LongBowTestSuite: + def __init__(self): + self.options = [] + return + + def setOptions(self, options=[]): + self.options = options + return + + def run(self, testRunners=[]): + result = 0 + for test in testRunners: + outputFileName = test + ".log" + outputFile = open(outputFileName, 'w') + command = [ test ] + self.options + print command + status = call(command, stdout=outputFile) + if result == 0: + result = status + pass + outputFile.close() + pass + return result + + +if __name__ == '__main__': + testRunners = [] + if len(sys.argv) < 2: + print "Usage: longbow-test-suite.py testExecutable ..." + print "Run one or more LongBow test runners as indpendant processes" + sys.exit(1) + testRunners = testRunners + sys.argv[1:] + + testSuite = LongBowTestSuite() + testSuite.setOptions([ "--run-nonforked" ]) + exitStatus = testSuite.run(testRunners) diff --git a/longbow/src/python/longbow-vocabulary-report.py b/longbow/src/python/longbow-vocabulary-report.py new file mode 100755 index 00000000..25004428 --- /dev/null +++ b/longbow/src/python/longbow-vocabulary-report.py @@ -0,0 +1,66 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import argparse + +sys.path.append("@INSTALL_PYTHON_DIR@") +sys.path.append("@DEPENDENCY_PYTHON_DIR@") +sys.path.append("../site-packages/longbow/") +import VocabularyReport +import hfcca + +def main(argv): + desc = ''' +Print the vocabulary (number of tokens) of functions and files. + +The option --function displays the file name, function name, +line number of the function, the number of tokens + +The default option --summary displays the file name, the average vocabulary +of all functions in the file and a score ranging from 0 to 100. + +Usage: +$ longbow-vocabulary-report parc_JSON.c +parc_JSON.c 51.00 100.00 +$ +$ echo parc_JSON.c | longbow-vocabulary-report --function -o csv - +vocabulary,parc_JSON.c,parcJSON_Create,49,50,100.00 +... +$ + +''' + + parser = argparse.ArgumentParser(prog='longbow-vocabulary-report', formatter_class=argparse.RawDescriptionHelpFormatter, description=desc) + parser.add_argument('-s', '--summary', default=False, action="store_true", help="print the average vocabulary of each target file.") + parser.add_argument('-f', '--function', default=False, action="store_true", help="print the vocabulary of each function in each target file.") + parser.add_argument('-', '--stdin', default=False, action="store_true", required=False, help="read the list of files from standard input rather than the command line.") + parser.add_argument('-a', '--average', default=False, action="store_true", required=False, help="display only the simple average of the average vocabulary of each target file.") + parser.add_argument('-o', '--output', default="text", action="store", required=False, type=str, help="the output format: \"text\" or \"csv\"") + parser.add_argument("files", help="Files to check", nargs="*") + + args = parser.parse_args() + + VocabularyReport.commandLineMain(args, hfcca) + + +if __name__ == "__main__": + ''' +@(#) longbow-vocabulary-report @VERSION@ @DATE@ +@(#) All Rights Reserved. Use is subject to license terms. + ''' + main(sys.argv) diff --git a/longbow/src/python/parc_uncrustify.cfg b/longbow/src/python/parc_uncrustify.cfg new file mode 100755 index 00000000..475d8049 --- /dev/null +++ b/longbow/src/python/parc_uncrustify.cfg @@ -0,0 +1,115 @@ +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + + +indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs +input_tab_size = 4 # original tab size +output_tab_size = 4 # new tab size +indent_columns = output_tab_size +indent_label = 2 # pos: absolute col, neg: relative column +# indent_align_string = False # align broken strings +# indent_brace = 0 + +nl_if_leave_one_liners = false # Don't split one-line if/else statements - 'if(a) b++;' (false/true) + +nl_enum_brace = remove # (ignore/add/remove/force) newline between 'enum' and '{' +nl_union_brace = remove # "union {" vs "union \n {" +nl_struct_brace = remove # "struct {" vs "struct \n {" +nl_do_brace = remove # "do {" vs "do \n {" +nl_if_brace = remove # "if () {" vs "if () \n {" +nl_for_brace = remove # "for () {" vs "for () \n {" +nl_else_brace = remove # "else {" vs "else \n {" +nl_while_brace = remove # "while () {" vs "while () \n {" +nl_switch_brace = remove # "switch () {" vs "switch () \n {" +# nl_func_var_def_blk = 1 +# nl_before_case = 1 +nl_fcall_brace = add # "foo() {" vs "foo()\n{" +nl_fdef_brace = add # "int foo() {" vs "int foo()\n{" +# nl_after_return = TRUE +nl_brace_while = remove +nl_brace_else = remove +nl_squeeze_ifdef = TRUE +nl_func_type_name = add # (ignore/add/remove/force) newline between return type and function name in a function definition + + +# The span for aligning struct initializer values (0=don't align) +align_struct_init_span = 4 # number + +# Spaces to indent 'case' from 'switch' +# Usually 0 or indent_columns. +indent_switch_case = 4 # number + +# Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. +# If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. +mod_full_brace_if_chain = false # false/true +# mod_paren_on_return = add # "return 1;" vs "return (1);" +mod_full_brace_if = add # "if (a) a--;" vs "if (a) { a--; }" +mod_full_brace_for = add # "for () a--;" vs "for () { a--; }" +mod_full_brace_do = add # "do a--; while ();" vs "do { a--; } while ();" +mod_full_brace_while = add # "while (a) a--;" vs "while (a) { a--; }" +mod_remove_empty_return = true # Remove a void 'return;' that appears as the last statement in a function. (false/true) + +sp_after_ptr_star = remove # (ignore/add/remove/force) space after pointer star '*', if followed by a word. +sp_func_proto_paren = remove # (ignore/add/remove/force) A space between function name and '(' on function declaration +sp_return_paren = force # (ignore/add/remove/force) a space between 'return' and '(' +sp_before_semi = remove +sp_paren_paren = remove # space between (( and )) +sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)" +sp_before_sparen = force # "if (" vs "if(" +sp_after_sparen = force # "if () {" vs "if (){" +sp_after_cast = add # "(int) a" vs "(int)a" +sp_inside_braces = force # "{ 1 }" vs "{1}" +sp_inside_braces_struct = force # "{ 1 }" vs "{1}" +sp_inside_braces_enum = force # "{ 1 }" vs "{1}" +sp_inside_paren = remove # "( 1 )" vs "(1)" +sp_inside_fparen = remove # "( 1 )" vs "(1)" - functions +sp_inside_sparen = remove # "( 1 )" vs "(1)" - if/for/etc +sp_type_func = add # ignore/add/remove/force A space between return type and function name +sp_assign = force +sp_arith = force +sp_bool = force +sp_compare = force +sp_after_comma = force +sp_func_def_paren = remove # "int foo (){" vs "int foo(){" +sp_func_call_paren = remove # "foo (" vs "foo(" +sp_func_proto_paren = remove # "int foo ();" vs "int foo();" +sp_paren_brace = add # Force a space between ')' and '{' +sp_else_brace = add # Add or remove space between 'else' and '{' if on the same line (ignore/add/remove/force) +sp_brace_else = force # Add or remove space between '}' and 'else' if on the same line (ignore/add/remove/force) + +# align_with_tabs = FALSE # use tabs to align +# align_on_tabstop = FALSE # align on tabstops +# align_enum_equ_span = 4 +# align_nl_cont = TRUE +# align_var_def_span = 2 +# align_var_def_inline = TRUE +# align_var_def_star = TRUE +# align_var_def_colon = TRUE +# align_assign_span = 1 +# align_struct_init_span = 3 +# align_var_struct_span = 3 +# align_right_cmt_span = 3 +# align_pp_define_span = 3 +# align_pp_define_gap = 4 +# align_number_left = TRUE +# align_typedef_span = 5 +# align_typedef_gap = 3 + +cmt_star_cont = TRUE # put a star on subsequent comment lines + +eat_blanks_before_close_brace = TRUE +eat_blanks_after_open_brace = TRUE + +# Add or remove space between pointer stars '*' +sp_between_ptr_star = remove diff --git a/longbow/src/python/site-packages/CMakeLists.txt b/longbow/src/python/site-packages/CMakeLists.txt new file mode 100644 index 00000000..fab750f7 --- /dev/null +++ b/longbow/src/python/site-packages/CMakeLists.txt @@ -0,0 +1,12 @@ +install(FILES longbow.pth DESTINATION ${INSTALL_BASE_PYTHON_DIR}) +install(FILES longbow/LongBow.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/FileUtil.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/GCov.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/GCovSummary.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/ANSITerm.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/SymbolTable.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/Language_C.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/StyleReport.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/CoverageReport.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/VocabularyReport.py DESTINATION ${INSTALL_PYTHON_DIR}) +install(FILES longbow/NameReport.py DESTINATION ${INSTALL_PYTHON_DIR}) diff --git a/longbow/src/python/site-packages/longbow.pth b/longbow/src/python/site-packages/longbow.pth new file mode 100755 index 00000000..9f0d4f64 --- /dev/null +++ b/longbow/src/python/site-packages/longbow.pth @@ -0,0 +1,18 @@ +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +# +# longbow package configuration +longbow diff --git a/longbow/src/python/site-packages/longbow/.gitignore b/longbow/src/python/site-packages/longbow/.gitignore new file mode 100644 index 00000000..0d20b648 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/longbow/src/python/site-packages/longbow/ANSITerm.py b/longbow/src/python/site-packages/longbow/ANSITerm.py new file mode 100755 index 00000000..8594c949 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/ANSITerm.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import subprocess +import re +import sys +import pprint + +ansiRed = "\x1b[31m"; +ansiGreen = "\x1b[32m"; +ansiYellow = "\x1b[33m"; +ansiBlue = "\x1b[34m"; +ansiMagenta = "\x1b[35m"; +ansiCyan = "\x1b[36m"; +ansiReset = "\x1b[0m"; + +def colorize(color, chars): + + result = chars + if color == "red": + result = ansiRed + chars + ansiReset + elif color == "green": + result = ansiGreen + chars + ansiReset + elif color == "yellow": + result = ansiYellow + chars + ansiReset + elif color == "blue": + result = ansiBlue + chars + ansiReset + elif color == "magenta": + result = ansiMagenta + chars + ansiReset + elif color == "cyan": + result = ansiCyan + chars + ansiReset + else: + print >> sys.stderr, "Bad color name:", color + + return result + + +def printColorized(color, string): + print colorize(color, string) + return + + +class ANSITerm: + def __init__(self): + return + + def printColorized(self, color, string): + print colorize(color, string) diff --git a/longbow/src/python/site-packages/longbow/CoverageReport.py b/longbow/src/python/site-packages/longbow/CoverageReport.py new file mode 100755 index 00000000..c18ae056 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/CoverageReport.py @@ -0,0 +1,262 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys +import os +import re +import subprocess +import difflib +import csv +# import argparse +import pprint +# sys.path.append("${INSTALL_PYTHON_DIR}") +# sys.path.append("${DEPENDENCY_PYTHON_DIR}") +# sys.path.append("../site-packages/longbow/") +import LongBow +import GCov +import GCovSummary +import FileUtil +import ANSITerm +import Language_C + +def checkTestExecutable(executableFileName): + result = False + + if not os.path.exists(executableFileName): + return result + + path = os.path.dirname(executableFileName) + pattern = os.path.basename(executableFileName)+'*.gcda' + if not Language_C.findFiles(path, pattern): + return result + + pattern = os.path.basename(executableFileName)+'*.gcno' + if not Language_C.findFiles(path, pattern): + return result + + result = True + return result + +def findTestExecutable(fileName, hints=[]): + ''' +Given a file name, look in the canonical places for a corresponding LongBow test file. + ''' + directoryName = os.path.dirname(fileName) + if len(directoryName) == 0: + directoryName = "." + + file = Language_C.Module(fileName) + + possibleTestFiles = list() + for hint in hints: + possibleTestFiles.append(hint + "/" + file.getExecutableName()) + possibleTestFiles.append(hint + "/" + file.getTestExecutableName()) + possibleTestFiles.append(directoryName + "/" + file.getExecutableName()) + possibleTestFiles.append(directoryName + "/" + file.getTestExecutableName()) + possibleTestFiles.append(directoryName + "/test/" + file.getTestExecutableName()) + + result = None + for possibleTestFile in possibleTestFiles: + if checkTestExecutable(possibleTestFile) == True: + result = os.path.abspath(possibleTestFile) + break + + return result + + +def textSummary(args, filesAndTests, gCovResults, prefix=""): + + summary = GCov.computeSummary(filesAndTests, gCovResults) + + if not args.includeTestSources: + summary = GCovSummary.removeTestSourceFiles(summary) + + if len(summary) == 0: + return + + if args.explain: + pp = pprint.PrettyPrinter(indent=2, width=150) + pp.pprint(summary) + + maximumFileLength = max(map(lambda entry: len(entry), summary)) + + format = "%s%-" + str(maximumFileLength) + "s %6s" + print format % (prefix, "File Path", "Score") + + format = "%s%-" + str(maximumFileLength) + "s %6.2f" + for testedFile in sorted(summary.keys()): + string = format % (prefix, testedFile, summary[testedFile]["coverage"]) + if summary[testedFile]["direct"] == "indirect": + ANSITerm.printColorized("magenta", string) + else: + LongBow.scorePrinter(eval(args.distribution), summary[testedFile]["coverage"], string) + + return + + +def textAverage(args, filesAndTests, gcovResults): + summary = GCov.computeSummary(filesAndTests, gcovResults) + + if not args.includeTestSources: + summary = GCovSummary.removeTestSourceFiles(summary) + + score = GCovSummary.averageCoverage(summary) + + LongBow.scorePrinter(eval(args.distribution), score, "%.2f" % (score)) + return score + + +def csvSummary(args, filesAndTests, gCovResults): + summary = GCov.computeSummary(filesAndTests, gCovResults) + + if not args.includeTestSources: + summary = GCovSummary.removeTestSourceFiles(summary) + + if len(summary) > 0: + for testedFile in sorted(summary.keys()): + outputString = "%s,%.2f" % (testedFile, summary[testedFile]["coverage"]) + LongBow.scorePrinter(eval(args.distribution), summary[testedFile]["coverage"], outputString) + + return + + +def csvAverage(args, filesAndTests, gcovResults): + summary = GCov.computeSummary(filesAndTests, gcovResults) + + if not args.includeTestSources: + summary = GCovSummary.removeTestSourceFiles(summary) + + score = GCovSummary.averageCoverage(summary) + + LongBow.scorePrinter(eval(args.distribution), score, "%.2f" % (score)) + return + + +def textVisualDisplayGcovLine(line): + token = line.split(":", 2) + if len(token) == 3: + if token[0] == "#####": + print ANSITerm.colorize("red", token[1] + " " + token[2]) + elif token[0] == "$$$$$": + print ANSITerm.colorize("yellow", token[1] + " " + token[2]) + else: + print ANSITerm.colorize("green", token[1] + " " + token[2]) + + return + + +def textVisual(args, filesAndTests, gcovResults): + + summary = GCov.computeSummary(filesAndTests, gcovResults) + if args.explain: + pp = pprint.PrettyPrinter(indent=2, width=150) + pp.pprint(summary) + pp.pprint(filesAndTests) + + for entry in filesAndTests: + print entry[0] + try: + gcovLines = summary[entry[0]]["gcovLines"] + map(lambda line: textVisualDisplayGcovLine(line.strip()), gcovLines) + except KeyError: + print >> sys.stderr, "No coverage information for", entry[0] + + return + + +def displaySummary(args, filesAndTests, newGCovResults): + if args.output == "text": + textSummary(args, filesAndTests, newGCovResults) + elif args.output == "csv": + csvSummary(args, filesAndTests, newGCovResults) + else: + print >> sys.stderr, "Unsupported output type" + return + + +def displayAverage(args, filesAndTests, gcovResults): + if args.output == "text": + textAverage(args, filesAndTests, gcovResults) + elif args.output == "csv": + csvAverage(args, filesAndTests, gcovResults) + else: + print >> sys.stderr, "Unsupported output type" + return + + +def explain(args, filesAndTests, gcovResults): + + pp = pprint.PrettyPrinter(indent=2, width=150) + pp.pprint(gcovResults) + + return + +def getFilesAndTests(fileNames, testDirs=[]): + namesAndPaths = map(lambda fileName: [fileName, os.path.abspath(fileName)], fileNames) + filesAndTests = map(lambda nameAndPath: [ nameAndPath[0], findTestExecutable(nameAndPath[1], testDirs) ], namesAndPaths) + return filesAndTests + + +def gradeAndPrint(targets, testDirs=[], problemsOnly=False, prefix=""): + filesAndTests = getFilesAndTests(targets, testDirs) + newGCovResults = map(lambda fileAndTestFile: GCov.getCoverage(fileAndTestFile[1]), filesAndTests) + + summarys = GCov.computeSummary(filesAndTests, newGCovResults) + if len(summarys) < 1: + print "%sNo GCov Results - Please be sure to run 'make check' first" % prefix + return False + summarys = GCovSummary.removeTestSourceFiles(summarys) + + paths = summarys.keys() + if problemsOnly: + paths = filter(lambda key: summarys[key]["coverage"] < 100, paths) + + distribution=[99,90] + maximumFileLength = max(map(lambda entry: len(os.path.relpath(entry)), paths)) + format = "%s%-" + str(maximumFileLength) + "s %6s" + print format % (prefix, "File Path", "Score") + format = "%s%-" + str(maximumFileLength) + "s %6.2f" + for path in sorted(paths): + string = format % (prefix, os.path.relpath(path), summarys[path]["coverage"]) + LongBow.scorePrinter(distribution, summarys[path]["coverage"], string) + + return True + +def commandLineMain(args, fileNames, testDir=""): + + testDirs = [] + if testDir: + testDirs.append(testDir) + fileNames = map(lambda fileName: os.path.abspath(fileName), fileNames) + filesAndTests = map(lambda fileName: [fileName, findTestExecutable(fileName, testDirs)], fileNames) + + filesWithNoTest = filter(lambda fileAndTest: fileAndTest[1] == None, filesAndTests) + if len(filesWithNoTest) != 0: + outputFormat = "%s has no corresponding test executable or coverage data.\n" + map(lambda filesAndTests: sys.stderr.write(outputFormat % (filesAndTests[0])), filesWithNoTest) + + gCovResults = map(lambda fileAndTestFile: GCov.getCoverage(fileAndTestFile[1]), filesAndTests) + + if args.summary is True: + displaySummary(args, filesAndTests, gCovResults) + elif args.average is True: + displayAverage(args, filesAndTests, gCovResults) + elif args.visual is True: + textVisual(args, filesAndTests, gCovResults) + elif args.explain is True: + explain(args, filesAndTests, gCovResults) + + return True diff --git a/longbow/src/python/site-packages/longbow/DoxygenReport.py b/longbow/src/python/site-packages/longbow/DoxygenReport.py new file mode 100755 index 00000000..46edf047 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/DoxygenReport.py @@ -0,0 +1,161 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import pprint +import subprocess +import difflib +import csv +import LongBow + +def concatenateContinuationLines(lines): + ''' + Parse doxygen log lines. + Lines that are indented by a space are continutations of the previous line. + ''' + result = list() + accumulator = "" + for line in lines: + line = line.rstrip() + if line.startswith(" ") == False and line.startswith(" ") == False: + if len(accumulator) > 0: + result.append(accumulator) + accumulator = line + else: + accumulator = accumulator + " " + line.lstrip() + + result.append(accumulator) + + return result + +def parseLine(line): + result = None + if not line.startswith("<"): + fields = line.split(":") + if len(fields) >= 4: + result = { "fileName" : fields[0].strip(), + "lineNumber" : int(fields[1].strip()), + "type" : "documentation", + "severity" : fields[2].strip(), + "message" : " ".join(fields[3:]).strip()} + elif line.startswith("error"): + print line + elif len(line) > 0: + print "Consider using doxygen -s:", line + + return result + +def canonicalize(lines): + lines = concatenateContinuationLines(lines) + parsedLines = map(lambda line: parseLine(line), lines) + parsedLines = filter(lambda line: line != None, parsedLines) + return parsedLines + +def organize(entries): + result = dict() + + for entry in entries: + if not entry["fileName"] in result: + result[entry["fileName"]] = dict() + + entryByFile = result[entry["fileName"]] + + if not str(entry["lineNumber"]) in entryByFile: + entryByFile[str(entry["lineNumber"])] = list() + if not entry in entryByFile[str(entry["lineNumber"])]: + entryByFile[str(entry["lineNumber"])].append(entry) + + return result + +def textualSummary(distribution, documentation): + maxWidth = 0 + for entry in documentation: + if len(entry) > maxWidth: + maxWidth = len(entry) + + formatString ="%-" + str(maxWidth) + "s %8d %8d %.2f%%" + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + LongBow.scorePrinter(distribution, score, formatString % (entry, totalLines, badLines, score)) + return + +def textualAverage(distribution, documentation, format): + sum = 0.0 + + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + sum = sum + score + + if len(documentation) == 0: + averageScore = 100.0 + else: + averageScore = sum / float(len(documentation)) + + LongBow.scorePrinter(distribution, averageScore, format % averageScore) + +def csvSummary(distribution, documentation): + formatString ="documentation,%s,%d,%d,%.2f%%" + for entry in documentation: + badLines = len(documentation[entry]) + totalLines = LongBow.countLines(entry) + score = float(totalLines - badLines) / float(totalLines) * 100.0 + LongBow.scorePrinter(distribution, score, formatString % (entry, totalLines, badLines, score)) + return + + +def gradeAndPrint(targets, doxLogfile, problemsOnly=False, prefix=""): + with open(doxLogfile, 'r') as f: + lines = f.readlines() + + lines = canonicalize(lines) + + result = organize(lines) + + pp = pprint.PretyPrinter(intent=len(prefix)) + + distribution=[100, 95] + textualSummary(distribution, result) + return True + +def commandLineMain(args, fileNames): + if not args.summary and not args.average: + args.summary = True + + with open(args.doxygenlog, 'r') as f: + lines = f.readlines() + + lines = canonicalize(lines) + + result = organize(lines) + + pp = pprint.PrettyPrinter(indent=4) + #pp.pprint(result) + + distribution = eval(args.distribution) + if args.summary: + if args.output == "text": + textualSummary(distribution, result) + else: + csvSummary(distribution, result) + + if args.average: + textualAverage(distribution, result, "%.2f") diff --git a/longbow/src/python/site-packages/longbow/FileUtil.py b/longbow/src/python/site-packages/longbow/FileUtil.py new file mode 100755 index 00000000..ae3113f6 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/FileUtil.py @@ -0,0 +1,102 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import csv +import subprocess + +def readFileLines(fileName): + ''' + Get the entire file into memory as a list of lines. + ''' + result = None + + with open(fileName, "r") as file: + result = file.readlines() + + return result + +def readFileString(fileName): + ''' + Get the entire file into memory as a python string. + ''' + result = None + + if fileName != None and len(fileName) > 0: + with open (fileName, "r") as file: + result = file.read() + + return result + +def sourceFileNameToName(sourceFileName): + ''' + Given the path to a source file, return the name without any path components or trailing suffix. + ''' + name = os.path.basename(sourceFileName) + return name.split(".")[0] + +def canonicalizeFunctionName(functionName): + ''' + Given a function name that contains the initial '_' character, + strip it and return a canonicalised form of the same name suitable for a source file. + ''' + if functionName[0] == "_": + functionName = functionName[1:] + return functionName + +def isReservedName(functionName): + ''' + Given a canonicalized name, determine if it is a reserved name according to ISO/IEC 9899:2011 and ANSI Sec. 4.1.2.1, + identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. + ''' + if functionName[0] == '_' and functionName[1] == '_': + return True + elif functionName[0] == '_' and functionName[1].isupper(): + return True + return False + +def getDarwinTestableFunctions(objectFileName): + ''' + Retrieve a set of local and global function names within a file. + ''' + command = [ "/usr/bin/nm", "-gUm", objectFileName ] + + output = subprocess.check_output(command) + lines = output.splitlines() + + external = [] + internal = [] + for line in lines: + if line: + fields = line.split(" ") + if (len(fields) > 1) and (fields[1] == "(__TEXT,__text)"): + functionName = canonicalizeFunctionName(fields[3]) + + if not isReservedName(functionName): + if fields[2] == "external": + external.append( ( functionName ) ) + else: + internal.append( ( functionName ) ) + pass + pass + pass + pass + + external.sort() + internal.sort() + return { "Local": internal, "Global" : external } diff --git a/longbow/src/python/site-packages/longbow/GCov.py b/longbow/src/python/site-packages/longbow/GCov.py new file mode 100755 index 00000000..c2705fda --- /dev/null +++ b/longbow/src/python/site-packages/longbow/GCov.py @@ -0,0 +1,232 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import subprocess +import re +import sys +import pprint +import FileUtil +import Language_C + +class GCov: + def __init__(self): + return + +def canonicalizeLines(lines): + result = [] + accumulatedLine = "" + for line in lines: + line = line.strip() + if len(line) == 0: + if len(accumulatedLine.strip()) > 0: + result.append(accumulatedLine.strip()) + accumulatedLine = "" + elif "creating" in line: + if len(accumulatedLine.strip()) > 0: + result.append(accumulatedLine.strip()) + accumulatedLine = "" + result.append(line) + else: + accumulatedLine = accumulatedLine + " " + line + return result + +def executeGCovCommand(testExecutableFileName): + currentDirectory = os.getcwd() + targetDirectory = os.path.dirname(os.path.abspath(testExecutableFileName)) + testExecutableBaseName = os.path.basename(testExecutableFileName) + + os.chdir(targetDirectory) + objects = Language_C.findFiles("./", testExecutableBaseName+"*.o") + if not objects: + return + objdir = os.path.dirname(objects[0]) + gcdas = Language_C.findFiles("./", testExecutableBaseName+"*.gcda") + if not gcdas: + return + gcda = gcdas[0] + gcnos = Language_C.findFiles("./", testExecutableBaseName+"*.gcno") + if not gcnos: + return + gcno = gcnos[0] + proc = subprocess.Popen(['gcov', '-af', '-o='+objdir, '-gcda='+gcda, '-gcno='+gcno, testExecutableBaseName], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + os.chdir(currentDirectory) + + inputLines = map(lambda line: line.strip(), proc.stdout) + + return canonicalizeLines(inputLines) + +def parseFunctionLine(line): + # Function 'TestFixture_Global_TearDown' Lines executed:71.43% of 7" + search = re.search("Function '(.*)' Lines executed:(.*)% of (.*)", line, re.IGNORECASE) + + result = [] + if search: + functionName = search.group(1) + percentage = search.group(2) + totalLines = search.group(3) + result = { functionName : { "coverage" : float(percentage), "numberOfLines" : int(totalLines) } } + + return result + +def parseFileLine(testExecutableDirectoryName, line): + # File './../parc_Buffer.c' Lines executed:92.69% of 424 + search = re.search("File '(.*)' Lines executed:(.*)% of (.*)", line, re.IGNORECASE) + + result = { } + if search: + baseName = os.path.basename(search.group(1)); + fileName = os.path.abspath(testExecutableDirectoryName + "/" + baseName) + percentage = search.group(2) + totalLines = search.group(3) + result = { fileName : { "coverage" : float(percentage), "totalLines" : int(totalLines) } } + + return result + +def parseCreatingLine(testExecutableDirectoryName, line): + search = re.search("(.*):creating '(.*)'", line, re.IGNORECASE) + + result = None + if search: + baseName = os.path.basename(search.group(1)); + fileName = os.path.abspath(testExecutableDirectoryName + "/" + baseName) + baseName = os.path.basename(search.group(2)); + gcovFileName = os.path.abspath(testExecutableDirectoryName + "/" + baseName) + + result = { "fileName" : fileName, "gcovFileName" : gcovFileName, "gcovLines" : FileUtil.readFileLines(gcovFileName) } + + return result + + +def computeCoverageFromGCovLines(testExecutableDirectoryName, testExecutableFileName, lines): + ''' + This produces a dictionary consisting of: + + 'testedFiles' : dictionary containing as keys 'functions' and the name of a file that was tested + + The value of the key that is the name of a file that was tested is a dictionary containing the keys, + 'coverage', 'gcovFileName', and 'gcovLines' + + 'coverage' is the percentage of code executed + + 'testedFunctions' is a list containing lists consisting of the function name, the percent executed, and the number of lines in the function. + ''' + testedFiles = { } + testedFunctions = { } + gcovFileNames = [] + for line in lines: + if line.startswith("Function"): + element = parseFunctionLine(line) + testedFunctions.update(element) + elif line.startswith("File"): + element = parseFileLine(testExecutableDirectoryName, line) + testedFiles.update(element) + else: + element = parseCreatingLine(testExecutableDirectoryName, line) + if element != None: + fileName = element["fileName"] + del element["fileName"] + testedFiles[fileName].update(element) + pass + + result = { testExecutableFileName : { "testedFunctions" : testedFunctions, "testedFiles" : testedFiles } } + + return result + + +def noCoverage(): + result = { "testedFiles" : { }, "testedFunctions" : { } } + return result + +def getCoverage(testExecutableFileName): + ''' + ''' + if testExecutableFileName == None: + return None + + testExecutableFileName = os.path.abspath(testExecutableFileName) + testExecutableDirectoryName = os.path.dirname(testExecutableFileName) + gcovLines = executeGCovCommand(testExecutableFileName) + + return computeCoverageFromGCovLines(testExecutableDirectoryName, testExecutableFileName, gcovLines) + + +def selectGreaterCoverage(testedFileA, testedFileB): + result = testedFileB + if testedFileA["coverage"] >= testedFileB["coverage"]: + result = testedFileA + + return result + +def computeSummary(filesAndTests, newGCovResults): + ''' + First, for each target file named in the gcov results, find the corresponding testedFile and report the maximum coverage. + + If the target file is not in any of the testedFiles + + { targetFileName : { "coverage": percent, "veracity" : "direct" / "indirect" } } + ''' + + newGCovResults = filter(lambda entry: entry != None, newGCovResults) + + result = dict() + for entry in newGCovResults: + for testExecutableName in entry: + testExecutableCSourceName = Language_C.Module(testExecutableName).getCSourceName() + + for testedFileName in entry[testExecutableName]["testedFiles"]: + testedFile = entry[testExecutableName]["testedFiles"][testedFileName] + + if Language_C.Module(testedFileName).getTestExecutableName() == os.path.basename(testExecutableName): + result[testedFileName] = testedFile + result[testedFileName]["direct"] = "direct" + elif testedFileName in result: + bestCoverage = selectGreaterCoverage(testedFile, result[testedFileName]) + if result[testedFileName] != bestCoverage: + result[testedFileName] = bestCoverage + result[testedFileName]["direct"] = "indirect" + else: + result[testedFileName] = testedFile + result[testedFileName]["direct"] = "indirect" + + return result + +def computeAverage(filesAndTests, gcovResults): + summary = computeSuperSummary(filesAndTests, gcovResults) + + filesToAverage = removeTestSourceFiles(summary) + + score = 0.0 + + if len(filesToAverage) > 0: + sum = reduce(lambda x, y: x + y, map(lambda entry: summary[entry]["coverage"], filesToAverage)) + score = sum / float(len(filesToAverage)) + + return score + + +if __name__ == '__main__': + pp = pprint.PrettyPrinter(indent=4, width=132) + if True: + gcovResult = getCoverage("/Users/gscott/Documents/workspace/Distillery/Libparc/parc/algol/test/test_parc_JSON") + else: + lines = sys.stdin.readlines() + lines = canonicalizeLines(lines) + pp.pprint(lines) + + gcovResult = computeCoverageFromGCovLines("/Users/gscott/Documents/workspace/Distillery/Libparc/parc/algol/test/", lines) + + pp.pprint(gcovResult) diff --git a/longbow/src/python/site-packages/longbow/GCovSummary.py b/longbow/src/python/site-packages/longbow/GCovSummary.py new file mode 100755 index 00000000..bfa6710a --- /dev/null +++ b/longbow/src/python/site-packages/longbow/GCovSummary.py @@ -0,0 +1,42 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import subprocess +import re +import sys +import pprint +import FileUtil +import Language_C + + +def removeTestSourceFiles(gcovSummary): + deleteThese = filter(lambda entry: Language_C.Module(entry).isTestSourceName(), gcovSummary) + + for entry in deleteThese: + del gcovSummary[entry] + + return gcovSummary + + +def averageCoverage(summary): + score = 0.0 + + if len(summary) > 0: + sum = reduce(lambda x, y: x + y, map(lambda entry: summary[entry]["coverage"], summary)) + score = sum / float(len(summary)) + + return score diff --git a/longbow/src/python/site-packages/longbow/Language_C.py b/longbow/src/python/site-packages/longbow/Language_C.py new file mode 100755 index 00000000..85183133 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/Language_C.py @@ -0,0 +1,202 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import glob + +import fnmatch +import subprocess + +def findFiles(startDir, pattern): + matches = [] + for root, dirnames, filenames in os.walk(startDir): + for filename in fnmatch.filter(filenames, pattern): + matches.append(os.path.join(root, filename)) + + return matches + +def getLibPathForObject(libraryPath, filename): + ''' + Returns a path to an object file suitable for nm + ''' + result = '' + + command = ['/usr/bin/ar', '-t', libraryPath] + output = subprocess.check_output(command) + lines = output.splitlines() + + for line in lines: + tokens = line.split('.') + if tokens[0] == filename: + result = libraryPath + '(' + line + ')' + break + + return result + +class Module: + '''Represent a C language module. + A module consists of the file names of the C source, C header file, object file, and an executable file + def __init__(self, srcPath, objectDirs=[]): + self.path = self.initialzePath(srcPath) + if not objectDirs: + objectDirs = [self.path] + split = srcPath.split("/") + self.originalName = split[len(split) - 1] + self.originalBaseName = os.path.basename(srcPath) + tokens = self.originalBaseName.split('.') + self.fileName = tokens[0].replace("/","") + + if self.fileName.startswith("test_"): + self.fileName = self.fileName[5:] + + # Search for an appropriate object + self.objectPath = ""; + for objectDir in objectDirs: + if objectDir.endswith(".a"): + self.objectPath = getLibPathForObject(objectDir, self.fileName) + if self.objectPath: + break + else: + objectSearchPath = os.path.join(objectDir, self.fileName) + "*.o*" + ofiles = glob.glob(objectSearchPath); + if ofiles: + # if we've found some matches, assume we want the first. + self.objectPath = ofiles[0]; + break + return + + def isTestExecutableName(self): + return self.getTestExecutableName() == self.originalBaseName + + def isTestSourceName(self): + return self.getTestSourceName() == self.originalBaseName + + def isCSourceName(self): + return self.getCSourceName() == self.originalBaseName + + def isCHeaderName(self): + return self.getCHeaderName() == self.originalBaseName + + def getCSourceName(self): + return self.fileName + ".c" + + def getCHeaderName(self): + return self.fileName + ".h" + + def getPathToObjectFile(self): + return self.objectPath; + + def getExecutableName(self): + return self.fileName + + def getTestExecutableName(self): + return "test_" + self.fileName + + def getTestSourceName(self): + return self.getTestExecutableName() + ".c" + + def getNamespace(self): + sourceFileName = self.getCSourceName() + if (sourceFileName.find("_") >= 0): + stripped = sourceFileName[0:sourceFileName.index("_")] + return stripped + else: + return None + + def getModuleName(self): + sourceFileName = self.getCSourceName() + split = sourceFileName.split("/") + sourceFileName = split[len(split) - 1] + if (sourceFileName.find(".") >= 0): + stripped = sourceFileName[0:sourceFileName.index(".")] + return stripped + else: + return None + + def getModulePrefix(self): + sourceFileName = self.getCSourceName() + squashed = sourceFileName.replace("_", "") + if (squashed.find(".") >= 0): + return squashed[0:squashed.index(".")] + else: + return None + + def getTypeName(self): + sourceFileName = self.getCSourceName() + if (sourceFileName.find(".") >= 0 and sourceFileName.find("_") >= 0): + stripped = sourceFileName[(sourceFileName.index("_") + 1):sourceFileName.index(".")] + return stripped + else: + return None + + def getModulePath(self): + return self.path + + def initialzePath(self, sourceFileName): + parts = sourceFileName.split("/") + parts = parts[0:len(parts) - 1] + return '/'.join(map(str, parts)) + +if __name__ == '__main__': + cFile = Module("file.c.gcov") + if cFile.getCSourceName() != "file.c": + print "getCSourceName failed", cFile.getCSourceName() + + if cFile.getCHeaderName() != "file.h": + print "getCHeaderName failed", cFile.getCHeaderName() + + if cFile.getTestSourceName() != "test_file.c": + print "getTestSourceName failed", cFile.getTestSourceName() + + if cFile.getTestExecutableName() != "test_file": + print "getTestExecutableName failed", cFile.getTestExecutableName() + + if cFile.getNamespace() != None: + print "getNamespace failed", cFile.getNamespace() + + if cFile.getModuleName() != "file": + print "getModuleName failed", cFile.getModuleName() + + if cFile.getModulePrefix() != "file": + print "getModulePrefix failed", cFile.getModulePrefix() + + if cFile.getTypeName() != None: + print "getTypeName failed", cFile.getTypeName() + + cFile = Module("parc_Object.c.gcov") + if cFile.getCSourceName() != "parc_Object.c": + print "getCSourceName failed", cFile.getCSourceName() + + if cFile.getCHeaderName() != "parc_Object.h": + print "getCHeaderName failed", cFile.getCHeaderName() + + if cFile.getTestSourceName() != "test_parc_Object.c": + print "getTestSourceName failed", cFile.getTestSourceName() + + if cFile.getTestExecutableName() != "test_parc_Object": + print "getTestExecutableName failed", cFile.getTestExecutableName() + + if cFile.getNamespace() != "parc": + print "getNamespace failed", cFile.getNamespace() + + if cFile.getModuleName() != "parc_Object": + print "getModuleName failed", cFile.getModuleName() + + if cFile.getModulePrefix() != "parcObject": + print "getModulePrefix failed", cFile.getModulePrefix() + + if cFile.getTypeName() != "Object": + print "getTypeName failed", cFile.getTypeName() diff --git a/longbow/src/python/site-packages/longbow/LongBow.py b/longbow/src/python/site-packages/longbow/LongBow.py new file mode 100755 index 00000000..d1f0e77a --- /dev/null +++ b/longbow/src/python/site-packages/longbow/LongBow.py @@ -0,0 +1,96 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import sys + +ansiRed = "\x1b[31m"; +ansiGreen = "\x1b[32m"; +ansiYellow = "\x1b[33m"; +ansiMagenta = "\x1b[35m"; +ansiReset = "\x1b[0m"; + + +def buildRed(string): + if sys.stdout.isatty(): + return ansiRed + string + ansiReset + else: + return string + + +def buildGreen(string): + if sys.stdout.isatty(): + return ansiGreen + string + ansiReset + else: + return string + + +def buildYellow(string): + if sys.stdout.isatty(): + return ansiYellow + string + ansiReset + else: + return string + + +def score(distribution, score): + result = "red" + + if (score > distribution[0]): + result = "green" + elif (score > distribution[1]): + result = "yellow" + + return result + + +def scoreBuilder(distribution, score, string): + ''' + scores is a list of 2 decreasing values. + The first is the minimum score for green, the second is the minimum score for yellow. + The rest art red + ''' + if (score > distribution[0]): + return buildGreen(string) + elif (score > distribution[1]): + return buildYellow(string) + else: + return buildRed(string) + + +def scorePrinter(distribution, score, string): + print scoreBuilder(distribution, score, string) + + +def countLines(fileName): + i = 0 + with open(fileName) as f: + for i, l in enumerate(f): + pass + return i + 1 + + +def CFileNameToFunctionPrefix(fileName): + ''' + Given the name of a C source file or header file, + return the canonical name prefix for functions within that file. + For example, the input name "parc_Buffer.c" results in "parcBuffer_" + ''' + fileName = os.path.basename(fileName); + fileNameSpace = os.path.splitext(fileName)[0] + parts = fileNameSpace.partition("_") + result = None + if len(parts) == 3: + result = parts[0] + parts[2] + "_" + return result diff --git a/longbow/src/python/site-packages/longbow/NameReport.py b/longbow/src/python/site-packages/longbow/NameReport.py new file mode 100755 index 00000000..1d38b4ec --- /dev/null +++ b/longbow/src/python/site-packages/longbow/NameReport.py @@ -0,0 +1,818 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import subprocess +import argparse +import csv +import traceback + +import LongBow +from Language_C import Module +from FileUtil import * +from pprint import pprint + +class NoObjectFileException(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + + +# Global error string formatting map +conformanceErrorFormatMap = { + "NAMESPACE_MISMATCH" : "Function signature %s does not have the correct namespace prefix (%s)", + "MODULE_MISMATCH" : "Function signature %s does not have the correct module prefix (%s)", + "INVALID_STATIC_NAME" : "Local function signature %s must begin with an underscore '_'.", + "INVALID_GLOBAL_ENUM_NAME" : "Global enumeration prefix %s must match the module namespace %s.", + "INVALID_STATIC_ENUM_NAME" : "Local enumeration prefix %s must begin with an underscore '_'.", + "INVALID_GLOBAL_ENUM_VALUE_NAME" : "Global enumeration value prefix %s must match the enum name %s.", + "INVALID_GLOBAL_TYPEDEF_NAME" : "Global typedef prefix %s must match the module namespace %s.", + "INVALID_STATIC_TYPEDEF_NAME" : "Local typedef prefix %s must begin with an underscore '_'.", +} + +def tuplesListToCSV(points): + ''' + Convert a list of tuples -- data points -- to a list of CSV-formatted strings. + ''' + lines = [] + for point in points: + line = "" + for i in range(len(point) - 1): + line = line + str(point[i]) + "," + line = line + str(point[-1]) + lines.append(line) + return lines + +def tuplesListToPrettyText(points, distribution = [99, 90]): + ''' + Convert a list of tuples -- data points -- to a list of colorized strings based + on the provided distribution. + ''' + lines = [] + for point in points: + line = "" + for i in range(len(point) - 1): + line = line + str(point[i]) + " " + line = line + str(point[-1]) + lines.append(LongBow.scoreBuilder(distribution, point[-1], line)) + return lines + +def writeListToStream(llist, fileHandle, appendNewLine = True): + ''' + Write the list of lines to the given file stream handle, appending a new line after + every line if told to do so. + ''' + for line in llist: + fileHandle.write(line) + if appendNewLine: + fileHandle.write("\n") + +def isValidModuleName(namespace, typeName, moduleName): + ''' + Determine if a given module name is valid (conforming) given the namespace and typename. + + For example, a module in the `parc` namespace with typename `JSON` must be named `parc_JSON`. + ''' + constructedName = namespace + "_" + typeName + return (moduleName == constructedName) + +def isValidFunctionName(namespace, modulePrefix, functionName, scope): + ''' + Determine if a given function name is valid (conforming) given the namespace and typename. + ''' + if (scope != "Local"): + if(not functionName.startswith(namespace)): + return False, conformanceErrorFormatMap["NAMESPACE_MISMATCH"] % ('"' + functionName + '"', namespace) + elif (not functionName.startswith(modulePrefix)): + return False, conformanceErrorFormatMap["MODULE_MISMATCH"] % ('"' + functionName + '"', modulePrefix) + else: + return True, "" + elif (scope == "Local" and not functionName.startswith("_")): + return False, conformanceErrorFormatMap["INVALID_STATIC_NAME"] % ('"' + functionName + '"') + else: + return True, "" + +def isValidTypedefName(typePrefix, name, static): + ''' + Determine if a given typedef name is valid (conforming) given the namespace and typename. + ''' + originalName = name + originalTypePrefix = typePrefix + + name = name.lower() + typePrefix = typePrefix.lower() + + if ((not static) and name.startswith(typePrefix)) and originalName[0].isupper(): + return True, "" + elif ((not static) and (not name.startswith(typePrefix))): + return False, conformanceErrorFormatMap["INVALID_GLOBAL_TYPEDEF_NAME"] % ('"' + originalName + '"', originalTypePrefix) + elif (static and name.startswith('_')): + return True, "" + else: + return False, conformanceErrorFormatMap["INVALID_STATIC_TYPEDEF_NAME"] % ('"' + originalName + '"') + +def isValidEnumName(typePrefix, name, values, static): + ''' + Determine if a given enumeration name is valid (conforming) given the namespace and typename. + ''' + originalName = name + originalTypePrefix = typePrefix + + name = name.lower() + typePrefix = typePrefix.lower() + + if ((not static) and name.startswith(typePrefix)) and originalName[0].isupper(): + pass + elif ((not static) and (not name.startswith(typePrefix))): + return False, conformanceErrorFormatMap["INVALID_GLOBAL_ENUM_NAME"] % ('"' + originalName + '"', originalTypePrefix) + elif (static and name.startswith('_')): + pass + else: + return False, conformanceErrorFormatMap["INVALID_STATIC_ENUM_NAME"] % ('"' + originalName + '"') + + for enumVal in values: + if ((not static) and not enumVal.startswith(originalName)): + return False, conformanceErrorFormatMap["INVALID_GLOBAL_ENUM_VALUE_NAME"] % ('"' + enumVal + '"', originalName) + return True, "" + +def getTypedefs(path, source): + ''' + Retrieve the names of typedefs (excluding enums) in a given file by parsing the file for + typedef specifications. This walks over every line in the file searching for each one, + since we cannot extract enum names nicely using linux tools. + ''' + typedefs = [] + pathToFile = os.path.join(path, source) + if os.path.isfile(pathToFile): + fin = open(os.path.join(path, source), 'r') + lines = fin.readlines() + i = 0 # LC + while (i < len(lines)): + line = lines[i].strip() + if not line.startswith("//"): + values = [] + if "typedef" in line and "enum" not in line: # go to the end of the typedef + if "{" in line: + while "}" not in line: + i = i + 1 + line = lines[i].strip() + name = line.replace("}","").replace(";","").strip() + typedefs.append(name) + else: + splits = line.split(" ") + if "struct" in splits[1]: + name = splits[3].replace(";","") + typedefs.append(name.strip()) + else: + pass + i = i + 1 + return typedefs + +def getEnumerations(path, source): + ''' + Retrieve the names of enumerations in a given file by parsing the file for enum specifications. + This walks over every line in the file searching for enums, since we cannot extract enum names + nicely using linux tools. + ''' + enums = [] + pathToFile = os.path.join(path, source) + if os.path.isfile(pathToFile): + fin = open(os.path.join(path, source), 'r') + lines = fin.readlines() + i = 0 # LC + while (i < len(lines)): + line = lines[i].strip() + if not line.startswith("//"): + values = [] + if "typedef enum" in line: # go to the end of the enumeration + while (i + 1 < len(lines) and line.find("}") < 0): + i = i + 1 + line = lines[i].strip() + values.append(line) # append each string value + if (line.find("}") >= 0): + name = line.replace("}","").replace(";","") + values.pop(len(values) - 1) + enums.append((name.strip(), values)) + i = i + 1 + return enums + +def getTypedefsFromFiles(fileInfoList): + ''' + Get the typedefs from each file in the fileInfoList. + + Each element in fileInfoList is a tuple of the form (path, filename, staticTag), + where staticTag is a flag used to indicate if the typedefs in said file should + be treated as static. + ''' + allTypedefs = [] + for (path, fileName, staticTag) in fileInfoList: + typedefs = getTypedefs(path, fileName) + for typedef in typedefs: + allTypedefs.append((typedef, staticTag)) + return allTypedefs + +def getEnumerationsFromFiles(fileInfoList): + ''' + Get the enums from each file in the fileInfoList. + + Each element in fileInfoList is a tuple of the form (path, filename, staticTag), + where staticTag is a flag used to indicate if the enums in said file should + be treated as static. + ''' + allEnums = [] + for (path, fileName, staticTag) in fileInfoList: + enums = getEnumerations(path, fileName) + for (enumName, values) in enums: + allEnums.append((enumName, values, staticTag)) + return allEnums + +class FunctionConformanceContainer(): + def __init__(self, module): + self.path = module.getModulePath() + self.module = module + self.failedFunctions = [] + self.passedFunctions = [] + + if (len(self.path) > 0): + self.fullPath = self.path + os.sep + module.getCSourceName() + else: + self.fullPath = module.getCSourceName() + + self.computeConformance() + + def computeConformance(self): + functionDictionary = {} + objectFileName = self.module.getPathToObjectFile() + sourceFileName = os.path.join(self.path, self.module.getCSourceName()) + temp = objectFileName + if '.a' in temp: # If this is a path into an archive + temp = temp.split('(')[0] + if not os.path.isfile(temp): + raise NoObjectFileException("You must compile " + str(sourceFileName) + " to generate a corresponding object or provide a special object file path") + + try: + functionDictionary = getDarwinTestableFunctions(objectFileName) + except: + raise Exception("You must compile " + str(sourceFileName) + " to generate a corresponding object or provide a special object file path") + + namespace = self.module.getNamespace() + modulePrefix = self.module.getModulePrefix() + + # Find all passing/failing functions + if (namespace != None and modulePrefix != None): + for scope in functionDictionary: + for functionName in functionDictionary[scope]: + isValid, reason = isValidFunctionName(namespace, modulePrefix, functionName, scope) + if isValid: + self.addPassedFunction(functionName) + else: + self.addFailedFunction(functionName, reason) + + def containsMainFunction(self): + for (functionName, reason) in self.failedFunctions: + if (functionName.strip() == "main" or functionName.strip().startswith("main")): + return True + for functionName in self.passedFunctions: + if (functionName.strip() == "main" or functionName.strip().startswith("main")): + return True + return False + + @staticmethod + def getType(): + return "function-names" + + def addFailedFunction(self, function, reason): + self.failedFunctions.append((function, reason)) + + def getFailedFunctions(self): + return self.failedFunctions + + def addPassedFunction(self, function): + self.passedFunctions.append(function) + + def getPassedFunctions(self): + return self.passedFunctions + + def analyzeConformance(self): + ''' + Convert the raw pass/fail function results into a set of individual + data points (finegrain results) and overall percentage. + ''' + numPassed = len(self.passedFunctions) + numFailed = len(self.failedFunctions) + + self.percentage = 100.0 + self.points = [] + + if (numPassed + numFailed > 0): # skip invalid entries + self.percentage = float(float(numPassed) / float(numFailed + numPassed)) * 100.0 + + # Data point schema: + # namespace, moduleName, targetName, topic, line, col, score + for fname in self.passedFunctions: + data = ["function-name", fname, 100.0] + self.points.append(data) + + for (fname, reason) in self.failedFunctions: + data = ["function-name", fname, reason, 0.0] + self.points.append(data) + + def getNumberOfPassed(self): + return len(self.passedFunctions) + + def getNumberOfFailed(self): + return len(self.failedFunctions) + + def totalCSV(self): + return tuplesListToCSV(map(lambda point : [self.fullPath] + point, self.points)) + + def totalText(self, distribution): + formattedLines = tuplesListToPrettyText(self.points, distribution) + return map(lambda formattedLine : self.fullPath + " " + formattedLine, formattedLines) + + def summaryCSV(self): + line = [(self.getType(), self.percentage)] + return tuplesListToCSV(line) + + def summaryText(self, distribution): + line = [(self.getType(), self.percentage)] + return tuplesListToPrettyText(line, distribution) + + def getScore(self): + return (self.getType(), self.percentage) + + +class EnumConformanceContainer(): + def __init__(self, module): + self.path = module.getModulePath() + self.module = module + self.failedEnums = [] + self.passedEnums = [] + + if (len(self.path) > 0): + self.fullPath = self.path + os.sep + module.getCSourceName() + else: + self.fullPath = module.getCSourceName() + + self.computeConformance() + + def computeConformance(self): + sourceFileName = self.module.getCSourceName() + headerFileName = self.module.getCHeaderName() + + enums = getEnumerationsFromFiles([(self.path, sourceFileName, True), (self.path, headerFileName, False)]) + modulePrefix = self.module.getModulePrefix() + if (modulePrefix != None): + for (enumName, values, staticTag) in enums: + isValid, reason = isValidEnumName(modulePrefix, enumName, values, staticTag) + if isValid: + self.addPassedEnum(enumName) + else: + self.addFailedEnum(enumName, reason) + + @staticmethod + def getType(): + return "enum-names" + + def addFailedEnum(self, enum, reason): + self.failedEnums.append((enum, reason)) + + def getFailedEnums(self): + return self.failedEnums + + def addPassedEnum(self, enum): + self.passedEnums.append(enum) + + def getPassedEnums(self): + return self.passedEnums + + def analyzeConformance(self): + ''' + Convert the raw pass/fail enum results into a set of individual + data points (finegrain results) and overall percentage. + ''' + self.enumPercentage = 100.0 + self.points = [] + numPassed = len(self.passedEnums) + numFailed = len(self.failedEnums) + + if (numPassed + numFailed > 0): + self.enumPercentage = float((float(numPassed) / float(numPassed + numFailed)) * 100) + + for ename in self.passedEnums: + data = ["enum-name", ename, 100.0] + self.points.append(data) + + for (ename, reason) in self.failedEnums: + data = ["enum-name", ename, reason, 0.0] + self.points.append(data) + + def getNumberOfPassed(self): + return len(self.passedEnums) + + def getNumberOfFailed(self): + return len(self.failedEnums) + + def totalCSV(self): + return tuplesListToCSV(map(lambda point : [self.fullPath] + point, self.points)) + + def totalText(self, distribution): + formattedLines = tuplesListToPrettyText(self.points, distribution) + return map(lambda formattedLine : self.fullPath + " " + formattedLine, formattedLines) + + def summaryCSV(self): + line = [(self.getType(), self.enumPercentage)] + return tuplesListToCSV(line) + + def summaryText(self, distribution): + line = [(self.getType(), self.enumPercentage)] + return tuplesListToPrettyText(line, distribution) + + def getScore(self): + return (self.getType(), self.enumPercentage) + +class TypedefConformanceContainer(): + def __init__(self, module): + self.path = module.getModulePath() + self.module = module + self.failedTypedefs = [] + self.passedTypedefs = [] + + if (len(self.path) > 0): + self.fullPath = self.path + os.sep + module.getCSourceName() + else: + self.fullPath = module.getCSourceName() + + self.computeConformance() + + def computeConformance(self): + sourceFileName = self.module.getCSourceName() + headerFileName = self.module.getCHeaderName() + + typedefs = getTypedefsFromFiles([(self.path, sourceFileName, True), (self.path, headerFileName, False)]) + + modulePrefix = self.module.getModulePrefix() + if (modulePrefix != None): + for (typedefName, staticTag) in typedefs: + isValid, reason = isValidTypedefName(modulePrefix, typedefName, staticTag) + if isValid: + self.addPassedTypedef(typedefName) + else: + self.addFailedTypedef(typedefName, reason) + + @staticmethod + def getType(): + return "typedef-names" + + def addFailedTypedef(self, typedef, reason): + self.failedTypedefs.append((typedef, reason)) + + def getFailedTypedefs(self): + return self.failedTypedefs + + def addPassedTypedef(self, typedef): + self.passedTypedefs.append(typedef) + + def getPassedTypedefs(self): + return self.passedTypedefs + + def analyzeConformance(self): + ''' + Convert the raw pass/fail typedef results into a set of individual + data points (finegrain results) and overall percentage. + ''' + self.points = [] + self.typedefPercentage = 100.0 + numPassed = len(self.passedTypedefs) + numFailed = len(self.failedTypedefs) + if (numPassed + numFailed > 0): + self.typedefPercentage = float(float(numPassed) / float(numFailed + numPassed)) * 100 + + for tName in self.passedTypedefs: + data = ["typedef-name", tName, 100.0] + self.points.append(data) + + for (tName, reason) in self.failedTypedefs: + data = ["typedef-name", tName, reason, 0.0] + self.points.append(data) + + def getNumberOfPassed(self): + return len(self.passedTypedefs) + + def getNumberOfFailed(self): + return len(self.failedTypedefs) + + def totalCSV(self): + return tuplesListToCSV(map(lambda point : [self.fullPath] + point, self.points)) + + def totalText(self, distribution): + formattedLines = tuplesListToPrettyText(self.points, distribution) + return map(lambda formattedLine : self.fullPath + " " + formattedLine, formattedLines) + + def summaryCSV(self): + line = [(self.getType(), self.typedefPercentage)] + return tuplesListToCSV(line) + + def summaryText(self, distribution): + line = [(self.getType(), self.typedefPercentage)] + return tuplesListToPrettyText(line, distribution) + + def getScore(self): + return (self.getType(), self.typedefPercentage) + +class ModuleConformanceContainer(): + ''' + This conformance container stores a collection of individual type naming + conformance results within a particular module, and uses the information + contained therein to provide total finegrain and summarized + results of the conformance results for each type. + ''' + + def __init__(self, module): + self.conformanceContainers = [] + self.path = module.getModulePath() + self.module = module + self.validName = False + self.process = True + + if (len(self.path) > 0): + self.fullPath = self.path + os.sep + module.getCSourceName() + else: + self.fullPath = module.getCSourceName() + + def setProcess(self, value): + self.process = value + + def processModule(self): + return self.process + + def addConformanceContainer(self, complianceContainer): + self.conformanceContainers.append(complianceContainer) + + def analyzeConformance(self): + for container in self.conformanceContainers: + container.analyzeConformance() + + def getNumberOfPassed(self): + tuples = [] + for container in self.conformanceContainers: + tuples.append((container.getType(), container.getNumberOfPassed())) + return tuples # list of (topic, # of passed) + + def getNumberOfFailed(self): + tuples = [] + for container in self.conformanceContainers: + tuples.append((container.getType(), container.getNumberOfFailed())) + return tuples # list of (topic, # of failed) + + def totalCSV(self): + csvTuples = [] + for container in self.conformanceContainers: + csvTuples = csvTuples + container.totalCSV() + return csvTuples + + def totalText(self, distribution): + textTuples = [] + for container in self.conformanceContainers: + textTuples = textTuples + container.totalText(distribution) + return textTuples + + def summaryCSV(self): + singleTuple = [self.fullPath] + for container in self.conformanceContainers: + csvGroup = container.summaryCSV() + singleTuple = singleTuple + [csvGroup[-1]] + return tuplesListToCSV([tuple(singleTuple)]) + + def summaryText(self, distribution, divider=' '): + formattedLine = self.fullPath + for container in self.conformanceContainers: + lineGroup = container.summaryText(distribution)[0].split(" ") + formattedLine = formattedLine + divider + lineGroup[-2] + ' ' + lineGroup[-1] + return [formattedLine] + + def getScores(self): + scores = {} + for container in self.conformanceContainers: + scoreKey, scoreVal = container.getScore() + scores[scoreKey] = scoreVal + return scores + +class ModuleSetConformanceContainer(): + ''' + This conformance container stores a collection of individual module naming + conformance results, and uses the information contained therein to provide + summaries of conformance results. + ''' + + def __init__(self): + self.conformanceList = [] + + def addConformanceContainer(self, container): + self.conformanceList.append(container) + + def analyzeConformance(self): + passed = {} # passed type-number bucket + failed = {} # failed type-number bucket + + for container in self.conformanceList: + passedSet = container.getNumberOfPassed() + for (conformanceType, number) in passedSet: + if (conformanceType in passed): + passed[conformanceType] = passed[conformanceType] + number + else: + passed[conformanceType] = number + failedSet = container.getNumberOfFailed() + for (conformanceType, number) in failedSet: + if (conformanceType in failed): + failed[conformanceType] = failed[conformanceType] + number + else: + failed[conformanceType] = number + + self.typeConformancePercentages = {} + for conformanceType in passed: + total = passed[conformanceType] + failed[conformanceType] + percentage = 100.0 + if (total > 0): + percentage = (float(passed[conformanceType]) / float(total)) * 100.0 + self.typeConformancePercentages[conformanceType] = percentage + + def summaryCSV(self): + collatedTuple = ["average-scores"] + for conformanceType in self.typeConformancePercentages: + collatedTuple.append(conformanceType) # append type + collatedTuple.append(self.typeConformancePercentages[conformanceType]) # append percentage + return tuplesListToCSV([tuple(collatedTuple)]) + + def summaryText(self, distribution): + formattedLine = "average-scores" + for conformanceType in self.typeConformancePercentages: + prettyTypeText = tuplesListToPrettyText([(conformanceType, self.typeConformancePercentages[conformanceType])])[0] + formattedLine = formattedLine + " " + prettyTypeText + return [formattedLine] + +def computeModuleNameConformance(module): + ''' + Compute the module name conformance. There is no container for this result + since it's a simple boolean. + ''' + namespace = module.getNamespace() + moduleName = module.getModuleName() + typeName = module.getTypeName() + + if (namespace != None and moduleName != None and typeName != None): + return isValidModuleName(namespace, typeName, moduleName) + else: + return False + +def computeModuleConformance(module): + ''' + Compute the naming conformance results for an entire module, + which includes conformance results for all types contained therein. + ''' + moduleContainer = ModuleConformanceContainer(module) + + # Get the compliance results for functions, memorizing whether or not a main function was seen + functionContainer = FunctionConformanceContainer(module) + moduleContainer.addConformanceContainer(functionContainer) + moduleContainer.setProcess(not functionContainer.containsMainFunction()) + + # Now handle enums, typedefs, etc. + moduleContainer.addConformanceContainer(EnumConformanceContainer(module)) + moduleContainer.addConformanceContainer(TypedefConformanceContainer(module)) + moduleContainer.setValidName = computeModuleNameConformance(module) + + # Now that we have the data, run over it to generate the results + moduleContainer.analyzeConformance() + + return moduleContainer + +def getConformanceHeaders(): + headers = [FunctionConformanceContainer.getType(), EnumConformanceContainer.getType(), TypedefConformanceContainer.getType()] + return headers + +def gradeAndPrint(targets, objectDirs, problemsOnly=False, printPrefix=""): + if len(targets) < 1: + print "No Files To Grade" + return + + distribution = [99, 90] + maxFileNameLength = max(max(map(lambda target: len(target), targets)), len("File Name")) + + moduleConformanceSet = ModuleSetConformanceContainer() + headers = getConformanceHeaders() + pformat = '{prefix}{:<{maxFileNameLength}}' + nformat = pformat + for header in headers: + nformat = nformat + '{:>15}' + print nformat.format('File Name', *headers, prefix=printPrefix, maxFileNameLength=maxFileNameLength) + + + for target in targets: + module = Module(target, objectDirs) + if module.isTestSourceName(): + continue + fileNamePrefix = module.getModuleName() + path = module.getModulePath() + try: + moduleConformance = computeModuleConformance(module) + if not moduleConformance.processModule(): + pass + else: + moduleConformanceSet.addConformanceContainer(moduleConformance) + scores = moduleConformance.getScores() + minScore = 100.0 + for key in scores: + score = scores[key] + if score < minScore: + minScore = score + scores[key] = '%3.1f'%score + if problemsOnly and minScore == 100.0: + continue + printVals=[] + for hval in headers: + score = 'N/A' + if hval in scores: + score = scores[hval] + printVals.append(score) + line = nformat.format(target, *printVals, prefix=printPrefix, maxFileNameLength=maxFileNameLength) + LongBow.scorePrinter(distribution, minScore, line) + except NoObjectFileException as e: + eformat = pformat + "Could Not Grade: No .o file found for file" + line = eformat.format(target, prefix=printPrefix, maxFileNameLength=maxFileNameLength, msg=e) + print LongBow.buildRed(line) + pass + except Exception as e: + eformat = pformat + "Could Not Grade: {msg}" + line = eformat.format(target, prefix=printPrefix, maxFileNameLength=maxFileNameLength, msg=e) + print LongBow.buildRed(line) + pass + moduleConformanceSet.analyzeConformance() + + +def commandLineMain(args, targets, objectDir): + distribution = eval(args.distribution) + moduleConformanceSet = ModuleSetConformanceContainer() + + summary = args.summary + average = args.average + finegrain = args.finegrain + if not (summary or average or finegrain): + summary = True + + objectDirs = [objectDir] + for i in range(len(targets)): + module = Module(targets[i], objectDirs) + prefix = module.getModuleName() + path = module.getModulePath() + + tb = None + try: + moduleConformance = computeModuleConformance(module) + if not moduleConformance.processModule(): + print >> sys.stderr, "Skipping module " + str(prefix) + ": contains a `main` function" + else: + moduleConformanceSet.addConformanceContainer(moduleConformance) + + if summary: + if args.output == "text": + writeListToStream(moduleConformance.summaryText(distribution), sys.stdout) + else: + writeListToStream(moduleConformance.summaryCSV(), sys.stdout) + + if finegrain: + if args.output == "text": + writeListToStream(moduleConformance.totalText(distribution), sys.stdout) + else: + writeListToStream(moduleConformance.totalCSV(), sys.stdout) + + except Exception as e: + tb = traceback.format_exc() + print >> sys.stderr, "Error: can't analyze conformance of " + os.path.join(path, prefix) + ": " + str(e) + finally: + if tb != None and args.trace: + print tb + pass + + moduleConformanceSet.analyzeConformance() + if average: + if args.output == "text": + writeListToStream(moduleConformanceSet.summaryText(distribution), sys.stdout) + else: + writeListToStream(moduleConformanceSet.summaryCSV(), sys.stdout) diff --git a/longbow/src/python/site-packages/longbow/StyleReport.py b/longbow/src/python/site-packages/longbow/StyleReport.py new file mode 100755 index 00000000..7e8d72e0 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/StyleReport.py @@ -0,0 +1,382 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import os +import tempfile +import subprocess +import difflib +import csv +import argparse + +import LongBow +import ANSITerm +import FileUtil +import pprint + +def getExemplar(fileName, command, config): + """Create the exemplar formatted file into memory as a string""" + + with open(fileName) as inputFile: + result = subprocess.check_output([command, "-q", "-c", config], stdin=inputFile) + return result; + + +def diff(exemplar, fileName): + d = difflib.Differ() + differ = d.compare(exemplar.splitlines(), fileName.splitlines()) + return differ + + +class Ratchet: + def __init__(self): + self.currentValue = 0 + self.signal = 0 + + def value(self): + return self.currentValue + + def toggle(self, signal): + if self.signal == "-": + if signal == "-": + self.currentValue = self.currentValue + 1 + elif signal == "?": + self.currentValue = self.currentValue + 1 + self.signal = 0 + else: + self.currentValue = self.currentValue + 1 + self.signal = 0 + pass + elif self.signal == "+": + if signal == "-": + self.currentValue = self.currentValue + 1 + elif signal == "?": + self.currentValue = self.currentValue + 1 + self.signal = 0 + else: + self.currentValue = self.currentValue + 1 + self.signal = 0 + pass + else: + self.signal = signal; + + return self.currentValue + + +def computeNonCompliantLines(differ): + lines = 0 + changes = Ratchet() + + for l in differ: + if l.startswith('-'): + changes.toggle(l[0]) + lines = lines - 1 + elif l.startswith('+'): + changes.toggle(l[0]) + lines = lines + 1 + elif l.startswith('?'): + pass + elif l.startswith(' '): + lines = lines +1 + else: + print "What is this:", l + + return changes.value() + + +def reportWhy(differ): + print '\n'.join(diff) + return + + +class SyntaxCompliance: + def __init__(self, fileName, exemplarCommand, exemplarConfig): + self.fileName = fileName + self.nonCompliantLines = 0 + self.score = 0 + self.exemplarCommand = exemplarCommand + self.exemplarConfig = exemplarConfig + try: + self.fileData = FileUtil.readFileString(self.fileName) + self.totalLines = len(self.fileData.splitlines()) + except IOError, e: + print >> sys.stderr, e + sys.exit(1) + pass + + def check(self): + self.exemplarData = getExemplar(self.fileName, self.exemplarCommand, self.exemplarConfig) + differ = diff(self.fileData, self.exemplarData) + + self.nonCompliantLines = computeNonCompliantLines(differ) + + return self + + def report(self): + result = { "fileName" : self.fileName, + "label": "style", + "score": self.getScore(), + "totalLines" : self.getTotalLines(), + "nonCompliantLines" : self.getNonCompliantLines() + } + return result + + def getFileName(self): + return self.fileName + + def getExemplarCommand(self): + return self.exemplarCommand; + + def getExemplarConfig(self): + return self.exemplarConfig; + + def getScore(self): + result = 0 + try: + result = int(100 * (1.0 - (float(self.getNonCompliantLines()) / float(self.getTotalLines())))) + except ZeroDivisionError: + pass + return result + + def getTotalLines(self): + return self.totalLines + + def getNonCompliantLines(self): + return self.nonCompliantLines + + def explain(self): + self.exemplarData = getExemplar(self.fileName, self.exemplarCommand, self.exemplarConfig) + differ = diff(self.fileData, self.exemplarData) + + ansiTerm = ANSITerm.ANSITerm() + + for l in differ: + if l[0] == '-': + ansiTerm.printColorized("red", l) + elif l[0] == '+': + ansiTerm.printColorized("green", l) + elif l[0] == '?': + ansiTerm.printColorized("yellow", l[0:len(l)-1]) + else: + print l + pass + return + + +def csvScore(distribution, report): + string = "style,%s,%d,%d,%.2f" % (report["fileName"], report["totalLines"], report["nonCompliantLines"], report["score"]) + LongBow.scorePrinter(distribution, report["score"], string) + return + + +def csvAverage(distribution, complianceList): + scores = map(lambda target: target.getScore(), complianceList) + sum = reduce(lambda sum, score : sum + score, scores) + value = float(sum) / float(len(complianceList)) + LongBow.scorePrinter(distribution, value, "%.2f" % (value)) + return + + +def csvTotal(distribution, complianceList): + totalLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getTotalLines(), complianceList)) + totalNonCompliantLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getNonCompliantLines(), complianceList)) + value = 100.0 - (100.0 * float(totalNonCompliantLines) / float(totalLines)) + LongBow.scorePrinter(distribution, value, "%.2f" % (value)) + return + + +def csvSummary(distribution, complianceList): + map(lambda target: csvScore(distribution, target.report()), complianceList) + return + + +def textScore(distribution, report, maxFileNameLength, prefix=""): + ''' + + ''' + format = "%s%-*s %6d %6d %6.2f" + string = format % (prefix, maxFileNameLength, report["fileName"], report["totalLines"], report["nonCompliantLines"], report["score"]) + LongBow.scorePrinter(distribution, report["score"], string) + return + + +def textAverage(distribution, complianceList): + scores = map(lambda target: target.getScore(), complianceList) + sum = reduce(lambda sum, score : sum + score, scores) + value = float(sum) / float(len(complianceList)) + LongBow.scorePrinter(distribution, value, "%.2f" % (value)) + return + + +def textTotal(distribution, complianceList): + totalLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getTotalLines(), complianceList)) + totalNonCompliantLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getNonCompliantLines(), complianceList)) + value = 100.0 - (100.0 * float(totalNonCompliantLines) / float(totalLines)) + LongBow.scorePrinter(distribution, value, "%.2f" % (value)) + return + + +def textSummary(distribution, complianceList, prefix=""): + if len(complianceList) > 0: + maxFileNameLength = max(max(map(lambda target: len(target.getFileName()), complianceList)), len("File Name")) + + print "%s%-*s %6s %6s %6s" % (prefix, maxFileNameLength, "File Name", "Lines", "Errors", "Score") + map(lambda target: textScore(distribution, target.report(), maxFileNameLength, prefix), complianceList) + + return + + +def textVisual(complianceList): + map(lambda target: target.explain(), complianceList) + return + + +def openDiff(sourceFile, exemplarCommand, exemplarConfig): + exemplar = getExemplar(sourceFile, exemplarCommand, exemplarConfig); + temporaryExemplarFile = tempfile.NamedTemporaryFile(suffix=".c", delete=False) + try: + with open(temporaryExemplarFile.name, "w") as exemplarOutput: + exemplarOutput.write(exemplar) + + subprocess.check_output(["opendiff", sourceFile, temporaryExemplarFile.name, "-merge", sourceFile]) + finally: + pass + + return + + +def displaySummary(args, complianceList): + distribution = eval(args.distribution) + + if args.output == "text": + textSummary(distribution, complianceList) + elif args.output == "gui": + textSummary(distribution, complianceList) + else: + csvSummary(distribution, complianceList) + return + + +def displayAverage(args, complianceList): + + distribution = eval(args.distribution) + + if args.output == "text": + textAverage(distribution, complianceList) + elif args.output == "gui": + textAverage(distribution, complianceList) + else: + csvAverage(distribution, complianceList) + return + + +def displayTotal(args, complianceList): + distribution = eval(args.distribution) + + if args.output == "text": + textTotal(distribution, complianceList) + elif args.output == "gui": + textTotal(distribution, complianceList) + else: + csvTotal(distribution, complianceList) + return + + +def guiVisual(args, complianceList): + map(lambda target: openDiff(target.getFileName(), target.getExemplarCommand(), target.getExemplarConfig()), complianceList) + return + + +def displayVisual(args, complianceList): + if args.output == "text": + textVisual(complianceList) + elif args.output == "gui": + guiVisual(args, complianceList) + else: + print >> sys.stderr, "Unsupported output format '%s'. Expected 'text' or 'gui'." % (args.output) + sys.exit(1) + return + + +def sortComplianceList(args, complianceList): + + sorter = { + "name" : { "function" : lambda k: k.getFileName(), "reverse" : False }, + "descending-name" : { "function" : lambda k: k.getFileName(), "reverse" : True }, + "score" : { "function" : lambda k: k.getScore(), "reverse" : False }, + "descending-score" : { "function" : lambda k: k.getScore(), "reverse" : True }, + "size" : { "function" : lambda k: k.getTotalLines(), "reverse" : False }, + "descending-size" : { "function" : lambda k: k.getTotalLines(), "reverse" : True }, + } + + if args.key == "help": + print >> sys.stderr, "Supported sort keys:" + map(lambda k: sys.stderr.write("'" + k + "' "), sorted(sorter)) + print + sys.exit(1) + + if args.key in sorter: + complianceList = sorted(complianceList, key=sorter[args.key]["function"], reverse=sorter[args.key]["reverse"]) + else: + print >> sys.stderr, "Unsupported sort key '%s'. Type '--key help'" % (args.key) + sys.exit(1) + + return complianceList + + +def exclude(args, complianceList): + excluded = map(lambda token : token.strip(), args.exclude.split(",")) + complianceList = filter(lambda entry: LongBow.score(eval(args.distribution), entry.getScore()) not in excluded, complianceList) + + return complianceList + + +def gradeAndPrint(targets, exemplarCommand, exemplarConfig, problemsOnly=False, prefix=""): + complianceList = [] + problemList = [] + for target in targets: + try: + complianceList.append(SyntaxCompliance(target, exemplarCommand, exemplarConfig).check()) + except: + problemList.append(target) + pass + complianceList = sorted(complianceList, key=lambda k: k.getFileName()) + if problemsOnly: + complianceList = filter(lambda entry: entry.getScore() < 100, complianceList) + distribution=[99,90] + textSummary(distribution, complianceList, prefix) + + for target in problemList: + print LongBow.buildRed("%s%s could not be evaluated" % (prefix, target)) + + +def commandLineMain(args, targets, exemplarCommand, exemplarConfig): + complianceList = map(lambda target: SyntaxCompliance(target, exemplarCommand, exemplarConfig).check(), targets) + + complianceList = sortComplianceList(args, complianceList) + + complianceList = exclude(args, complianceList) + + if args.summary: + displaySummary(args, complianceList) + elif args.average: + displayAverage(args, complianceList) + elif args.total: + displayTotal(args, complianceList) + elif args.visual: + displayVisual(args, complianceList) + return diff --git a/longbow/src/python/site-packages/longbow/SymbolTable.py b/longbow/src/python/site-packages/longbow/SymbolTable.py new file mode 100755 index 00000000..20a909d7 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/SymbolTable.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# +import os +import subprocess +import re +import sys +import pprint + +def parseLocation(location): + token = location.split("[") + objectFileName = location + + if len(token) > 1: + libraryName = token[0] + objectFileName = token[1].split("]")[0] + else: + libraryName = None + + objectFileName = objectFileName.split(":")[0] + return (libraryName, objectFileName) + +def parseDarwinOutput(lines, accumulator = { }): + + for line in lines: + token = line.split(" ") + fullName = token[0] + + libraryName, objectFileName = parseLocation(token[0]) + name = token[1] + type = token[2] + if fullName in accumulator: + if type == "U": + accumulator[fullName]["undefined"].append({ "name" : name }) + elif type == "T": + accumulator[fullName]["defined"].append({ "name" : name }) + elif type == "D": + accumulator[fullName]["globalData"].append({ "name" : name }) + else: + accumulator[fullName] = { "fullName" : fullName, "libraryName" : libraryName, "objectFileName" : objectFileName, "defined" : [], "undefined" : [], "globalData" : [] } + + return accumulator + +def getDarwinSymbolTable(objectFileName, accumulator = { }): + command = [ "/usr/bin/nm", "-PAog", objectFileName ] + + output = subprocess.check_output(command) + lines = output.splitlines() + return parseDarwinOutput(lines, accumulator) + + +def getSymbolTable(objectFileName, accumulator = { }): + ''' + { + fullName : { "defined" : list of dictionaries, + "undefined": list of dictionaries, + "globalData" : list of dictionaries, + "libraryName" : string + "objectFileName : string + }, + } + ''' + return getDarwinSymbolTable(objectFileName, accumulator) + + +if __name__ == '__main__': + + table = dict() + for f in sys.argv: + table = getSymbolTable(f, table) + + pp = pprint.PrettyPrinter(indent=4, width=132) + + pp.pprint(table) diff --git a/longbow/src/python/site-packages/longbow/VocabularyReport.py b/longbow/src/python/site-packages/longbow/VocabularyReport.py new file mode 100755 index 00000000..5609db11 --- /dev/null +++ b/longbow/src/python/site-packages/longbow/VocabularyReport.py @@ -0,0 +1,162 @@ +#! /usr/bin/env python +# Copyright (c) 2017 Cisco and/or its affiliates. +# 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. +# + +# + +import sys +import itertools + +import LongBow + +def computeVocabularyScore(tokenCount): + return 100.0 + + +def csvFunctionResult(file, function): + score = computeVocabularyScore(file.token_count) + string = "vocabulary,%s,%s,%d,%d,%.2f" % (file.filename, function.name, function.start_line, function.token_count, score) + + LongBow.scorePrinter([90, 80], score, string) + return function.token_count + + +def csvFileVocabulary(file): + score = computeVocabularyScore(file.token_count) + string = "vocabulary,%s,,,%.2f,%.2f" % (file.filename, file.average_token, score) + LongBow.scorePrinter([90, 80], score, string) + return + + +def csvFunction(fileInformationList): + for fileInformation in fileInformationList: + complexities = map(lambda function: csvFunctionResult(fileInformation, function), fileInformation) + return + + +def csvSummary(fileInformationList): + map(lambda file: csvFileVocabulary(file), fileInformationList) + return + + +def textFunctionResult(file, function, maxFileNameLength, maxFunctionNameLength): + score = computeVocabularyScore(function.token_count) + format = "%-" + str(maxFileNameLength) + "s %-" + str(maxFunctionNameLength) + "s %3d %3d %6.2f" + string = format % (file.filename, function.name, function.start_line, function.token_count, score) + + LongBow.scorePrinter([90, 80], score, string) + return function.cyclomatic_complexity + + +def textFileVocabulary(file, maxFileNameLength, printFormat=""): + score = computeVocabularyScore(file.average_CCN) + if printFormat == "": + printFormat = "%-" + str(maxFileNameLength) + "s %6.2f %6.2f" + string = printFormat % (file.filename, file.average_token, score) + LongBow.scorePrinter([90, 80], score, string) + return + + +def computeMaxFileNameLength(fileInformationList): + result = 0 + for fileInformation in fileInformationList: + if len(fileInformation.filename) > result: + result = len(fileInformation.filename) + return result + + +def computeMaxFunctionNameLength(fileInformationList): + result = 0 + for fileInformation in fileInformationList: + if len(fileInformation.filename) > result: + result = len(fileInformation.filename) + return result + + +def textFunction(fileInformationList): + maxFileNameLength = max(map(lambda fileInformation: len(fileInformation.filename), fileInformationList)) + maxFunctionNameLength = max(map(lambda fileInformation: max(map(lambda function: len(function.name), fileInformation)), fileInformationList)) + + for fileInformation in fileInformationList: + complexities = map(lambda function: textFunctionResult(fileInformation, function, maxFileNameLength, maxFunctionNameLength), fileInformation) + return + + +def textSummary(fileInformationList, prefix=""): + if len(fileInformationList) < 1: + print "%sNo Files To Grade" % prefix + return + maxFileNameLength = max(map(lambda fileInformation: len(fileInformation.filename), fileInformationList)) + printFormat = prefix + "%-" + str(maxFileNameLength) + "s %10s %6s" + print printFormat % ("File Path", "Ave Token", "Score") + printFormat = prefix + "%-" + str(maxFileNameLength) + "s %10.2f %6.2f" + map(lambda file: textFileVocabulary(file, maxFileNameLength, printFormat), fileInformationList) + return + + +def computeAverage(fileInformationList): + vocabulary = map(lambda fileInformation : fileInformation.average_token, fileInformationList) + sum = reduce(lambda sum, x: sum + x, vocabulary) + return float(sum) / float(len(vocabulary)) + + +def gradeAndPrint(fileList, hfcca, problemsOnly=False, prefix=""): + options, arguments = hfcca.createHfccaCommandLineParser().parse_args(args=["foo"]) + result = hfcca.analyze(fileList, options) + + # Convert from that iterator to a simple list... + fileInformationList = map(lambda x : x, result) + if problemsOnly: + fileInformationList = filter(lambda item: computeVocabularyScore(item.average_CCN) < 100, fileInformationList) + + textSummary(fileInformationList, prefix) + +def commandLineMain(args, hfcca): + targets = [] + + if args.stdin: + for line in sys.stdin: + t = line.strip() + if (len(t) > 0): + targets.append(t) + else: + targets = args.files + + if (len(targets) == 0): + print >> sys.stderr, "Error: target list cannot be empty" + + # If nothing was specified, print the summary as a default + if args.summary == False and args.function == False and args.average == False: + args.summary = True + + options, arguments = hfcca.createHfccaCommandLineParser().parse_args(args=["VocabularyReport"]) + result = hfcca.analyze(targets, options) + + # Convert from that iterator to a simple list... + fileInformationList = map(lambda x : x, result) + + if args.function: + if args.output == "text": + textFunction(fileInformationList) + else: + csvFunction(fileInformationList) + + if args.summary: + if args.output == "text": + textSummary(fileInformationList) + else: + csvSummary(fileInformationList) + + if args.average: + print "%.2f" % computeAverage(fileInformationList) |