diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..268ea1c --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,15 @@ +# These are supported funding model platforms + +github: [pcisar] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +polar: # Replace with a single Polar username +buy_me_a_coffee: # Replace with a single Buy Me a Coffee username +thanks_dev: # Replace with a single thanks.dev username +custom: # https://firebirdsql.org/en/donate/ diff --git a/.gitignore b/.gitignore index 2f9c59c..101e7c3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST +.hatch/ # PyInstaller # Usually these files are written by a python script from a template @@ -133,4 +134,8 @@ dmypy.json *.wpu # Sphinx build -docs/_build \ No newline at end of file +docs/_build +docs/firebird-base.docset/ + +# Other local files and directories +local/ diff --git a/.readthedocs.yml b/.readthedocs.yml index e81e510..279e491 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,9 +9,12 @@ version: 2 sphinx: configuration: docs/conf.py - +build: + os: "ubuntu-22.04" + tools: + python: "3.11" + # Optionally set the version of Python and requirements required to build your docs python: - version: 3.8 install: - requirements: docs/requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..16edf50 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,320 @@ +# Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + + +## [2.0.2] - 2025-06-02 + +### Fixed + +- Fix: "quick fingers" issue with `_decompose` fix. + +## [2.0.1] - 2025-06-02 + +### Fixed + +- Issue with trace configuration. +- Issues with `_decompose`. +- Signature match in `eventsocket`. + +## [2.0.0] - 2025-04-30 + +### Added + +- `firebird.base.buffer.MemoryBuffer.get_raw` method. +- `get_raw` method to `BufferFactory`, `BytesBufferFactory` and `CTypesBufferFactory`. +- `__repr__` method for `PyCode` and `PyCallable` that will limit output to 50 characters. +- Optional `encoding` parameter for `ZMQAddress` constructor. + +### Changed + +- Tests changed from `unittest` to `pytest`, 96% code coverage. +- Minimal Python version raised to 3.11. +- The `firebird.base.logging` module was completelly reworked. +- Function `firebird.base.types.Conjunctive` renamed to `conjunctive`. +- `firebird.base.collections.DataList.__init__` parameter `frozen` is now keyword-only. +- `firebird.base.collections.DataList.extract` parameter `copy` is now keyword-only. +- `firebird.base.collections.DataList.sort` parameter `reverse` is now keyword-only. +- `firebird.base.collections.DataList.split` parameter `frozen` is now keyword-only. +- `firebird.base.collections.Registry.popitem` parameter `last` is now keyword-only. +- `firebird.base.collections.BaseObjectCollection.contains` parameter `expr` now does not have default value. +- Deprecated `firebird.base.config.create_config` function was removed. +- `firebird.base.config.DirectoryScheme` parameter `force_home` is now keyword only. +- `firebird.base.config.Option` parameters `required` and `default` are now keyword only. +- Parameter `context` was removed from `firebird.base.trace.traced` decorator. +- Option `context` was removed from `firebird.base.trace.BaseTraceConfig`. +- Log function return value as `repr` rather than `str`. +- Sentinel objects completely reworked. Individual sentinels are now classes derived from `Sentinel`. + +### Fixed + +- Broken `firebird.base.types.Distinct` support for dataclasses and hash function. +- Raise `BufferError` istead `IOError` in `firebird.base.buffer.MemoryBuffer` methods `resize`, + `read` and `read_number` +- Problem with `firebird.base.collections.Registry.pop` that did not raised `KeyError` when + `default` was not specified. +- Bug in `firebird.base.collections.Registry.popitem` with `last` = True. +- Problem with name handling in `firebird.base.config.ConfigOption.clear` and `set_value`. +- Problem with `firebird.base.config.WindowsDirectoryScheme` and `firebird.base.config.MacOSDirectoryScheme` constructors. +- Problem with `firebird.base.config.ListOption.item_types` value. +- Problem with internal `.Convertor` initialization in `firebird.base.config.ListOption`. +- Use copy of `default` list stead direct use in `firebird.base.config.ListOption`. +- `firebird.base.config.ListOption.get_formatted` and `firebird.base.config.ListOption.get_as_str` + should return typed values for multitype lists. +- `firebird.base.config.ConfigOption.validate` should validate the `Config` as well if defined. +- `firebird.base.config.ConfigListOption.validate` should report error for empty list when `required`. +- Problem with conversion of flags from string in `firebird.base.strconv`. + +## [1.8.0] - 2024-05-03 + +### Added + +- New `EnvExtendedInterpolation` class in `cnfig` module that extends `configparser.ExtendedInterpolation` + with special handling for "env" section that returns value of specified environment + variable, or empty string if such variable is not defined. + +## [1.7.2] - 2024-02-20 + +### Fixed + +- `Error.getattr()` should not mask the absence of `__notes__` attribute. + +## [1.7.1] - 2023-10-08 + +### Fixed + +- Log record values `module` and `filename` were not assigned properly under Python 3.11 +- Failed tests due to subtle changes in Python 3.11 + +### Changed + +- Downgrade dependency to protobuf>=4.23.4 + +## [1.7.0] - 2023-10-03 + +### Changed + +- Update dependency to protobuf >=4.24.3 +- Build system changed from setuptools to hatch +- Package version is now defined in firebird.base.__about__.py (__version__) + +### Added + +- .pyi file for config protobuf + +## [1.6.1] - 2023-03-03 + +### Fixed + +- Bug with Config.get_config() and `plain` bool argument. + +### Changed + +- firebird.base.config.StrOption now supports preservation of significant leading whitespace + for multiline values (like PyCodeOption). + +## [1.6.0] - 2023-02-15 + +### Fixed + +- Bug in TraceManager.load_config(). + +### Changed + +- Registration of already registered protobuf objects is now ignored instead + raising exception. +- Module firebird.base.config: + + - Config.get_config() and Option.get_config() now provides `plain` bool argument to + return configuration text without comments. Deafult is False. + - create_config is now deprecated, will be removed in version 2.0. + +## [1.5.0] - 2022-11-14 + +### Changed + +- Move away from setup.cfg to pyproject.toml, new source tree layout. + +## [1.4.3] - 2022-10-27 + +### Added + +- Added internal functions firebird.base.types._decompose and firebird.base.types._power_of_two + from stdlib enum module, because they were removed in Python 3.11. + +### Changed + +- Module firebird.base.protobuf now uses importlib.metadata.entry_points + instead pkg_resources.iter_entry_points. +- Improved documentation. + +## [1.4.2] - 2022-10-05 + +### Fixed + +- Signature in firebird.base.config.IntOption.clear(). +- Signature in firebird.base.trace.TraceManager.add_trace(). Keyword argument `decorator` + (with default) could not be used with args/kwargs, so it was removed. New + firebird.base.trace.TraceManager.decorator attribute was added to + firebird.base.trace.TraceManager that could be used to change trace decorator used + for intrumentation. + +### Changed + +- Optimizations. +- Cleanup of pylint warnings. +- Updated documentation. + +## [1.4.1] - 2022-09-28 + +### Added + +- Documentation is now also provided as Dash / Zeal docset, downloadable from releases + at github. + +### Fixed + +- Uregistered bug in trace.TraceConfig - redundant `flags` definition. + +## [1.4.0] - 2022-06-13 + +### Changed + +- Upgrade to protobuf 4.21.1. As this upgrade has consequences, please read + https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates + +## [1.3.1] - 2022-01-11 + +### Added + +* `~firebird.base.buffer` module: + +- Added firebird.base.buffer.MemoryBuffer.write_sized_string() for symetry with read_sized_string(). +- Now firebird.base.buffer.MemoryBuffer string functions has also `errors` parameter in + addition to `encoding`. + +### Changed + +- Direct assignment to firebird.base.config.Config option raises a `ValueError` exception + with message "Cannot assign values to option itself, use `option.value` instead". + +## [1.3.0] - 2021-06-03 + +### Added + +- firebird.base.config.Config has new constructor keyword-only argument `description`. + +### Fixed + +- Uregistered bug in config.ListOption - value and default was the same instance + +### Changed + +- Layout produced by firebird.base.config.get_config() was changed. + +## [1.2.0] - 2021-03-04 + +### Added + +- New function firebird.base.protobuf.get_message_factory. +- Module firebird.base.trace: Added: `apply_to_descendants` boolean configuration option to + apply configuration also to all registered descendant classes. The default value is `True`. + +### Fixed + +- Bug in firebird.base.signal.eventsocket signature handling. + +### Changed + +- Build scheme changed to `PEP 517`. +- Various changes to documentation and type hint adjustments. +- firebird.base.config module: + + - **BREAKING CHANGE**: ApplicationDirectoryScheme was replaced by + DirectoryScheme class, and get_directory_scheme() has changed signature. + - Directory scheme was reworked and now also supports concept of HOME directory. + - New MacOS directory scheme support. As I don't have access to MacOS, this support + should be considered EXPERIMENTAL. Any feedback about it's correctness is welcome. + - Added: New Config constructor keyword-only `bool` argument `optional` and + associated Config.optional read-only property. + - Added: Config.has_value() function. + - New class: PathOption for Configuration options with `pathlib.Path` value. + +## [1.1.0] - 2020-11-30 + +### Added + +- New module: signal - Callback system based on Signals and Slots, and "Delphi events" +- New class: firebird.base.config.ApplicationDirectoryScheme +- Introduced firebird.base.config.PROTO_CONFIG constant with fully qualified name for + ConfigProto protobuf. +- Module firebird.base.protobuf: Added direct support for key well-known data types + `Empty`, `Any`, `Duration`, `Timestamp`, `Struct`, `Value`, `ListValue` and `FieldMask`. + They are automatically registered. New constants 'PROTO_' with fully qualified names. +- firebird.base.protobuf.create_message()` has new optional `serialized` argument with + `bytes` that should be parsed into newly created message instance. +- New functions firebird.base.protobuf.struct2dict() and firebird.base.protobuf.dict2struct() +- Modules firebird.base.trace: Added support for trace configuration based on firebird.base.config, + using new classes BaseTraceConfig, TracedMethodConfig, TracedClassConfig and TraceConfig. +- New methods in firebird.base.trace.TraceManager: + + - load_config() to update trace from configuration. + - set_flag() and clear_flag(). +- New function firebird.base.types.load(). + +### Changed + +- firebird.base.types.load() function now supports `object_name[.object_name...]` + specifications instead single `object_name`. +- firebird.base.config.Config.load_config(): raises error when section is missing, + better error handling when exception is raised while loading options +- firebird.base.config.PyCallableOption signature argument could be inspect.Signature + or Callable +- Optional argument `to_default` in `~firebird.base.config.Option.clear()` is now keyword-only. +- firebird.base.logging.get_logging_id() uses __qualname__ instead __name__ +- firebird.base.trace.TraceFlag value `DISABLED` was renamed to `NONE`. +- firebird.base.types.MIME now handles access to properties more efficiently and faster. +- Changes in documentation. + +## [1.0.0] - 2020-10-13 + +### Added + +- Documentation: new examples for trace, logging and hooks +- Documentation: adjustments to css + +### Changed + +- DataList is now generic class. +- DataList.extract() has new 'copy' argument. + +## [0.6.1] - 2020-09-15 + +- Promoted to stable +- More documentation + +## [0.6.0] - 2020-06-30 + +### Added + +- New module: firebird.base.strconv - Data conversion from/to string +- New module: firebird.base.trace - Trace/audit for class instances + +### Changed + +- Changed module: firebird.base.types, New classes: MIME - MIME type specification, + PyExpr - Source code for Python expression, PyCode - Python source code and PyCallable - + Source code for Python callable. Removed function: str2bool +- Reworked module: firebird.base.config - Classes for configuration definitions + with new classes: ConfigOption - Configuration option with Config value, + ConfigListOption - Configuration option with list of Config values, and + DataclassOption - Configuration option with a dataclass value. +- Changed module: firebird.base.logging - Trace/audit functionality removed (into new + module firebird.base.trace) + +## [0.5.0] - 2020-05-28 + +Initial release. + diff --git a/LICENSE b/LICENSE index 366ae47..8d25235 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ MIT License =========== -Copyright (c) 2020 The Firebird Project +Copyright (c) 2019 The Firebird Project (www.firebirdsql.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe254dd --- /dev/null +++ b/README.md @@ -0,0 +1,161 @@ +# firebird-base + +## Firebird base modules for Python + +[![PyPI - Version](https://img.shields.io/pypi/v/firebird-base.svg)](https://pypi.org/project/firebird-base) +[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/firebird-base.svg)](https://pypi.org/project/firebird-base) +[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch) +[![PyPI - Downloads](https://img.shields.io/pypi/dm/firebird-base)](https://pypi.org/project/firebird-base) +[![Libraries.io SourceRank](https://img.shields.io/librariesio/sourcerank/pypi/firebird-base)](https://libraries.io/pypi/firebird-base) + +The firebird-base package is a set of Python 3 modules commonly used by [Firebird Project](https://github.com/FirebirdSQL) +in various development projects (for example the firebird-driver or Saturnin). However, these +modules have general applicability outside the scope of development for [Firebird](https://www.firebirdsql.org). + +----- + +**Table of Contents** + +- [Installation](#installation) +- [License](#license) +- [Introduction](#introduction) +- [Documentation](#documentation) + +## Installation + +```console +pip install firebird-base +``` + +## License + +`firebird-base` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. + +## Introduction + +### Common data types + +The `types` module provides collection of classes and other types that are often used by +other library modules or applications. + +- Exception `Error` that is intended to be used as a base class of all application-related + errors. The important difference from `Exception` class is that `Error` accepts keyword + arguments, that are stored into instance attributes with the same name. +- `Singleton` base class for singletons. +- `Sentinel` base class for named sentinel objects that provide meaningful `str` and `repr`, + along with collection of predefined sentinels. +- `Distinct` abstract base class for classes (incl. dataclasses) with distinct instances. +- Collection of `Enums` and `custom string types`. + +### Various collection types + +The `collections` module provides data structures that behave much like builtin `list` and +`dict` types, but with direct support of operations that can use structured data stored in +container, and which would normally require utilization of `operator`, `functools` or other +means. + +All containers provide next operations: + +- `filter` and `filterfalse` that return generator that yields items for which expr is + evaluated as True (or False). +- `find` that returns first item for which expr is evaluated as True, or default. +- `contains` that returns True if there is any item for which expr is evaluated as True. +- `occurrence` that returns number of items for which expr is evaluated as True. +- `all` and `any` that return True if expr is evaluated as True for all or any collection element(s). +- `report` that returns generator that yields data produced by expression(s) evaluated on collection items. + +Individual collection types provide additional operations like splitting and extracting +based on expression etc. + +Expressions used by these methods could be strings that contain Python expression referencing +the collection item(s), or lambda functions. + +### Data conversion from/to string + +While Python types typically support conversion to string via builtin `str()` function (and +custom `__str__` methods), there is no symetric operation that converts string created by +`str()` back to typed value. Module `strconv` provides support for such symetric conversion +from/to string for any data type. + +Symetric string conversion is used by `firebird.base.config` module, notably by +`firebird.base.config.ListOption` and `firebird.base.config.DataclassOption`. You can +extend the range of data types supported by these options by registering convertors for +required data types. + +### Configuration definitions + +Complex applications (and some library modules like `logging`) could be often parametrized +via configuration. Module `firebird.base.config` provides a framework for unified structured +configuration that supports: + +- configuration options of various data type, including lists and other complex types +- validation +- direct manipulation of configuration values +- reading from (and writing into) configuration in `configparser` format +- exchanging configuration (for example between processes) using Google protobuf messages + +Additionally, the `ApplicationDirectoryScheme` abstract base class defines set of mostly +used application directories. The function `get_directory_scheme()` could be then used +to obtain instance that implements platform-specific standards for file-system location +for these directories. Currently, only "Windows", "Linux" and "MacOS" directory schemes +are supported. + +### Memory buffer manager + +Module `buffer` provides a raw memory buffer manager with convenient methods to read/write +data of various data types. + +### Hook manager + +Module `hooks` provides a general framework for callbacks and “hookable” events, that +supports multiple usage strategies. + +### Context-based logging + +Module `logging` provides context-based logging system built on top of standard `logging` +module. It also solves the common logging management problem when various modules use hard-coded +separate loggers, and provides several types of message wrappers that allow lazy message +interpolation using f-string, brace (`str.format`) or dollar (`string.Template`) formats. + +The context-based logging: + +1. Adds context information into `logging.LogRecord`, that could be used in logging entry formats. +2. Allows assignment of loggers to specific contexts. + +### Trace/audit for class instances + +Module `trace` provides trace/audit logging for functions or object methods through +context-based logging provided by `logging` module. + +The trace logging is performed by `traced` decorator. You can use this decorator directly, +or use `TracedMixin` class to automatically decorate methods of class instances on creation. +Each decorated callable could log messages before execution, after successful execution or +on failed execution (when unhandled exception is raised by callable). The trace decorator +can automatically add `agent` and `context` information, and include parameters passed to +callable, execution time, return value, information about raised exception etc. to log messages. + +The trace logging is managed by `TraceManager`, that allows dynamic configuration of traced +callables at runtime. + +Trace supports configuration based on `firebird.base.config`. + +### Registry for Google Protocol Buffer messages and enums + +Module `protobuf` provides central registry for Google Protocol Buffer messages and enums. +The generated `*_pb2.py protobuf` files could be registered using `register_decriptor` or +`load_registered` function. The registry could be then used to obtain information about +protobuf messages or enum types, or to create message instances or enum values. + +### Callback systems + +Module `firebird.base.signal` provides two callback mechanisms: one based on signals and +slots similar to Qt signal/slot, and second based on optional method delegation similar to +events in Delphi. + +In both cases, the callback callables could be functions, instance or class methods, +partials and lambda functions. The `inspect` module is used to define the signature for +callbacks, and to validate that only compatible callables are assigned. + +## Documentation + +The documentation for this package is available at [https://firebird-base.readthedocs.io](https://firebird-base.readthedocs.io) diff --git a/README.rst b/README.rst deleted file mode 100644 index 2a6f713..0000000 --- a/README.rst +++ /dev/null @@ -1,30 +0,0 @@ -================================ -Firebird base modules for Python -================================ - -The `firebird-base` package provides common Python 3 modules used by `Firebird Project`_ -in various development projects. However, these modules have general applicability outside -the scope of development for `Firebird`_ ® RDBMS. - -Topic covered by `firebird-base` package: - -* General data types like `singletons`, `sentinels` and objects with identity. -* Unified system for data conversion from/to string. -* `DataList` and `Registry` collection types with advanced data-processing cappabilities. -* Work with structured binary buffers. -* Global registry of Google `protobuf` messages and enumerations. -* Extended configuration system based on `ConfigParser`. -* Context-based logging. -* Trace/audit for class instances. -* General "hook" mechanism. - - -|donate| - -.. _Firebird: http://www.firebirdsql.org -.. _Firebird Project: https://github.com/FirebirdSQL - -.. |donate| image:: https://www.firebirdsql.org/img/donate/donate_to_firebird.gif - :alt: Contribute to the development - :scale: 100% - :target: https://www.firebirdsql.org/en/donate/ diff --git a/docs/buffer.txt b/docs/buffer.txt index fb8ce88..6ffdc13 100644 --- a/docs/buffer.txt +++ b/docs/buffer.txt @@ -8,8 +8,45 @@ buffer - Memory buffer manager Overview ======== -This module provides a raw memory buffer manager with convenient methods to read/write -data of various data type. +This module provides a `MemoryBuffer` class for managing raw memory buffers, +offering a convenient and consistent API for reading and writing various data types +(integers of different sizes, strings with different termination/prefixing styles, raw bytes). +It's particularly useful for tasks involving binary data serialization/deserialization, +such as implementing network protocols or handling custom file formats. + +The underlying memory storage can be customized via a `BufferFactory`. Two factories +are provided: + +- `BytesBufferFactory`: Uses Python's built-in `bytearray`. +- `CTypesBufferFactory`: Uses `ctypes.create_string_buffer` for potentially different + memory characteristics or C-level interoperability. + +Example:: + + from firebird.base.buffer import MemoryBuffer, ByteOrder + + # Create a buffer (default uses bytearray) + buf = MemoryBuffer(10) # Initial size 10 bytes + + # Write data + buf.write_short(258) # Write 2 bytes (0x0102 in little-endian) + buf.write_pascal_string("Hi") # Write 1 byte length (2) + "Hi" + buf.write(b'\\x0A\\x0B') # Write raw bytes + + # Reset position to read + buf.pos = 0 + + # Read data + num = buf.read_short() + s = buf.read_pascal_string() + extra = buf.read(2) + + print(f"Number: {num}") # Output: Number: 258 + print(f"String: '{s}'") # Output: String: 'Hi' + print(f"Extra bytes: {extra}") # Output: Extra bytes: b'\\n\\x0b' + print(f"Final position: {buf.pos}") # Output: Final position: 7 + print(f"Raw buffer: {buf.get_raw()}") # Output: Raw buffer: bytearray(b'\\x02\\x01\\x02Hi\\n\\x0b\\x00\\x00\\x00') + MemoryBuffer ============ @@ -21,3 +58,6 @@ Buffer factories .. autoclass:: BytesBufferFactory .. autoclass:: CTypesBufferFactory +Functions +========= +.. autofunction:: safe_ord diff --git a/docs/changelog.txt b/docs/changelog.txt index 08221a1..18bf2dd 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -2,6 +2,119 @@ Changelog ######### +Version 2.0.2 +============= + +* Fix: "quick fingers" issue with `_decompose` fix. + +Version 2.0.1 +============= + +* Fix: for trace configuration. +* Fix: issues with `_decompose`. +* Fix: Signature match in `.eventsocket`. + +Version 2.0.0 +============= + +* Change tests from `unittest` to `pytest`, 96% code coverage. +* Minimal Python version raised to 3.11. +* Code cleanup and optimization for Python 3.11 features. +* `~firebird.base.types` module: + + - Change: Function `Conjunctive` renamed to `.conjunctive`. + - Fix: `.Distinct` support for dataclasses was broken. + - Fix: `.Distinct` support for `hash` was broken. + - Change: Sentinel objects completely reworked. Individual sentinels are now classes + derived from `.Sentinel`. + - Added: `__repr__` method for `.PyCode` and `.PyCallable` that will limit output to 50 characters. + - Added: Optional `encoding` parameter for `ZMQAddress` constructor. + +* `~firebird.base.buffer` module: + + - Added `.MemoryBuffer.get_raw` method. + - Added `get_raw` method to `.BufferFactory`, `.BytesBufferFactory` and `.CTypesBufferFactory`. + - Fix: `resize`, `read` and `read_number` now raise `BufferError` istead `IOError`. + +* `~firebird.base.collections` module: + + - `.DataList.__init__` parameter `frozen` is now keyword-only. + - `.DataList.extract` parameter `copy` is now keyword-only. + - `.DataList.sort` parameter `reverse` is now keyword-only. + - `.DataList.split` parameter `frozen` is now keyword-only. + - `.Registry.popitem` parameter `last` is now keyword-only. + - `.BaseObjectCollection.contains` parameter `expr` now does not have default value. + - Fix: problem with `.Registry.pop` that did not raised `KeyError` when `default` was + not specified. + - Fix: bug in `.Registry.popitem` with `last` = True. + +* `~firebird.base.config` module: + + - Deprecated `.create_config` function was removed. + - Change: `.DirectoryScheme` parameter `force_home` is now keyword only. + - Change: `.Option` parameters `required` and `default` are now keyword only. + - Fix: Problem with name handling in `.ConfigOption.clear` and `set_value`. + - Fix: Problem with `.WindowsDirectoryScheme` and `.MacOSDirectoryScheme` constructors. + - Fix: Problem with `.ListOption.item_types` value. + - Fix: Problem with internal `.Convertor` initialization in `.ListOption`. + - Fix: Use copy of `default` list stead direct use in `.ListOption`. + - Fix: `.ListOption.get_formatted` and `.ListOption.get_as_str` should return typed values + for multitype lists. + - Fix: `.ConfigOption.validate` should validate the `.Config` as well if defined. + - Fix: `.ConfigListOption.validate` should report error for empty list when `required`. + +* `~firebird.base.strconv` module: + + - Fix: Problem with conversion of flags from string. + +* Changed: The `~firebird.base.logging` module was completelly reworked. + +* `~firebird.base.trace` module: + + - Change: Parameter `context` was removed from `.traced` decorator + - Change: Option `context` was removed from `.BaseTraceConfig`. + - Change: Log function return value as `repr` rather than `str`. + + + +Version 1.8.0 +============= + +* `~firebird.base.config` module: + + - New `.EnvExtendedInterpolation` class that extends `configparser.ExtendedInterpolation` + with special handling for "env" section that returns value of specified environment + variable, or empty string if such variable is not defined. + + +Version 1.7.2 +============= + +- `.Error.getattr()` should not mask the absence of `__notes__` attribute. + +Version 1.7.1 +============= + +- Log record values `module` and `filename` were not assigned properly under Python 3.11, +- Failed tests due to subtle changes in Python 3.11 +- Downgrade dependency to `protobuf>=4.23.4` + +Version 1.7.0 +============= + +* Update dependency to protobuf >=4.24.3 +* Build system changed from setuptools to hatch +* Package version is now defined in firebird.base.__about__.py (__version__) + +Version 1.6.1 +============= + +* `~firebird.base.config` module: + + - Fixed bug with `.Config.get_config()` and `plain` bool argument. + - `.StrOption` now supports preservation of significant leading whitespace for multiline + values (like `.PyCodeOption`). + Version 1.6.0 ============= @@ -14,12 +127,12 @@ Version 1.6.0 - `.Config.get_config()` and `.Option.get_config()` now provides `plain` bool argument to return configuration text without comments. Deafult is False. + - `.create_config` is now deprecated, will be removed in version 2.0. * `~firebird.base.trace` module: - Fixed bug in `.TraceManager.load_config()`. - Version 1.5.0 ============= diff --git a/docs/conf.py b/docs/conf.py index 7e80248..7522a92 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,17 +16,19 @@ import sphinx_bootstrap_theme +from firebird.base.__about__ import __version__ + # -- Project information ----------------------------------------------------- -project = 'Firebird-base' -copyright = '2020-2023, The Firebird Project' -author = 'Pavel Císař' +project = "Firebird-base" +copyright = "2020-2025, The Firebird Project" +author = "Pavel Císař" # The short X.Y version -version = '1.6.0' +version = __version__ # The full version, including alpha/beta/rc tags -release = '1.6.0' +release = __version__ # -- General configuration --------------------------------------------------- @@ -35,47 +37,47 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.intersphinx', - 'sphinx.ext.autodoc', - 'sphinx.ext.napoleon', - 'sphinx.ext.viewcode', - 'sphinx.ext.autosectionlabel', + "sphinx.ext.intersphinx", + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx.ext.autosectionlabel", #'sphinx_autodoc_typehints', - 'sphinx.ext.todo', + "sphinx.ext.todo", #'sphinx.ext.coverage', ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.txt' +source_suffix = ".txt" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'requirements.txt'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "requirements.txt"] -default_role = 'py:obj' +default_role = "py:obj" # -- Options for HTML output ------------------------------------------------- -html_favicon = '_static/fb-favicon.png' +html_favicon = "_static/fb-favicon.png" # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # #html_theme = 'alabaster' -html_theme = 'bootstrap' +html_theme = "bootstrap" html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # bootstrap theme config @@ -90,7 +92,7 @@ #'navbar_title': "Firebird-base", # Tab name for entire site. (Default: "Site") - 'navbar_site_name': "Site", + "navbar_site_name": "Site", # A list of tuples containing pages or urls to link to. # Valid tuples should be in the following forms: @@ -99,7 +101,7 @@ # (name, "http://example.com", True) # arbitrary absolute url # Note the "1" or "True" value above as the third argument to indicate # an arbitrary url. - 'navbar_links': [ + "navbar_links": [ ("Introduction", "introduction"), ("Modules", "modules"), ("Index", "genindex"), @@ -108,7 +110,7 @@ ], # Render the next and previous page links in navbar. (Default: true) - 'navbar_sidebarrel': False, + "navbar_sidebarrel": False, # Render the current pages TOC in the navbar. (Default: true) #'navbar_pagenav': True, @@ -118,7 +120,7 @@ # Global TOC depth for "site" navbar tab. (Default: 1) # Switching to -1 shows all levels. - 'globaltoc_depth': 3, + "globaltoc_depth": 3, # Include hidden TOCs in Site navbar? # @@ -127,19 +129,19 @@ # will break. # # Values: "true" (default) or "false" - 'globaltoc_includehidden': "false", + "globaltoc_includehidden": "false", # HTML navbar class (Default: "navbar") to attach to
element. # For black navbar, do "navbar navbar-inverse" - 'navbar_class': "navbar navbar-inverse", + "navbar_class": "navbar navbar-inverse", # Fix navigation bar to top of page? # Values: "true" (default) or "false" - 'navbar_fixed_top': "true", + "navbar_fixed_top": "true", # Location of link to source. # Options are "nav" (default), "footer" or anything else to exclude. - 'source_link_position': "none", + "source_link_position": "none", # Bootswatch (http://bootswatch.com/) theme. # @@ -153,11 +155,11 @@ # - Bootstrap 2: https://bootswatch.com/2 # - Bootstrap 3: https://bootswatch.com/3 #'bootswatch_theme': "united", # cerulean, flatly, lumen, materia, united, yeti - 'bootswatch_theme': "cerulean", + "bootswatch_theme": "cerulean", # Choose Bootstrap version. # Values: "3" (default) or "2" (in quotes) - 'bootstrap_version': "2", + "bootstrap_version": "2", } # -- Extension configuration ------------------------------------------------- @@ -167,26 +169,26 @@ # Autodoc options # --------------- autodoc_default_options = { - 'content': 'both', - 'members': True, - 'member-order': 'groupwise', - 'undoc-members': True, - 'exclude-members': '__weakref__', - 'show-inheritance': True, - 'no-inherited-members': True, + "content": "both", + "members": True, + "member-order": "groupwise", + "undoc-members": True, + "exclude-members": "__weakref__", + "show-inheritance": True, + "no-inherited-members": True, } set_type_checking_flag = True -autodoc_class_signature = 'mixed' +autodoc_class_signature = "mixed" always_document_param_types = True -autodoc_typehints = 'both' # default 'signature' -autodoc_typehints_format = 'short' -autodoc_typehints_description_target = 'all' - -autodoc_type_aliases = {'Item': '~firebird.base.collections.Item', - 'TypeSpec': '~firebird.base.collections.TypeSpec', - 'ItemExpr': '~firebird.base.collections.ItemExpr', - 'FilterExpr': '~firebird.base.collections.FilterExpr', - 'CheckExpr': '~firebird.base.collections.CheckExpr', +autodoc_typehints = "both" # default 'signature' +autodoc_typehints_format = "short" +autodoc_typehints_description_target = "all" + +autodoc_type_aliases = {"Item": "~firebird.base.collections.Item", + "TypeSpec": "~firebird.base.collections.TypeSpec", + "ItemExpr": "~firebird.base.collections.ItemExpr", + "FilterExpr": "~firebird.base.collections.FilterExpr", + "CheckExpr": "~firebird.base.collections.CheckExpr", } # Napoleon options @@ -207,7 +209,7 @@ # -- Options for intersphinx extension --------------------------------------- # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} +intersphinx_mapping = {"python": ("https://docs.python.org/3", None)} # -- Options for todo extension ---------------------------------------------- diff --git a/docs/config.txt b/docs/config.txt index dc79f62..2f2b99e 100644 --- a/docs/config.txt +++ b/docs/config.txt @@ -33,16 +33,21 @@ The framework is based around two classes: `.PyCode` and `.PyCallable`. It also provides special options `ConfigOption` and `ConfigListOption`. -Additionally, the `.ApplicationDirectoryScheme` abstract base class defines set of mostly +Additionally, the `.DirectoryScheme` abstract base class defines set of mostly used application directories. The function `.get_directory_scheme()` could be then used to obtain instance that implements platform-specific standards for file-system location for these directories. Currently, only "Windows", "Linux" and "MacOS" directory schemes are supported. -.. note:: - You may use `platform.system` call to determine the scheme name suitable for platform +.. tip:: + You may use `.get_directory_scheme()` function to get the scheme suitable for platform where your application is running. +.. tip:: + If your configurations contain secrets like passwords or access tokens, that would be + read from files via `configparser`, you should consider to use `.EnvExtendedInterpolation` + that has support for option values defined via environment variables. + Usage ----- First, you need to define your own configuration. @@ -288,7 +293,7 @@ The protobuf message is defined in :file:`/proto/config.proto`. cfg_msg = ConfigProto() Because the proto file is NOT registered in `.protobuf` registry, you must register - it manually. The proto file is listed in `setup.cfg` under *"firebird.base.protobuf"* + it manually. The proto file is listed in `pyproject.toml` under *"firebird.base.protobuf"* entrypoint, so use `load_registered('firebird.base.protobuf')` for its registration. .. code-block:: @@ -331,6 +336,11 @@ Application Directory Scheme .. autoclass:: MacOSDirectoryScheme .. autofunction:: get_directory_scheme +Configparser interpolation +========================== + +.. autoclass:: EnvExtendedInterpolation + Config ====== .. autoclass:: Config @@ -359,5 +369,6 @@ Options Functions ========= -.. autofunction:: create_config +.. autofunction:: has_verticals +.. autofunction:: has_leading_spaces diff --git a/docs/firebird-base.docset/Contents/Info.plist b/docs/firebird-base.docset/Contents/Info.plist deleted file mode 100644 index 08ec3f3..0000000 --- a/docs/firebird-base.docset/Contents/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleIdentifier - firebird-base - CFBundleName - firebird-base - DashDocSetDeclaredInStyle - originalName - DashDocSetFallbackURL - https://firebird-base.readthedocs.io/en/latest/ - DashDocSetFamily - python - DocSetPlatformFamily - firebird-base - isDashDocset - - isJavaScriptEnabled - - - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/.buildinfo b/docs/firebird-base.docset/Contents/Resources/Documents/.buildinfo deleted file mode 100644 index 5d0f8b8..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c6141e70e401315cd341f57590fb931d -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/buffer.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/buffer.html deleted file mode 100644 index 131ccec..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/buffer.html +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - firebird.base.buffer — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.buffer

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/buffer.py
-# DESCRIPTION:    Memory buffer manager
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""Firebird Base - Memory buffer manager
-
-This module provides a raw memory buffer manager with convenient methods to read/write
-data of various data type.
-"""
-
-from __future__ import annotations
-from typing import runtime_checkable, Protocol, Type, Union, Any
-from ctypes import memset, create_string_buffer
-from .types import Sentinel, UNLIMITED, ByteOrder
-
-
[docs]@runtime_checkable -class BufferFactory(Protocol): # pragma: no cover - """BufferFactory Protocol definition. - """ -
[docs] def create(self, init_or_size: Union[int, bytes], size: int=None) -> Any: - """This function must create and return a mutable character buffer. - - Arguments: - init_or_size: Must be an integer which specifies the size of the array, or a bytes - object which will be used to initialize the array items. - size: Size of the array. - """
-
[docs] def clear(self, buffer: Any) -> None: - """Fills the buffer with zero. - - Argument: - buffer: A memory buffer previously created by `BufferFactory.create()` method. - """
- -
[docs]class BytesBufferFactory: - """Buffer factory for `bytearray` buffers. - """ -
[docs] def create(self, init_or_size: Union[int, bytes], size: int=None) -> bytearray: - """This function creates a mutable character buffer. The returned object is a - `bytearray`. - - Arguments: - init_or_size: Must be an integer which specifies the size of the array, - or a bytes object which will be used to initialize the array items. - size: Size of the array. - - Important: - Although arguments are the same as for `ctypes.create_string_buffer`, - the behavior is different when new buffer is initialized from bytes: - - 1. If there are more bytes than specified `size`, this function copies only - `size` bytes into new buffer. The `~ctypes.create_string_buffer` raises - an excpetion. - 2. Unlike `~ctypes.create_string_buffer` when `size` is NOT specified, - the buffer is NOT made one item larger than its length so that the last - element in the array is a NUL termination character. - """ - if isinstance(init_or_size, int): - return bytearray(init_or_size) - size = len(init_or_size) if size is None else size - buffer = bytearray(size) - limit = min(len(init_or_size), size) - buffer[:limit] = init_or_size[:limit] - return buffer
-
[docs] def clear(self, buffer: bytearray) -> None: - """Fills the buffer with zero. - """ - buffer[:] = b'\x00' * len(buffer)
- -
[docs]class CTypesBufferFactory: - """Buffer factory for `ctypes` array of `~ctypes.c_char` buffers. - """ -
[docs] def create(self, init_or_size: Union[int, bytes], size: int=None) -> bytearray: - """This function creates a `ctypes` mutable character buffer. The returned object - is an array of `ctypes.c_char`. - - Arguments: - init_or_size: Must be an integer which specifies the size of the array, - or a bytes object which will be used to initialize the array items. - size: Size of the array. - - Important: - Although arguments are the same as for `ctypes.create_string_buffer`, - the behavior is different when new buffer is initialized from bytes: - - 1. If there are more bytes than specified `size`, this function copies only - `size` bytes into new buffer. The `~ctypes.create_string_buffer` raises - an excpetion. - 2. Unlike `~ctypes.create_string_buffer` when `size` is NOT specified, - the buffer is NOT made one item larger than its length so that the last - element in the array is a NUL termination character. - """ - if isinstance(init_or_size, int): - return create_string_buffer(init_or_size) - size = len(init_or_size) if size is None else size - buffer = create_string_buffer(size) - limit = min(len(init_or_size), size) - buffer[:limit] = init_or_size[:limit] - return buffer
-
[docs] def clear(self, buffer: bytearray, init: int=0) -> None: - """Fills the buffer with specified value (default). - """ - memset(buffer, init, len(buffer))
- -def safe_ord(byte: Union[bytes, int]) -> int: - """If `byte` argument is byte character, returns ord(byte), otherwise returns argument. - """ - return byte if isinstance(byte, int) else ord(byte) - -
[docs]class MemoryBuffer: - """Generic memory buffer manager. - """ -
[docs] def __init__(self, init: Union[int, bytes], size: int = None, *, - factory: Type[BufferFactory]=BytesBufferFactory, eof_marker: int = None, - max_size: Union[int, Sentinel]=UNLIMITED, byteorder: ByteOrder=ByteOrder.LITTLE): - """ - Arguments: - init: Must be an integer which specifies the size of the array, or a `bytes` object - which will be used to initialize the array items. - size: Size of the array. The argument value is used only when `init` is a `bytes` object. - factory: Factory object used to create/resize the internal memory buffer. - eof_marker: Value that indicates the end of data. Could be None. - max_size: If specified, the buffer couldn't grow beyond specified number of bytes. - byteorder: The byte order used to read/write numbers. - """ - #: Buffer factory instance used by manager [default: `BytesBufferFactory`]. - self.factory: BufferFactory = factory() - #: The memory buffer. The actual data type of buffer depends on `buffer factory`, - #: but it must provide direct acces to cells, slices and length like `bytearray`. - self.raw: bytearray = self.factory.create(init, size) - #: Current position in buffer, i.e. the next read/writen byte would be at this position. - self.pos: int = 0 - #: Value that indicates the end of data. Could be None. - self.eof_marker: int = eof_marker - #: The buffer couldn't grow beyond specified number of bytes [default: `.UNLIMITED`]. - self.max_size: Union[int, Sentinel] = max_size - #: The byte order used to read/write numbers [default: `.LITTLE`]. - self.byteorder: ByteOrder = byteorder
- def _ensure_space(self, size: int) -> None: - if len(self.raw) < self.pos + size: - self.resize(self.pos + size) - def _check_space(self, size: int): - if len(self.raw) < self.pos + size: - raise IOError("Insufficient buffer size") -
[docs] def clear(self) -> None: - """Fills the buffer with zeros and resets the position in buffer to zero. - """ - self.factory.clear(self.raw) - self.pos = 0
-
[docs] def resize(self, size: int) -> None: - """Resize buffer to specified length. - """ - if self.max_size is not UNLIMITED and self.max_size < size: - raise IOError(f"Cannot resize buffer past max. size {self.max_size} bytes") - self.raw = self.factory.create(self.raw, size)
-
[docs] def is_eof(self) -> bool: - """Return True when positioned past the end of buffer or on `.eof_marker` - (if defined). - """ - if self.pos >= len(self.raw): - return True - if self.eof_marker is not None and safe_ord(self.raw[self.pos]) == self.eof_marker: - return True - return False
-
[docs] def write(self, data: bytes) -> None: - """Write bytes. - """ - size = len(data) - self._ensure_space(size) - self.raw[self.pos:self.pos + size] = data - self.pos += size
-
[docs] def write_byte(self, byte: int) -> None: - """Write one byte. - """ - self._ensure_space(1) - self.raw[self.pos] = byte - self.pos += 1
-
[docs] def write_number(self, value: int, size: int, *, signed: bool=False) -> None: - """Write number with specified size (in bytes). - """ - self.write(value.to_bytes(size, self.byteorder.value, signed=signed))
-
[docs] def write_short(self, value: int) -> None: - """Write 2 byte number (c_ushort). - """ - self.write_number(value, 2)
-
[docs] def write_int(self, value: int) -> None: - """Write 4 byte number (c_uint). - """ - self.write_number(value, 4)
-
[docs] def write_bigint(self, value: int) -> None: - """Write tagged 8 byte number (c_ulonglong). - """ - self.write_number(value, 8)
-
[docs] def write_string(self, value: str, *, encoding: str='ascii', errors: str='strict') -> None: - """Write zero-terminated string. - """ - self.write(value.encode(encoding, errors)) - self.write_byte(0)
-
[docs] def write_pascal_string(self, value: str, *, encoding: str='ascii', errors: str='strict') -> None: - """Write tagged Pascal string (2 byte length followed by data). - """ - value = value.encode(encoding, errors) - self.write_byte(len(value)) - self.write(value)
-
[docs] def write_sized_string(self, value: str, *, encoding: str='ascii', errors: str='strict') -> None: - """Write string (2 byte length followed by data). - """ - value = value.encode(encoding, errors) - self.write_short(len(value)) - self.write(value)
-
[docs] def read(self, size: int=-1) -> bytes: - """Reads specified number of bytes, or all remaining data. - """ - if size < 0: - size = self.buffer_size - self.pos - self._check_space(size) - result = self.raw[self.pos: self.pos + size] - self.pos += size - return result
-
[docs] def read_number(self, size: int, *, signed=False) -> int: - """Read number with specified size in bytes. - """ - self._check_space(size) - result = (0).from_bytes(self.raw[self.pos: self.pos + size], self.byteorder.value, signed=signed) - self.pos += size - return result
-
[docs] def read_byte(self, *, signed: bool=False) -> int: - """Read 1 byte number (c_ubyte). - """ - return self.read_number(1, signed=signed)
-
[docs] def read_short(self, *, signed: bool=False) -> int: - """Read 2 byte number (c_ushort). - """ - return self.read_number(2, signed=signed)
-
[docs] def read_int(self, *, signed: bool=False) -> int: - """Read 4 byte number (c_uint). - """ - return self.read_number(4, signed=signed)
-
[docs] def read_bigint(self, *, signed: bool=False) -> int: - """Read 8 byte number (c_ulonglong). - """ - return self.read_number(8, signed=signed)
-
[docs] def read_sized_int(self, *, signed: bool=False) -> int: - """Read number cluster (2 byte length followed by data). - """ - return self.read_number(self.read_short(), signed=signed)
-
[docs] def read_string(self, *, encoding: str='ascii', errors: str='strict') -> str: - """Read null-terminated string. - """ - i = self.pos - while i < self.buffer_size and safe_ord(self.raw[i]) != 0: - i += 1 - result = self.read(i - self.pos).decode(encoding, errors) - self.pos += 1 - return result
-
[docs] def read_pascal_string(self, *, encoding: str='ascii', errors: str='strict') -> str: - """Read Pascal string (1 byte length followed by string data). - """ - return self.read(self.read_byte()).decode(encoding, errors)
-
[docs] def read_sized_string(self, *, encoding: str='ascii', errors: str='strict') -> str: - """Read string (2 byte length followed by data). - """ - return self.read(self.read_short()).decode(encoding, errors)
-
[docs] def read_bytes(self) -> bytes: - """Read content of binary cluster (2 bytes data length followed by data). - """ - return self.read(self.read_short())
- # Properties - @property - def buffer_size(self) -> int: - """Current buffer size in bytes. - """ - return len(self.raw) - @property - def last_data(self) -> int: - """Index of first non-zero byte when searched from the end of buffer. - """ - i = len(self.raw) - 1 - while i >= 0: - if safe_ord(self.raw[i]) != 0: - break - i -= 1 - return i
-
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/collections.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/collections.html deleted file mode 100644 index 3751625..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/collections.html +++ /dev/null @@ -1,729 +0,0 @@ - - - - - - - firebird.base.collections — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.collections

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/collections.py
-# DESCRIPTION:    Various collection types
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2019 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________.
-
-"""Firebird Base - Various collection types
-
-This module provides data structures that behave much like builtin `list` and `dict` types,
-but with direct support of operations that can use structured data stored in container, and
-which would normally require utilization of `operator`, `functools` or other means.
-
-All containers provide next operations:
-
-* `filter` and `filterfalse` that return generator that yields items for which `expr` is
-  evaluated as True (or False).
-* `find` that returns first item for which `expr` is evaluated as True, or default.
-* `contains` that returns True if there is any item for which `expr` is evaluated as True.
-* `occurrence` that returns number of items for which `expr` is evaluated as True.
-* `all` and `any` that return True if `expr` is evaluated as True for all or any list element(s).
-* `report` that returns generator that yields data produced by expression(s) evaluated on
-  list items.
-
-Individual collection types provide additional operations like splitting and extracting
-based on expression etc.
-
-Expressions used by these methods could be strings that contain Python expression
-referencing the collection item(s), or lambda functions.
-"""
-
-from __future__ import annotations
-from typing import Type, Union, Any, Dict, List, Tuple, Mapping, Sequence, Generator, \
-     Iterable, Callable, cast
-from operator import attrgetter
-import copy as std_copy
-from .types import Error, Distinct, Sentinel, UNDEFINED
-
-
-
[docs]def make_lambda(expr: str, params: str='item', context: Dict[str, Any]=None): - """Makes lambda function from expression. - - Arguments: - expr: Python expression as string. - params: Comma-separated list of names that should be used as lambda parameters - context: Dictionary passed as `context` to `eval`. - """ - return eval(f'lambda {params}:{expr}', context) if context else eval(f'lambda {params}:{expr}')
- - -#: Collection Item -Item = Any -#: Collection Item type specification -TypeSpec = Union[Type, Tuple[Type]] -#: Collection Item sort expression -ItemExpr = Union[str, Callable[[Item], Item]] -#: Filter expression -FilterExpr = Union[str, Callable[[Item], bool]] -#: Check expression -CheckExpr = Union[str, Callable[[Item, Any], bool]] - -
[docs]class BaseObjectCollection: - """Base class for collection of objects. - """ -
[docs] def filter(self, expr: FilterExpr) -> Generator[Item, None, None]: - """Returns generator that yields items for which `expr` is evaluated as True. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - L.filter(lambda x: x.name.startswith("ABC")) - L.filter('item.name.startswith("ABC")') - """ - fce = expr if callable(expr) else make_lambda(expr) - return (item for item in self if fce(item))
-
[docs] def filterfalse(self, expr: FilterExpr) -> Generator[Item, None, None]: - """Returns generator that yields items for which `expr` is evaluated as False. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - L.filterfalse(lambda x: x.name.startswith("ABC")) - L.filterfalse('item.name.startswith("ABC")') - """ - fce = expr if callable(expr) else make_lambda(expr) - return (item for item in self if not fce(item))
-
[docs] def find(self, expr: FilterExpr, default: Any=None) -> Item: - """Returns first item for which `expr` is evaluated as True, or default. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - default: Default value returned when Items is not found. - - Example: - .. code-block:: python - - L.find(lambda x: x.name.startswith("ABC")) - L.find('item.name.startswith("ABC")') - """ - for item in self.filter(expr): - return item - return default
-
[docs] def contains(self, expr: FilterExpr=None) -> bool: - """Returns True if there is any item for which `expr` is evaluated as True. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - if L.contains(lambda x: x.name.startswith("ABC")): - ... - if L.contains('item.name.startswith("ABC")'): - ... - """ - return self.find(expr) is not None
-
[docs] def report(self, *args) -> Generator[Any, None, None]: - """Returns generator that yields data produced by expression(s) evaluated on list items. - - Arguments: - args: Parameter(s) could be one from: - - - A callable accepting one parameter and returning data for output - - One or more expressions as string referencing item as `item`. - - Example: - .. code-block:: python - - # generator of tuples with item.name and item.size - - L.report(lambda x: (x.name, x.size)) - L.report('item.name','item.size') - - # generator of item names - - L.report(lambda x: x.name) - L.report('item.name') - """ - if len(args) == 1 and callable(args[0]): - fce = args[0] - else: - attrs = f'({",".join(args) if len(args) > 1 else args[0]})' - fce = make_lambda(attrs) - return (fce(item) for item in self)
-
[docs] def occurrence(self, expr: FilterExpr) -> int: - """Return number of items for which `expr` is evaluated as True. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - L.occurrence(lambda x: x.name.startswith("ABC")) - L.occurrence('item.name.startswith("ABC")') - """ - return sum(1 for item in self.filter(expr))
-
[docs] def all(self, expr: FilterExpr) -> bool: - """Return True if `expr` is evaluated as True for all list elements. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returning bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - L.all(lambda x: x.name.startswith("ABC")) - L.all('item.name.startswith("ABC")') - """ - fce = expr if callable(expr) else make_lambda(expr) - for item in self: - if not fce(item): - return False - return True
-
[docs] def any(self, expr: FilterExpr) -> bool: - """Return True if `expr` is evaluated as True for any list element. - - Arguments: - expr: Bool expression, a callable accepting one parameter and returnin bool or - bool expression as string referencing list item as `item`. - - Example: - .. code-block:: python - - L.any(lambda x: x.name.startswith("ABC")) - L.any('item.name.startswith("ABC")') - """ - fce = expr if callable(expr) else make_lambda(expr) - for item in self: - if fce(item): - return True - return False
- -
[docs]class DataList(List[Item], BaseObjectCollection): - """List of data (objects) with additional functionality. - """ -
[docs] def __init__(self, items: Iterable=None, type_spec: TypeSpec=UNDEFINED, - key_expr: str=None, frozen: bool=False): - """ - Arguments: - items: Sequence to initialize the collection. - type_spec: Reject instances that are not instances of specified types. - key_expr: Key expression. Must contain item referrence as `item`, for example - `item.attribute_name`. If **all** classes specified in `type_spec` - are descendants of `.Distinct`, the default value is `item.get_key()`, - otherwise the default is `None`. - frozen: Create frozen list. - - Raises: - ValueError: When initialization sequence contains invalid instance. - """ - assert key_expr is None or isinstance(key_expr, str) - assert key_expr is None or make_lambda(key_expr) is not None - if items is not None: - super().__init__(items) - else: - super().__init__() - if type_spec is not UNDEFINED and key_expr is None: - all_distinct = True - if isinstance(type_spec, tuple): - for ts in type_spec: - all_distinct = all_distinct and issubclass(ts, Distinct) - else: - all_distinct = all_distinct and issubclass(type_spec, Distinct) - if all_distinct: - key_expr = 'item.get_key()' - self.__key_expr: str = key_expr - self.__frozen: bool = False - self._type_spec: TypeSpec = type_spec - self.__map: Dict = None - if frozen: - self.freeze()
- def __valchk(self, value: Item) -> None: - if self._type_spec is not UNDEFINED and not isinstance(value, self._type_spec): - raise TypeError("Value is not an instance of allowed class") - def __updchk(self) -> None: - if self.__frozen: - raise TypeError("Cannot modify frozen DataList") - def __setitem__(self, index, value) -> None: - self.__updchk() - if isinstance(index, slice): - for val in value: - self.__valchk(val) - else: - self.__valchk(value) - super().__setitem__(index, value) - def __delitem__(self, index) -> None: - self.__updchk() - super().__delitem__(index) - def __contains__(self, o): - if self.__map is not None: - if isinstance(o, Distinct) and self.__key_expr == 'item.get_key()': - return o.get_key() in self.__map - return make_lambda(self.__key_expr)(o) in self.__map - return super().__contains__(o) -
[docs] def insert(self, index: int, item: Item) -> None: - """Insert item before index. - - Raises: - TypeError: When item is not an instance of allowed class, or list is frozen - """ - self.__updchk() - self.__valchk(item) - super().insert(index, item)
-
[docs] def remove(self, item: Item) -> None: - """Remove first occurrence of item. - - Raises: - ValueError: If the value is not present, or list is frozen - """ - self.__updchk() - super().remove(item)
-
[docs] def append(self, item: Item) -> None: - """Add an item to the end of the list. - - Raises: - TypeError: When item is not an instance of allowed class, or list is frozen - """ - self.__updchk() - self.__valchk(item) - super().append(item)
-
[docs] def extend(self, iterable: Iterable) -> None: - """Extend the list by appending all the items in the given iterable. - - Raises: - TypeError: When item is not an instance of allowed class, or list is frozen - """ - for item in iterable: - self.append(item)
-
[docs] def sort(self, attrs: List=None, expr: ItemExpr=None, reverse: bool=False) -> None: - """Sort items in-place, optionaly using attribute values as key or key expression. - - Arguments: - attrs: List of attribute names. - expr: Key expression, a callable accepting one parameter or expression - as string referencing list item as `item`. - - Important: - Only one parameter (`attrs` or `expr`) could be specified. - If none is present then uses default list sorting rule. - - Example: - .. code-block:: python - - L.sort(attrs=['name','degree']) # Sort by item.name, item.degree - L.sort(expr=lambda x: x.name.upper()) # Sort by upper item.name - L.sort(expr='item.name.upper()') # Sort by upper item.name - """ - assert attrs is None or isinstance(attrs, (list, tuple)) - if attrs: - super().sort(key=attrgetter(*attrs), reverse=reverse) - elif expr: - super().sort(key=expr if callable(expr) else make_lambda(expr), reverse=reverse) - elif self.__key_expr: - super().sort(key=make_lambda(self.__key_expr), reverse=reverse) - else: - super().sort(reverse=reverse)
-
[docs] def clear(self) -> None: - """Remove all items from the list. - - Raises: - TypeError: When list is frozen. - """ - self.__updchk() - super().clear()
-
[docs] def freeze(self) -> None: - """Set list to immutable (frozen) state. - - Freezing list makes internal map from `key_expr` to item index that significantly - speeds up retrieval by key using the `get()` method. - - It's not possible to `add`, `delete` or `change` items in frozen list, but `.sort` - is allowed. - """ - self.__frozen = True - if self.__key_expr: - fce = make_lambda(self.__key_expr) - self.__map = dict(((key, index) for index, key in enumerate((fce(item) for item in self))))
-
[docs] def split(self, expr: FilterExpr, frozen: bool=False) -> Tuple[DataList, DataList]: - """Return two new `DataList` instances, first with items for which `expr` is - evaluated as True and second for `expr` evaluated as False. - - Arguments: - expr: A callable accepting one parameter or expression as string referencing - list item as `item`. - frozen: Create frozen lists. - - Example: - .. code-block:: python - - below, above = L.split(lambda x: x.size > 100) - below, above = L.split('item.size > 100') - """ - return DataList(self.filter(expr), self._type_spec, self.__key_expr, frozen=frozen), \ - DataList(self.filterfalse(expr), self._type_spec, self.__key_expr, frozen=frozen)
-
[docs] def extract(self, expr: FilterExpr, copy: bool=False) -> DataList: - """Move/copy items for which `expr` is evaluated as True into new `DataList`. - - Arguments: - expr: A callable accepting one parameter or expression as string referencing list item - as `item`. - copy: When True, items are not removed from source DataList. - - Raises: - TypeError: When list is frozen and `copy` is False. - - Example: - .. code-block:: python - - L.extract(lambda x: x.name.startswith("ABC")) - L.extract('item.name.startswith("ABC")') - """ - if not copy: - self.__updchk() - fce = expr if callable(expr) else make_lambda(expr) - l = DataList(type_spec=self._type_spec, key_expr=self.__key_expr) - i = 0 - while len(self) > i: - item = self[i] - if fce(item): - l.append(item) - if not copy: - del self[i] - else: - i += 1 - else: - i += 1 - return l
-
[docs] def get(self, key: Any, default: Any=None) -> Item: - """Returns item with given key using default key expression. Returns `default` - value if item is not found. - - Uses very fast method to look up value of default key expression in `frozen` list, - otherwise it uses slower list traversal. - - Arguments: - key: Searched value. - default: Default value. - - Raises: - Error: If key expression is not defined. - - Example: - .. code-block:: python - - # Search using default key expression (fast for frozen list) - L.get('ITEM_NAME') - """ - if not self.__key_expr: - raise Error("Key expression required") - if self.__map: - i = self.__map.get(key) - return default if i is None else self[i] - fce = make_lambda(f'{self.__key_expr} == key', 'item, key') - for item in self: - if fce(item, key): - return item - return default
- @property - def frozen(self) -> bool: - """True if list items couldn't be changed. - """ - return self.__frozen - @property - def key_expr(self) -> Item: - """Key expression. - """ - return self.__key_expr - @property - def type_spec(self) -> Union[TypeSpec, Sentinel]: - """Specification of valid type(s) for list values, or `.UNDEFINED` if there is - no such constraint. - """ - return self._type_spec
- -
[docs]class Registry(BaseObjectCollection, Mapping[Any, Distinct]): - """Mapping container for `.Distinct` objects. - - Any method that expects a `key` also acepts `.Distinct` instance. - - To store items into registry with existence check, use: - - R.store(item) - - R.extend(items) or R.extend(item) - - To update items in registry (added if not present), use: - - R[key] = item - - R.update(items) or R.update(item) - - To check presence of item or key in registry, use: - - key in R - - To retrieve items from registry, use: - - R.get(key, default=None) - - R[key] - - R.pop(key, default=None) - - R.popitem(last=True) - - To delete items from registry, use: - - R.remove(item) - - del R[key] - - Whenever a `key` is required, you can use either a `Distinct` instance, or any value - that represens a key value for instances of stored type. - """ -
[docs] def __init__(self, data: Union[Mapping, Sequence, Registry]=None): - """ - Arguments: - data: Either a `.Distinct` instance, or sequence or mapping of `.Distinct` - instances. - """ - self._reg: Dict = {} - if data: - self.update(data)
- def __len__(self): - return len(self._reg) - def __getitem__(self, key): - return self._reg[key.get_key() if isinstance(key, Distinct) else key] - def __setitem__(self, key, value): - assert isinstance(value, Distinct) - self._reg[key.get_key() if isinstance(key, Distinct) else key] = value - def __delitem__(self, key): - del self._reg[key.get_key() if isinstance(key, Distinct) else key] - def __iter__(self): - return iter(self._reg.values()) - def __repr__(self): - return f"{self.__class__.__name__}(" \ - f"[{', '.join(repr(x) for x in self)}])" - def __contains__(self, item): - if isinstance(item, Distinct): - item = item.get_key() - return item in self._reg -
[docs] def clear(self) -> None: - """Remove all items from registry. - """ - self._reg.clear()
-
[docs] def get(self, key: Any, default: Any=None) -> Distinct: - """ D.get(key[,d]) -> D[key] if key in D else d. d defaults to None. - """ - return self._reg.get(key.get_key() if isinstance(key, Distinct) else key, default)
-
[docs] def store(self, item: Distinct) -> Distinct: - """Register an item. - - Raises: - ValueError: When item is already registered. - """ - assert isinstance(item, Distinct), f"Item is not of type '{Distinct.__name__}'" - key = item.get_key() - if key in self._reg: - raise ValueError(f"Item already registered, key: '{key}'") - self._reg[key] = item - return item
-
[docs] def remove(self, item: Distinct): - """Removes item from registry (same as: del R[item]). - """ - del self._reg[item.get_key()]
-
[docs] def update(self, _from: Union[Distinct, Mapping, Sequence]) -> None: - """Update items in the registry. - - Arguments: - _from: Either a `.Distinct` instance, or sequence or mapping of `.Distinct` - instances. - """ - if isinstance(_from, Distinct): - self[_from] = _from - else: - for item in cast(Mapping, _from).values() if hasattr(_from, 'values') else _from: - self[item] = item
-
[docs] def extend(self, _from: Union[Distinct, Mapping, Sequence]) -> None: - """Store one or more items to the registry. - - Arguments: - _from: Either a `.Distinct` instance, or sequence or mapping of `.Distinct` - instances. - """ - if isinstance(_from, Distinct): - self.store(_from) - else: - for item in cast(Mapping, _from).values() if hasattr(_from, 'values') else _from: - self.store(item)
-
[docs] def copy(self) -> Registry: - """Shalow copy of the registry. - """ - if self.__class__ is Registry: - return Registry(self) - data = self._reg - try: - self._reg = {} - c = std_copy.copy(self) - finally: - self._reg = data - c.update(self) - return c
-
[docs] def pop(self, key: Any, default: Any=None) -> Distinct: - """Remove specified `key` and return the corresponding `.Distinct` object. If `key` - is not found, the `default` is returned if given, otherwise `KeyError` is raised. - """ - return self._reg.pop(key.get_key() if isinstance(key, Distinct) else key, default)
-
[docs] def popitem(self, last: bool=True) -> Distinct: - """Returns and removes a `.Distinct` object. The objects are returned in LIFO order - if `last` is true or FIFO order if false. - """ - if last: - _, item = self._reg.popitem() - return item - item = next(iter(self)) - self.remove(item) - return item
-
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/config.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/config.html deleted file mode 100644 index 3ccb6de..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/config.html +++ /dev/null @@ -1,2702 +0,0 @@ - - - - - - - firebird.base.config — Firebird-base 1.6.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.config

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/config.py
-# DESCRIPTION:    Classes for configuration definitions
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2019 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________.
-
-"""Firebird Base - Classes for configuration definitions
-
-Complex applications (and some library modules like `logging`) could be often parametrized
-via configuration. This module provides a framework for unified structured configuration
-that supports:
-
-* configuration options of various data type, including lists and other complex types
-* validation
-* direct manipulation of configuration values
-* reading from (and writing into) configuration in `configparser` format
-* exchanging configuration (for example between processes) using Google protobuf messages
-* application directory scheme
-"""
-
-from __future__ import annotations
-from typing import Generic, Type, Any, List, Dict, Union, Sequence, Callable, Optional, \
-     TypeVar, cast, get_type_hints
-from abc import ABC, abstractmethod
-import platform
-from pathlib import Path
-from uuid import UUID
-from decimal import Decimal, DecimalException
-from configparser import ConfigParser, DEFAULTSECT
-from inspect import signature, Signature, Parameter
-from enum import Enum, Flag
-import os
-from .config_pb2 import ConfigProto
-from .types import Error, MIME, ZMQAddress, PyExpr, PyCode, PyCallable
-from .strconv import get_convertor, convert_to_str, Convertor
-
-PROTO_CONFIG = 'firebird.base.ConfigProto'
-
-def unindent_verticals(value: str) -> str:
-    """Removes trailing '|' character from each line in multiline string."""
-    lines = []
-    indent = None
-    for line in value.split('\n'):
-        if line.startswith('|'):
-            if indent is None:
-                indent = (len(line[1:]) - len(line[1:].strip())) + 1
-            lines.append(line[indent:])
-        else:
-            lines.append(line)
-    return '\n'.join(lines)
-
-def _eq(a: Any, b: Any) -> bool:
-    return str(a) == str(b)
-
-
[docs]def create_config(_cls: Type[Config], name: str) -> Config: # pragma: no cover - """Return newly created `Config` instance. Intended to be used with `functools.partial`. - """ - return _cls(name)
- -# Next two functions are copied from stdlib enum module, as they were removed in Python 3.11 - -def _decompose(flag, value): - """ - Extract all members from the value. - """ - # _decompose is only called if the value is not named - not_covered = value - negative = value < 0 - # issue29167: wrap accesses to _value2member_map_ in a list to avoid race - # conditions between iterating over it and having more pseudo- - # members added to it - if negative: - # only check for named flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None - ] - else: - # check for named flags and powers-of-two flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None or _power_of_two(v) - ] - members = [] - for member, member_value in flags_to_check: - if member_value and member_value & value == member_value: - members.append(member) - not_covered &= ~member_value - if not members and value in flag._value2member_map_: - members.append(flag._value2member_map_[value]) - members.sort(key=lambda m: m._value_, reverse=True) - if len(members) > 1 and members[0].value == value: - # we have the breakdown, don't need the value member itself - members.pop(0) - return members, not_covered - -def _power_of_two(value): - if value < 1: - return False - return value == 2 ** (value.bit_length() - 1) - -
[docs]class DirectoryScheme: - """Class that provide paths to typically used application directories. - - Default scheme uses HOME directory as root for other directories. The HOME is - determined as follows: - - 1. If environment variable `<app_name>_HOME` exists, its value is used as HOME directory. - 2. HOME directory is set to current working directory. - - Note: - All paths are set when the instance is created and can be changed later. - """ -
[docs] def __init__(self, name: str, version: str=None, force_home: bool=False): - """ - Arguments: - name: Appplication name. - version: Application version. - force_home: When True, general directories (i.e. all except user-specific and - TMP) would be always based on HOME directory. - """ - self.name: str = name - self.version: str = version - self.force_home: bool = force_home - _h = os.getenv(f'{self.name.upper()}_HOME') - self.__home: Path = Path(_h) if _h is not None else Path(os.getcwd()) - home = self.home - self.dir_map: Dict[str, Path] = {'config': home / 'config', - 'run_data': home / 'run_data', - 'logs': home / 'logs', - 'data': home / 'data', - 'tmp': home / 'tmp', - 'cache': home / 'cache', - 'srv': home / 'srv', - 'user_config': home / 'user_config', - 'user_data': home / 'user_data', - 'user_sync': home / 'user_sync', - 'user_cache': home / 'user_cache', - }
-
[docs] def has_home_env(self) -> bool: - """Returns True if HOME directory is set by "<app_name>_HOME" environment variable. - """ - return os.getenv(f'{self.name.upper()}_HOME') is not None
- @property - def home(self) -> Path: - """HOME directory. Initial value is path set by `<app_name>_HOME` environment - variable, or to current working directory when variable is not defined. - - Important: - When new value is assigned, the general directories (i.e. all except user-specific - and TMP) are redefined as subdirectories of new home path ONLY when HOME was - initially defined using `<app_name>_HOME` environment variable, or instance - was created with `force_home` = True. - - However, all paths could be still changed individually to any value. - """ - return self.__home - @home.setter - def home(self, value: Union[Path, str]) -> None: - self.__home = value if isinstance(value, Path) else Path(value) - if self.has_home_env() or self.force_home: - self.dir_map.update({'config': self.__home / 'config', - 'run_data': self.__home / 'run_data', - 'logs': self.__home / 'logs', - 'data': self.__home / 'data', - 'cache': self.__home / 'cache', - 'srv': self.__home / 'srv'}) - @property - def config(self) -> Path: - """Directory for host-specific system-wide configuration files. - """ - return self.dir_map['config'] - @config.setter - def config(self, path: Path) -> None: - self.dir_map['config'] = path - @property - def run_data(self) -> Path: - """Directory for run-time variable data that may not persist over boot. - """ - return self.dir_map['run_data'] - @run_data.setter - def run_data(self, path: Path) -> None: - self.dir_map['run_data'] = path - @property - def logs(self) -> Path: - """Directory for log files. - """ - return self.dir_map['logs'] - @logs.setter - def logs(self, path: Path) -> None: - self.dir_map['logs'] = path - @property - def data(self) -> Path: - """Directory for state information / persistent data modified by application as - it runs. - """ - return self.dir_map['data'] - @data.setter - def data(self, path: Path) -> None: - self.dir_map['data'] = path - @property - def tmp(self) -> Path: - """Directory for temporary files to be preserved between reboots. - """ - return self.dir_map['tmp'] - @tmp.setter - def tmp(self, path: Path) -> None: - self.dir_map['tmp'] = path - @property - def cache(self) -> Path: - """Directory for application cache data. - - Such data are locally generated as a result of time-consuming I/O or calculation. - The application must be able to regenerate or restore the data. The cached files - can be deleted without loss of data. - """ - return self.dir_map['cache'] - @cache.setter - def cache(self, path: Path) -> None: - self.dir_map['cache'] = path - @property - def srv(self) -> Path: - """Directory for site-specific data served by this system, such as data and - scripts for web servers, data offered by FTP servers, and repositories for - version control systems etc. - """ - return self.dir_map['srv'] - @srv.setter - def srv(self, path: Path) -> None: - self.dir_map['srv'] = path - @property - def user_config(self) -> Path: - """Directory for user-specific configuration. - """ - return self.dir_map['user_config'] - @user_config.setter - def user_config(self, path: Path) -> None: - self.dir_map['user_config'] = path - @property - def user_data(self) -> Path: - """Directory for User local data. - """ - return self.dir_map['user_data'] - @user_data.setter - def user_data(self, path: Path) -> None: - self.dir_map['user_data'] = path - @property - def user_sync(self) -> Path: - """Directory for user data synced accross systems (roaming). - """ - return self.dir_map['user_sync'] - @user_sync.setter - def user_sync(self, path: Path) -> None: - self.dir_map['user_sync'] = path - @property - def user_cache(self) -> Path: - """Directory for user-specific application cache data. - """ - return self.dir_map['user_cache'] - @user_cache.setter - def user_cache(self, path: Path) -> None: - self.dir_map['user_cache'] = path
- - -
[docs]class WindowsDirectoryScheme(DirectoryScheme): - """Directory scheme that conforms to Windows standards. - - If HOME is defined using "<app_name>_HOME" environment variable, or `force_home` parameter - is True, only user-specific directories and TMP are set according to platform standars, - while general directories remain as defined by base `DirectoryScheme`. - """ -
[docs] def __init__(self, name: str, version: str=None, force_home: bool=False): - """ - Arguments: - name: Appplication name. - version: Application version. - force_home: When True, general directories (i.e. all except user-specific and - TMP) would be always based on HOME directory. - """ - super().__init__(name, version, force_home) - app_dir = Path(self.name) - if self.version is not None: - app_dir /= self.version - pd = Path(os.path.expandvars('%PROGRAMDATA%')) - lad = Path(os.path.expandvars('%LOCALAPPDATA%')) - ad = Path(os.path.expandvars('%APPDATA%')) - # Set general directories only when HOME is not forced by environment variable. - if not self.has_home_env() and not force_home: - self.dir_map.update({'config': pd / app_dir / 'config', - 'run_data': pd / app_dir / 'run', - 'logs': pd / app_dir / 'log', - 'data': pd / app_dir / 'data', - 'cache': pd / app_dir / 'cache', - 'srv': pd / app_dir / 'srv', - }) - # Always set user-specific directories and TMP - self.dir_map.update({'tmp': lad / app_dir / 'tmp', - 'user_config': lad / app_dir / 'config', - 'user_data': lad / app_dir / 'data', - 'user_sync': ad / app_dir, - 'user_cache': lad / app_dir / 'cache', - })
- -
[docs]class LinuxDirectoryScheme(DirectoryScheme): - """Directory scheme that conforms to Linux standards. - - If HOME is defined using "<app_name>_HOME" environment variable, or `force_home` parameter - is True, only user-specific directories and TMP are set according to platform standars, - while general directories remain as defined by base `DirectoryScheme`. - """ -
[docs] def __init__(self, name: str, version: str=None, force_home: bool=False): - """ - Arguments: - name: Appplication name. - version: Application version. - force_home: When True, general directories (i.e. all except user-specific and - TMP) would be always based on HOME directory. - """ - super().__init__(name, version, force_home) - app_dir = Path(self.name) - if self.version is not None: - app_dir /= self.version - # Set general directories only when HOME is not forced by environment variable. - if not self.has_home_env() and not force_home: - self.dir_map.update({'config': Path('/etc') / app_dir, - 'run_data': Path('/run') / app_dir, - 'logs': Path('/var/log') / app_dir, - 'data': Path('/var/lib') / app_dir, - 'cache': Path('/var/cache') / app_dir, - 'srv': Path('/srv') / app_dir, - }) - # Always set user-specific directories and TMP - self.dir_map.update({'tmp': Path('/var/tmp') / app_dir, - 'user_config': Path('~/.config').expanduser() / app_dir, - 'user_data': Path('~/.local/share').expanduser() / app_dir, - 'user_sync': Path('~/.local/sync').expanduser() / app_dir, - 'user_cache': Path('~/.cache').expanduser() / app_dir, - })
- -
[docs]class MacOSDirectoryScheme(DirectoryScheme): - """Directory scheme that conforms to MacOS standards. - - If HOME is defined using "<app_name>_HOME" environment variable, only user-specific - directories and TMP are set according to platform standars, while general directories - remain as defined by base `DirectoryScheme`. - """ -
[docs] def __init__(self, name: str, version: str=None, force_home: bool=False): - """ - Arguments: - name: Appplication name. - version: Application version. - """ - super().__init__(name, version, force_home) - app_dir = Path(self.name) - if self.version is not None: - app_dir /= self.version - pd = Path('/Library/Application Support') - lad = Path('~/Library/Application Support').expanduser() - # Set general directories only when HOME is not forced by environment variable. - if not self.has_home_env() and not force_home: - self.dir_map.update({'config': pd / app_dir / 'config', - 'run_data': pd / app_dir / 'run', - 'logs': pd / app_dir / 'log', - 'data': pd / app_dir / 'data', - 'cache': pd / app_dir / 'cache', - 'srv': pd / app_dir / 'srv', - }) - # Always set user-specific directories and TMP - self.dir_map.update({'tmp': Path(os.getenv('TMPDIR')) / app_dir, - 'user_config': lad / app_dir / 'config', - 'user_data': lad / app_dir / 'data', - 'user_sync': lad / app_dir, - 'user_cache': Path('~/Library/Caches').expanduser() / app_dir / 'cache', - })
- -
[docs]def get_directory_scheme(app_name: str, version: str=None, *, force_home: bool=False) -> DirectoryScheme: - """Returns directory scheme for current platform. - - Arguments: - app_name: Application name - version: Application version string - force_home: When True, the general directies are always set to subdirectories of - `DirectoryScheme.home` directory. When False, these the home is used - ONLY when it's set by "<app_name>_HOME" environment variable. - """ - return {'Windows': WindowsDirectoryScheme, - 'Linux':LinuxDirectoryScheme, - 'Darwin': MacOSDirectoryScheme}.get(platform.system(), DirectoryScheme)(app_name, version, force_home)
- -T = TypeVar('T') - -
[docs]class Option(Generic[T], ABC): - """Generic abstract base class for configuration options. - """ -
[docs] def __init__(self, name: str, datatype: T, description: str, required: bool=False, - default: T=None): - """ - Arguments: - name: Option name. - datatype: Option datatype. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - assert name and isinstance(name, str), "name required" - assert datatype and isinstance(datatype, type), "datatype required" - assert description and isinstance(description, str), "description required" - assert default is None or isinstance(default, datatype), "default has wrong data type" - #: Option name. - self.name: str = name - #: Option datatype. - self.datatype: T = datatype - #: Option description. Can span multiple lines. - self.description: str = description - #: True if option must have a value. - self.required: bool = required - #: Default option value. - self.default: T = default - if default is not None: - self.set_value(default)
- def _check_value(self, value: T) -> None: - if value is None and self.required: - raise ValueError(f"Value is required for option '{self.name}'.") - if value is not None and not isinstance(value, self.datatype): - raise TypeError(f"Option '{self.name}' value must be a " - f"'{self.datatype.__name__}'," - f" not '{type(value).__name__}'") - def _get_value_description(self) -> str: - return f'{self.datatype.__name__}\n' -
[docs] def _get_config_lines(self, plain: bool=False) -> List[str]: - """Returns list of strings containing text lines suitable for use in configuration - file processed with `~configparser.ConfigParser`. - - Text lines with configuration start with comment marker `;` and end with newline. - - Arguments: - plain: When True, it outputs only the option value. When False, it includes also - option description and other helpful information. - - Note: - This function is intended for internal use. To get string describing current - configuration that is suitable for configuration files, use `get_config` method. - """ - lines = [] - if not plain: - if self.required: - lines.append("; REQUIRED option.\n") - for line in self.description.strip().splitlines(): - lines.append(f"; {line}\n") - first = True - for line in self._get_value_description().splitlines(): - lines.append(f"; {'Type: ' if first else ''}{line}\n") - first = False - value = self.get_value() - nodef = ';' if value == self.default else '' - value = '<UNDEFINED>' if value is None else self.get_formatted() - if '\n' in value: - chunks = value.splitlines(keepends=True) - new_value = [chunks[0]] - new_value.extend(f'{nodef}{x}' for x in chunks[1:]) - value = ''.join(new_value) - lines.append(f"{nodef}{self.name} = {value}\n") - return lines
-
[docs] def load_config(self, config: ConfigParser, section: str) -> None: - """Update option value from `~configparser.ConfigParser` instance. - - Arguments: - config: ConfigParser instance. - section: Name of ConfigParser section that should be used to get new option - value. - - Raises: - ValueError: When option value cannot be loadded. - KeyError: If section does not exists, and it's not `configparser.DEFAULTSECT`. - """ - if not config.has_section(section) and section != DEFAULTSECT: - raise KeyError(f"Configuration error: section '{section}' not found!") - if config.has_option(section, self.name): - self.set_as_str(config[section][self.name])
-
[docs] def validate(self) -> None: - """Validates option state. - - Raises: - Error: When required option does not have a value. - """ - if self.required and self.get_value() is None: - raise Error(f"Missing value for required option '{self.name}'")
-
[docs] def get_config(self, *, plain: bool=False) -> str: - """Returns string containing text lines suitable for use in configuration file - processed with `~configparser.ConfigParser`. - - Arguments: - plain: When True, it outputs only the option value. When False, it includes also - option description and other helpful information. - """ - return ''.join(self._get_config_lines(plain=plain))
-
[docs] def has_value(self) -> bool: - """Returns True if option value is not None. - """ - return self.get_value() is not None
-
[docs] @abstractmethod - def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """
-
[docs] @abstractmethod - def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """
-
[docs] @abstractmethod - def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """
-
[docs] @abstractmethod - def get_as_str(self) -> str: - """Returns value as string. - """
-
[docs] @abstractmethod - def get_value(self) -> T: - """Returns current option value. - """
-
[docs] @abstractmethod - def set_value(self, value: T) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """
-
[docs] @abstractmethod - def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """
-
[docs] @abstractmethod - def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """
- -
[docs]class Config: - """Collection of configuration options. - - Important: - Descendants must define individual options and sub configs as instance attributes. - """ -
[docs] def __init__(self, name: str, *, optional: bool=False, description: str=None): - """ - Arguments: - name: Name associated with Config (default section name). - optional: Whether config is optional (False) or mandatory (True) for - configuration file (see `.load_config()` for details). - description: Optional configuration description. Can span multiple lines. - """ - self._name: str = name - self._optional: bool = optional - self._description: str = description if description is not None else self.__doc__
- def __setattr__(self, name, value): - for attr in vars(self).values(): - if isinstance(attr, Option) and attr.name == name: - raise ValueError('Cannot assign values to option itself, use `option.value` instead') - super().__setattr__(name, value) -
[docs] def validate(self) -> None: - """Checks whether: - - all required options have value other than None. - - all options are defined as config attribute with the same name as option name - - Raises exception when any constraint required by configuration is violated. - """ - for option in self.options: - option.validate() - if not hasattr(self, option.name): - raise Error(f"Option '{option.name}' is not defined as " - f"attribute with the same name")
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears all owned options and options in owned sub-configs. - - Arguments: - to_default: If True, sets the option values to defaults, else to None. - """ - for option in self.options: - option.clear(to_default=to_default) - for config in self.configs: - config.clear(to_default=to_default)
-
[docs] def get_description(self) -> str: - """Configuration description. Can span multiple lines. - - Note: If description is not provided on instance creation, class doc string. - """ - return '' if self._description is None else self._description
-
[docs] def get_config(self, *, plain: bool=False) -> str: - """Returns string containing text lines suitable for use in configuration file - processed with `~configparser.ConfigParser`. - - Arguments: - plain: When True, it outputs only the option values. When False, it includes also - option descriptions and other helpful information. - """ - lines = [f'[{self.name}]\n', ';\n'] - if not plain: - for line in self.get_description().strip().splitlines(): - lines.append(f"; {line}\n") - for option in self.options: - if not plain: - lines.append('\n') - lines.append(option.get_config(plain=plain)) - for config in self.configs: - if not plain: - lines.append('\n') - lines.append(config.get_config()) - return ''.join(lines)
-
[docs] def load_config(self, config: ConfigParser, section: str=None) -> None: - """Update configuration. - - Arguments: - config: ConfigParser instance with configuration values. - section: Name of ConfigParser section that should be used to get new - configuration values. If not provided, uses `name`. - - Raises: - ValueError: When any option value cannot be loadded. - KeyError: If section does not exists, and config is not `optional` or section is - not `configparser.DEFAULTSECT`. - """ - if section is None: - section = self.name - if not config.has_section(section): - if self._optional: - return - if section != DEFAULTSECT: - raise Error(f"Configuration error: section '{section}' not found!") - try: - for option in self.options: - option.load_config(config, section) - for subcfg in self.configs: - subcfg.load_config(config) - except Error: - raise - except Exception as exc: # pragma: no cover - raise Error(f"Configuration error: {exc}") from exc
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains option values and sub-configs. - """ - for option in self.options: - option.load_proto(proto) - for subcfg in self.configs: - if subcfg.name in proto.configs: - subcfg.load_proto(proto.configs[subcfg.name])
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option values and sub-configs should be stored. - """ - for option in self.options: - option.save_proto(proto) - for subcfg in self.configs: - subcfg.save_proto(proto.configs.get_or_create(subcfg.name))
- @property - def name(self) -> str: - """Name associated with Config (default section name). - """ - return self._name - @property - def optional(self) -> bool: - """Whether config is optional (False) or mandatory (True) for configuration file - (see `.load_config()` for details). - """ - return self._optional - @property - def options(self) -> List[Option]: - """List of options defined for this Config instance. - """ - return [v for v in vars(self).values() if isinstance(v, Option)] - @property - def configs(self) -> List[Config]: - """List of sub-Configs defined for this Config instance. It includes all instance - attributes of `Config` type, and `Config` values of owned `ConfigOption` and - `ConfigListOption` instances. - """ - result = [v if isinstance(v, Config) else v.value - for v in vars(self).values() if isinstance(v, (Config, ConfigOption))] - for opt in (v for v in vars(self).values() if isinstance(v, ConfigListOption)): - result.extend(opt.value) - return result
- -# Options -
[docs]class StrOption(Option[str]): - """Configuration option with string value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: str=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: str = None - super().__init__(name, str, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = self._value - if '\n' in result: - lines = [] - for line in result.splitlines(True): - if lines: - lines.append(' ' + line) - else: - lines.append(line) - result = ''.join(lines) - return result
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = value
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value
-
[docs] def get_value(self) -> str: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: str) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_value(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: str = property(get_value, set_value, doc="Current option value")
- -
[docs]class IntOption(Option[int]): - """Configuration option with integer value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, - default: int=None, signed: bool=False): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - signed: When False, the option value cannot be negative. - """ - self._value: int = None - self.__signed: bool = signed - super().__init__(name, int, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else str(self._value)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - new = int(value) - if not self.__signed and new < 0: - raise ValueError("Negative numbers not allowed") - self._value = new
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return str(self._value)
-
[docs] def get_value(self) -> int: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: int) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - if value is not None and (not self.__signed and value < 0): - raise ValueError("Negative numbers not allowed") - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_sint32', 'as_sint64', 'as_uint32', 'as_uint64', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_string': - self.set_as_str(opt.as_string) - else: - self.set_value(getattr(opt, oneof))
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - opt = proto.options[self.name] - if self.__signed: - opt.as_sint64 = self._value - else: - opt.as_uint64 = self._value
- value: int = property(get_value, set_value, doc="Current option value")
- -
[docs]class FloatOption(Option[float]): - """Configuration option with float value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: float=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: float = None - super().__init__(name, float, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else str(self._value)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = float(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return str(self._value)
-
[docs] def get_value(self) -> float: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: float) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_float', 'as_double', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_string': - self.set_as_str(opt.as_string) - else: - self.set_value(getattr(opt, oneof))
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_double = self._value
- value: float = property(get_value, set_value, doc="Current option value")
- -
[docs]class DecimalOption(Option[Decimal]): - """Configuration option with decimal.Decimal value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: Decimal=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: Decimal = None - super().__init__(name, Decimal, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else str(self._value)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - try: - self._value = Decimal(value) - except DecimalException as exc: - raise ValueError(str(exc)) from exc
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return str(self._value)
-
[docs] def get_value(self) -> Decimal: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: Decimal) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto): - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_sint32', 'as_sint64', 'as_uint32', 'as_uint64', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_string': - self.set_as_str(opt.as_string) - else: - self.set_value(Decimal(getattr(opt, oneof)))
-
[docs] def save_proto(self, proto: ConfigProto): - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = str(self._value)
- value: Decimal = property(get_value, set_value, doc="Current option value")
- -
[docs]class BoolOption(Option[bool]): - """Configuration option with boolean value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: bool=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: bool = None - self.from_str = get_convertor(bool).from_str - super().__init__(name, bool, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - return 'yes' if self._value else 'no'
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = self.from_str(bool, value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return str(self._value)
-
[docs] def get_value(self) -> bool: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: bool) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_bool', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_string': - self.set_as_str(opt.as_string) - else: - self.set_value(opt.as_bool)
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_bool = self._value
- value: bool = property(get_value, set_value, doc="Current option value")
- -
[docs]class ZMQAddressOption(Option[ZMQAddress]): - """Configuration option with `.ZMQAddress` value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, - default: ZMQAddress=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: ZMQAddress = None - super().__init__(name, ZMQAddress, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else self._value
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = ZMQAddress(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value
-
[docs] def get_value(self) -> ZMQAddress: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: ZMQAddress) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: ZMQAddress = property(get_value, set_value, doc="Current option value")
- -
[docs]class EnumOption(Option[Enum]): - """Configuration option with enum value. - """ -
[docs] def __init__(self, name: str, enum_class: Enum, description: str, *, required: bool=False, - default: Enum=None, allowed: List=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - allowed: List of allowed Enum members. When not defined, all members of enum type are - allowed. - """ - self._value: Enum = None - #: List of allowed enum values. - self.allowed: Sequence = enum_class if allowed is None else allowed - self._members: Dict = {i.name.lower(): i for i in self.allowed} - super().__init__(name, enum_class, description, required, default)
- def _get_value_description(self) -> str: - return f"enum [{', '.join(x.name.lower() for x in self.allowed)}]\n" -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else self._value.name.lower()
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - name = value.lower() - if name in self._members: - self.set_value(self._members[name]) - else: - raise ValueError(f"Illegal value '{value}' for enum type " - f"'{self.datatype.__name__}'")
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value.name
-
[docs] def get_value(self) -> Enum: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: Enum) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - if value is not None and value not in self.allowed: - raise ValueError(f"Value '{value}' not allowed") - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value.name
- value: Enum = property(get_value, set_value, doc="Current option value")
- -
[docs]class FlagOption(Option[Flag]): - """Configuration option with flag value. - """ -
[docs] def __init__(self, name: str, flag_class: Flag, description: str, *, required: bool=False, - default: Flag=None, allowed: List=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - allowed: List of allowed Flag members. When not defined, all members of flag type are - allowed. - """ - self._value: Flag = None - #: List of allowed flag values. - self.allowed: Sequence = flag_class if allowed is None else allowed - self._members: Dict = {i.name.lower(): i for i in self.allowed} - super().__init__(name, flag_class, description, required, default)
- def _get_value_description(self) -> str: - return f"flag [{', '.join(x.name.lower() for x in self.allowed)}]\n" -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else self.get_as_str().lower()
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - result = self.datatype(0) - for name in (x.strip().lower() for x in value.split('|' if '|' in value else ',')): - if name in self._members: - result |= self._members[name] - else: - raise ValueError(f"Illegal value '{name}' for flag option '{self.name}'") - self.set_value(result)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - if self._value._name_ is not None: - return self._value.name - members, uncovered = _decompose(self.datatype, self._value) - if len(members) == 1 and members[0]._name_ is None: - return f'{members[0]._value_}' - return ' | '.join([str(m._name_ or m._value_) for m in members])
-
[docs] def get_value(self) -> Flag: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: Flag) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - if value is not None: - members, uncovered = _decompose(self.datatype, value.value) - if uncovered or [i for i in members if i.name is None or i.name.lower() not in self._members]: - raise ValueError(f"Illegal value '{value!s}' for flag option '{self.name}'") - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_uint64', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_uint64': - self.set_value(self.datatype(opt.as_uint64)) - else: - self.set_as_str(opt.as_string)
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_uint64 = self._value.value
- value: Flag = property(get_value, set_value, doc="Current option value")
- -
[docs]class UUIDOption(Option[UUID]): - """Configuration option with UUID value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: UUID=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: UUID = None - super().__init__(name, UUID, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else str(self._value)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = UUID(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return 'None' if self._value is None else self._value.hex
-
[docs] def get_value(self) -> UUID: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: UUID) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - oneof = opt.WhichOneof('kind') - if oneof not in ['as_bytes', 'as_string']: - raise TypeError(f"Wrong value type: {oneof[3:]}") - if oneof == 'as_bytes': - self.set_value(UUID(bytes=opt.as_bytes)) - else: - self.set_value(UUID(opt.as_string))
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_bytes = self._value.bytes
- value: UUID = property(get_value, set_value, doc="Current option value")
- -
[docs]class MIMEOption(Option[MIME]): - """Configuration option with MIME type specification value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: MIME=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: MIME = None - super().__init__(name, MIME, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else self._value
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = MIME(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return 'None' if self._value is None else self._value
-
[docs] def get_value(self) -> MIME: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: MIME) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: MIME = property(get_value, set_value, doc="Current option value")
- -
[docs]class ListOption(Option[List]): - """Configuration option with list of values. - - Important: - When option is read from `ConfigParser`, empty values are ignored. - """ -
[docs] def __init__(self, name: str, item_type: Union[Type, Sequence[Type]], description: str, - *, required: bool=False, default: List=None, separator: str=None): - """ - Arguments: - name: Option name. - item_type: Datatype of list items. It could be a type or sequence of types. - If multiple types are provided, each value in config file must - have format: `type_name:value_as_str`. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - separator: String that separates list item values when options value is read - from `ConfigParser`. It's possible to use a line break as separator. - If separator is `None` [default] and the value contains line breaks, - it uses the line break as separator, otherwise it uses comma as - separator. - """ - self._value: List = None - #: Datatypes of list items. If there is more than one type, each value in - #: config file must have format: `type_name:value_as_str`. - self.item_types: Sequence[Type] = (item_type, ) if isinstance(item_type, type) else item_type - #: String that separates list item values when options value is read from - #: `ConfigParser`. Default separator is None. It's possible to use a line break as - #: separator. If separator is `None` and the value contains line breaks, it uses - #: the line break as separator, otherwise it uses comma as separator. - self.separator: Optional[str] = separator - self._convertor: Convertor = get_convertor(item_type) if isinstance(item_type, type) else None - super().__init__(name, list, description, required, default)
- def _get_value_description(self) -> str: - return f"list [{', '.join(x.__name__ for x in self.item_types)}]\n" - def _check_value(self, value: List) -> None: - super()._check_value(value) - if value is not None: - i = 0 - for item in value: - if item.__class__ not in self.item_types: - raise ValueError(f"List item[{i}] has wrong type") - i += 1 - def _get_as_typed_str(self, value: Any) -> str: - result = convert_to_str(value) - if len(self.item_types) > 1: - result = f'{value.__class__.__name__}:{result}' - return result -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = [convert_to_str(i) for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - if sep == '\n': - x = '\n ' - return f"\n {x.join(result)}" - return f'{sep} '.join(result)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - new = [] - if value.strip(): - separator = ('\n' if '\n' in value else ',') if self.separator is None else self.separator - itype = self.item_types[0] - convertor = self._convertor - name_map = {} - if len(self.item_types) > 1: - name_map = {cls.__name__: cls for cls in self.item_types} - fullname_map = {f'{cls.__module__}.{cls.__name__}': cls for cls in self.item_types} - for item in (i for i in value.split(separator) if i.strip()): - if name_map: - itype_name, item = item.split(':', 1) - itype_name = itype_name.strip() - itype = fullname_map.get(itype_name) if '.' in itype_name else name_map.get(itype_name) - if itype is None: - raise ValueError(f"Item type '{itype_name}' not supported") - convertor = get_convertor(itype) - new.append(convertor.from_str(itype, item.strip())) - self._value = new
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - result = [convert_to_str(i) for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - return sep.join(result)
-
[docs] def get_value(self) -> List: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: List) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = None if value is None else list(value)
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - result = [self._get_as_typed_str(i) for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - proto.options[self.name].as_string = sep.join(result)
- value: List = property(get_value, set_value, doc="Current option value")
- -
[docs]class PyExprOption(Option[PyExpr]): - """String configuration option with Python expression value. - """ - def __init__(self, name: str, description: str, *, required: bool=False, default: PyExpr=None): - self._value: PyExpr = None - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - super().__init__(name, PyExpr, description, required, default) -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = self._value - if '\n' in result: - lines = [] - for line in result.splitlines(True): - if lines: - lines.append(' ' + line) - else: - lines.append(line) - result = ''.join(lines) - return result
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = PyExpr(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value
-
[docs] def get_value(self) -> PyExpr: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: PyExpr) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: PyExpr = property(get_value, set_value, doc="Current option value")
- -
[docs]class PyCodeOption(Option[PyCode]): - """String configuration option with Python code value. - - Important: - Python code must be properly indented, but ConfigParser multiline string values have - leading whitespace removed. To circumvent this, the `PyCodeOption` supports assignment - of text values where lines start with `|` character. This character is removed, along - with any number of subsequent whitespace characters that are between `|` and first - non-whitespace character on first line starting with `|`. - """ - def __init__(self, name: str, description: str, *, required: bool=False, default: PyCode=None): - self._value: PyCode = None - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - super().__init__(name, PyCode, description, required, default) -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = self._value - if '\n' in result: - lines = [] - for line in result.splitlines(True): - if lines: - lines.append(' | ' + line) - else: - lines.append(line) - result = ''.join(lines) - return result
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - value = unindent_verticals(value) - self._value = PyCode(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value
-
[docs] def get_value(self) -> PyCode: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: PyCode) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: PyCode = property(get_value, set_value, doc="Current option value")
- -
[docs]class PyCallableOption(Option[PyCallable]): - """String configuration option with Python callable value. - - Important: - Python code must be properly indented, but `ConfigParser` multiline string values have - leading whitespace removed. To circumvent this, the `PyCodeOption` supports assignment - of text values where lines start with `|` character. This character is removed, along - with any number of subsequent whitespace characters that are between `|` and first - non-whitespace character on first line starting with `|`. - """ - # pylint: disable=[W0621] -
[docs] def __init__(self, name: str, description: str, signature: Union[Signature, Callable], * , - required: bool=False, default: PyCallable=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - signature: Callable signature or callable. - required: True if option must have a value. - default: Default option value. - """ - self._value: PyCallable = None - #: Callable signature. - if not isinstance(signature, Signature): - signature = Signature.from_callable(PyCallable(signature)._callable_) - self.signature: Signature = signature - super().__init__(name, PyCallable, description, required=required, default=default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = self._value - if '\n' in result: - lines = [] - for line in result.splitlines(True): - if lines: - lines.append(' | ' + line) - else: - lines.append(line) - result = ''.join(lines) - return result
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - value = unindent_verticals(value) - self.set_value(PyCallable(value))
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return self._value
-
[docs] def get_value(self) -> PyCallable: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: PyCallable) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the callable has wrong signature. - """ - self._check_value(value) - if value is not None: - val_sig = signature(value._callable_) - if not _eq(val_sig.return_annotation, self.signature.return_annotation): - raise ValueError("Wrong callable return type") - if len(val_sig.parameters) != len(self.signature.parameters): - raise ValueError("Wrong number of parameters") - for par in self.signature.parameters.values(): - val_par: Parameter = val_sig.parameters[cast(Signature, par).name] - if not _eq(val_par.annotation, cast(Signature, par).annotation): - raise ValueError(f"Wrong type, parameter '{val_par.name}'") - if not _eq(val_par.default, cast(Signature, par).default): - raise ValueError(f"Wrong default, parameter '{val_par.name}'") - if not _eq(val_par.kind, cast(Signature, par).kind): - raise ValueError(f"Wrong parameter kind, parameter '{val_par.name}'") - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value
- value: PyCallable = property(get_value, set_value, doc="Current option value")
- -
[docs]class ConfigOption(Option[str]): - """Configuration option with `Config` value. - - Important: - This option is intended for sub-configs that should have *configurable* name (i.e. the - section name that holds sub-config values). To create sub-configs with fixed section - names, simply assign them to instance attributes of `Config` instance that owns them - (preferably in constructor). - - While the `value` attribute for this option is an instance of any class inherited from - `Config`, in other ways it behaves like `StrOption` that loads/saves only name of its - `Config` value (i.e. the section name). The actual I/O for sub-config's options is - delegated to `Config` instance that owns this option. - - The "empty" value for this option is not `None` (because the `Config` instance always - exists), but an empty string for `Config.name` attribute. - """ -
[docs] def __init__(self, name: str, description: str, config: Config, *, required: bool=False, - default: str=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - config: Option's value. - required: True if option must have a value. - default: Default `Config.name` value. - """ - assert isinstance(config, Config) - self._value: Config = config - super().__init__(name, str, description, required, default)
- def _get_value_description(self) -> str: - return "configuration section name\n" -
[docs] def validate(self) -> None: - """Validates option state. - - Raises: - Error: When required option does not have a value. - """ - if self.required and self.get_value().name == '': - raise Error(f"Missing value for required option '{self.name}'")
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Note: - This method calls `~Config.clear(to_default)`. - - Arguments: - to_default: If True, sets the `Config.name` to default value, else to empty string. - """ - self._value.clear(to_default=to_default) - self._value.name = self.default if to_default else ''
-
[docs] def get_formatted(self) -> str: - """Return value formatted for use in config file. - - The string contains section name that will be used to store the `Config` values. - """ - return self._value.name
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New `Config.name` value. - - Important: - Because the actual value is a `Config` instance, the string must contain the - `Config.name` value (which is the section name used to store `Config` options). - Beware that multiple Config instances with the same (section) name may cause - collision when configuration is written to protobuf message or configuration file. - """ - self._value.name = value
-
[docs] def get_as_str(self) -> str: - """Return value as string. - - Important: - Because the actual value is a `Config` instance, the returned string is the section - name used to store `Config` options. - """ - return self._value.name
-
[docs] def get_value(self) -> Config: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: str) -> None: - """Set new option value. - - This option type does not support direct assignment of `Config` value. Because this method - is also used to assign default value (which is a `Config.name`), it accepts None or string - argument that is interpreted as new Config name. `None` value is translated to empty string. - - Arguments: - value: New `Config` name. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When None or empty string is passed and option value is required. - """ - if value is None: - value = '' - if value == '' and self.required: - raise ValueError(f"Value is required for option '{self.name}'.") - self._value.name = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self._value.name
- value: Config = property(get_value, set_value, doc="Current option value")
- -
[docs]class ConfigListOption(Option[List]): - """Configuration option with list of `Config` values. - - Important: - This option is intended for configurable set of sub-configs of fixed type. - - While the `value` attribute for this option is a list of instances of single class - inherited from `Config`, in other ways it behaves like `ListOption` with `str` items - that loads/saves only names of its `Config` items (i.e. the section names). The actual - I/O for sub-config options is delegated to `Config` instance that owns this option. - - Important: - When option is read from `ConfigParser`, empty values are ignored. - """ -
[docs] def __init__(self, name: str, description: str, item_type: Type[Config], *, - required: bool=False, separator: str=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - item_type: Datatype of list items. Must be subclass of `Config`. - required: True if option must have a value. - separator: String that separates values when options value is read from `ConfigParser`. - It's possible to use a line break as separator. - If separator is `None` [default] and the value contains line breaks, it uses - the line break as separator, otherwise it uses comma as separator. - """ - assert issubclass(item_type, Config) - self._value: List = [] - #: Datatype of list items. - self.item_type: Type[Config] = item_type - #: String that separates values when options value is read from `ConfigParser`. - #: Default separator is None. It's possible to use a line break as separator. - #: If separator is `None` and the value contains line breaks, it uses the line - #: break as separator, otherwise it uses comma as separator. - self.separator: Optional[str] = separator - super().__init__(name, list, description, required, [])
- def _get_value_description(self) -> str: - return "list of configuration section names\n" - def _check_value(self, value: List) -> None: - super()._check_value(value) - if value is not None: - i = 0 - for item in value: - if item.__class__ is not self.item_type: - raise ValueError(f"List item[{i}] has wrong type") - i += 1 -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value.clear()
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = [i.name for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - if sep == '\n': - x = '\n ' - return f"\n {x.join(result)}" - return f'{sep} '.join(result)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - new = [] - if value.strip(): - separator = ('\n' if '\n' in value else ',') if self.separator is None else self.separator - for item in (i for i in value.split(separator) if i.strip()): - new.append(self.item_type(item.strip())) - self._value = new
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - result = [i.name for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - return sep.join(result)
-
[docs] def get_value(self) -> List: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: List) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - if value is None: - self.clear() - else: - self._value = list(value)
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - result = [i.name for i in self._value] - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - proto.options[self.name].as_string = sep.join(result)
- value: List = property(get_value, set_value, doc="Current option value")
- -
[docs]class DataclassOption(Option[Any]): - """Configuration option with a dataclass value. - - The `ConfigParser` format for this option is a list of values, where each list items - defines value for dataclass field in `field_name:value_as_str` format. The configuration - must contain values for all fields for the dataclass that does not have default value. - - Important: - This option uses type annotation for dataclass to determine the actual data type for - conversion from string. It means that: - - 1. If type annotation contains "typing" types, it's necessary to specify "real" types - for all dataclass fields using the `fields` argument. - 2. All used data types must have string convertors registered in `strconv` module. - - Important: - When option is read from `ConfigParser`, empty values are ignored. - """ -
[docs] def __init__(self, name: str, dataclass: Type, description: str, *, required: bool=False, - default: Any=None, separator: str=None, fields: Dict[str, Type]=None): - """ - Arguments: - name: Option name. - dataclass: Dataclass type. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - separator: String that separates dataclass field values when options value is read - from `ConfigParser`. It's possible to use a line break as separator. - If separator is `None` [default] and the value contains line breaks, it - uses the line break as separator, otherwise it uses comma as separator. - fields: Dictionary that maps dataclass field names to data types. - """ - assert hasattr(dataclass, '__dataclass_fields__') - self._fields: Dict[str, Type] = get_type_hints(dataclass) if fields is None else fields - if __debug__: - for ftype in self._fields.values(): - assert get_convertor(ftype) is not None - self._value: Any = None - #: Dataclass type. - self.dataclass: Type = dataclass - #: String that separates dataclass field values when options value is read from - #: `ConfigParser`. Default separator is None. It's possible to use a line break - #: as separator. If separator is `None` and the value contains line breaks, it - #: uses the line break as separator, otherwise it uses comma as separator. - self.separator: Optional[str] = separator - super().__init__(name, dataclass, description, required, default)
- def _get_value_description(self) -> str: - return "list of values, where each list item defines value for a dataclass field.\n" \ - "Item format: field_name:value_as_str\n" - def _get_str_fields(self) -> List[str]: - result = [] - if self._value is not None: - for fname in self._fields: - result.append(f'{fname}:{convert_to_str(getattr(self._value, fname))}') - return result -
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - if self._value is None: - return '<UNDEFINED>' - result = self._get_str_fields() - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - if sep == '\n': - x = '\n ' - return f"\n {x.join(result)}" - return f'{sep} '.join(result)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - new = {} - if value.strip(): - separator = ('\n' if '\n' in value else ',') if self.separator is None else self.separator - for item in (i for i in value.split(separator) if i.strip()): - try: - field_name, field_value = item.split(':', 1) - except Exception as exc: - raise ValueError(f"Illegal value '{value}' for option '{self.name}'") from exc - field_name = field_name.strip() - ftype = self._fields.get(field_name) - if ftype is None: - raise ValueError(f"Unknown data field '{field_name}' for option '{self.name}'") - convertor = get_convertor(ftype) - new[field_name] = convertor.from_str(ftype, field_value.strip()) - try: - new_val = self.dataclass(**new) - except Exception as exc: - raise ValueError(f"Illegal value '{value}' for option '{self.name}'") from exc - self._value = new_val
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - result = self._get_str_fields() - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - return sep.join(result)
-
[docs] def get_value(self) -> Any: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: Any) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - result = self._get_str_fields() - sep = self.separator - if sep is None: - sep = '\n' if sum(len(i) for i in result) > 80 else ',' - proto.options[self.name].as_string = sep.join(result)
- value: Any = property(get_value, set_value, doc="Current option value")
- -
[docs]class PathOption(Option[str]): - """Configuration option with `pathlib.Path` value. - """ -
[docs] def __init__(self, name: str, description: str, *, required: bool=False, default: Path=None): - """ - Arguments: - name: Option name. - description: Option description. Can span multiple lines. - required: True if option must have a value. - default: Default option value. - """ - self._value: Path = None - super().__init__(name, Path, description, required, default)
-
[docs] def clear(self, *, to_default: bool=True) -> None: - """Clears the option value. - - Arguments: - to_default: If True, sets the option value to default value, else to None. - """ - self._value = self.default if to_default else None
-
[docs] def get_formatted(self) -> str: - """Returns value formatted for use in config file. - """ - return '<UNDEFINED>' if self._value is None else str(self._value)
-
[docs] def set_as_str(self, value: str) -> None: - """Set new option value from string. - - Arguments: - value: New option value. - - Raises: - ValueError: When the argument is not a valid option value. - """ - self._value = Path(value)
-
[docs] def get_as_str(self) -> str: - """Returns value as string. - """ - return str(self._value)
-
[docs] def get_value(self) -> Path: - """Returns current option value. - """ - return self._value
-
[docs] def set_value(self, value: Path) -> None: - """Set new option value. - - Arguments: - value: New option value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - self._check_value(value) - self._value = value
-
[docs] def load_proto(self, proto: ConfigProto) -> None: - """Deserialize value from `.ConfigProto` message. - - Arguments: - proto: Protobuf message that may contains options value. - - Raises: - TypeError: When the new value is of the wrong type. - ValueError: When the argument is not a valid option value. - """ - if self.name in proto.options: - opt = proto.options[self.name] - if opt.HasField('as_string'): - self.set_as_str(opt.as_string) - else: - raise TypeError(f"Wrong value type: {opt.WhichOneof('kind')[3:]}")
-
[docs] def save_proto(self, proto: ConfigProto) -> None: - """Serialize value into `.ConfigProto` message. - - Arguments: - proto: Protobuf message where option value should be stored. - """ - if self._value is not None: - proto.options[self.name].as_string = self.get_as_str()
- value: Path = property(get_value, set_value, doc="Current option value")
-
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2023, The Firebird Project.
- Created using Sphinx 5.3.0.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/hooks.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/hooks.html deleted file mode 100644 index 44036ab..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/hooks.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - - firebird.base.hooks — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.hooks

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/hooks.py
-# DESCRIPTION:    Hook manager
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""Firebird Base - Hook manager
-
-This module provides a general framework for callbacks and "hookable" events.
-"""
-
-from __future__ import annotations
-from typing import Union, Any, Type, Dict, List, Set, Callable, cast
-from enum import Enum, Flag, auto
-from weakref import WeakKeyDictionary
-from dataclasses import dataclass, field
-from .types import Distinct, ANY, Singleton
-from .collections import Registry
-
-@dataclass(order=True, frozen=True)
-class Hook(Distinct):
-    """Hook registration info.
-    """
-    #: Event identification
-    event: Any
-    #: Hookable class
-    cls: type = ANY
-    #: Instance of registered hookable class
-    instance: Any = ANY
-    #: List of callbacks
-    callbacks: List[Callable] = field(default_factory=list)
-    def get_key(self) -> Any:
-        """Returns hook key.
-        """
-        return (self.event, self.cls, self.instance)
-
-class HookFlag(Flag):
-    """Internally used flags.
-    """
-    NONE = 0
-    INSTANCE = auto()
-    CLASS = auto()
-    NAME = auto()
-    ANY_EVENT = auto()
-
-
[docs]class HookManager(Singleton): - """Hook manager. - """ - def __init__(self): - self.obj_map: WeakKeyDictionary = WeakKeyDictionary() - self.hookables: Dict[Type, Set[Any]] = {} - self.hooks: Registry = Registry() - self.flags: HookFlag = HookFlag.NONE - def _update_flags(self, event: Any, cls: Any, obj: Any) -> None: - if event is ANY: - self.flags |= HookFlag.ANY_EVENT - if cls is not ANY: - self.flags |= HookFlag.CLASS - if obj is not ANY: - if isinstance(obj, str): - self.flags |= HookFlag.NAME - else: - self.flags |= HookFlag.INSTANCE -
[docs] def register_class(self, cls: Type, events: Union[Type[Enum], Set]=None) -> None: - """Register hookable class. - - Arguments: - cls: Class that supports hooks. - events: Supported events. - - Events could be specified using an `~enum.Enum` type or set of event identificators. - When Enum is used (recommended), all enum values are registered as hookable events. - """ - if isinstance(events, type) and issubclass(events, Enum): - events = set(events.__members__.values()) - self.hookables[cls] = events
-
[docs] def register_name(self, instance: Any, name: str) -> None: - """Associate name with hookable instance. - - Arguments: - instance: Instance of registered hookable class. - name: Unique name assigned to instance. - """ - if not isinstance(instance, tuple(self.hookables.keys())): - raise TypeError("The instance is not of hookable type") - self.obj_map[instance] = name
-
[docs] def add_hook(self, event: Any, source: Any, callback: Callable) -> None: - """Add new hook. - - Arguments: - event: Event identificator. - source: Hookable class or instance, or instance name. - callback: Callback function. - - Important: - The signature of `callback` must conform to requirements for particular hookable event. - - Raises: - TypeError: When `subject` is not registered as hookable. - ValueError: When `event` is not supported by specified `subject`. - """ - cls = obj = ANY - if isinstance(source, type): - if source in self.hookables: - cls = source - if event is not ANY: - found = False - for cls_ in (c for c in self.hookables if issubclass(cls, c)): - if event in self.hookables[cls_]: - found = True - break - if not found: - raise ValueError(f"Event '{event}' is not supported by '{cls.__name__}'") - else: - raise TypeError("The type is not registered as hookable") - elif isinstance(source, tuple(self.hookables)): - obj = source - if event is not ANY: - found = False - for cls_ in (c for c in self.hookables if isinstance(obj, c)): - if event in self.hookables[cls_]: - found = True - break - if not found: - raise ValueError(f"Event '{event}' is not supported by '{obj.__class__.__name__}'") - elif isinstance(source, str): - obj = source - else: - raise TypeError("Subject must be hookable class or instance, or name") - self._update_flags(event, cls, obj) - key = (event, cls, obj) - hook: Hook = self.hooks[key] if key in self.hooks else self.hooks.store(Hook(*key)) - hook.callbacks.append(callback)
-
[docs] def remove_hook(self, event: Any, source: Any, callback: Callable) -> None: - """Remove hook callback installed by `add_hook()`. - - Arguments: - event: Event identificator. - source: Hookable class or instance. - callback: Callback function. - - Important: - For successful removal, the argument values must be exactly the same as used in - `add_hook()` call. - - The method does nothing if described hook is not installed. - """ - cls = obj = ANY - if isinstance(source, type): - cls = source - else: - obj = source - key = (event, cls, obj) - hook: Hook = self.hooks.get(key) - if hook is not None: - hook.callbacks.remove(callback) - if not hook.callbacks: - self.hooks.remove(hook) - self.flags = HookFlag.NONE - for h in self.hooks: - self._update_flags(h.event, h.cls, h.instance)
-
[docs] def remove_all_hooks(self) -> None: - """Removes all installed hooks. - """ - self.hooks.clear() - self.flags = HookFlag.NONE
-
[docs] def reset(self) -> None: - """Removes all installed hooks and unregisters all hookable classes and instances. - """ - self.remove_all_hooks() - self.hookables.clear() - self.obj_map.clear()
-
[docs] def get_callbacks(self, event: Any, source: Any) -> List: - """Returns list of all callbacks installed for specified event and hookable subject. - - Arguments: - event: Event identificator. - source: Hookable class or instance, or name. - """ - result = [] - if isinstance(source, type): - if HookFlag.CLASS in self.flags: - if (hook := self.hooks.get((event, source, ANY))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.ANY_EVENT in self.flags and (hook := self.hooks.get((ANY, source, ANY))) is not None: - result.extend(cast(Hook, hook).callbacks) - elif isinstance(source, str): - if HookFlag.NAME in self.flags: - if (hook := self.hooks.get((event, ANY, source))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.ANY_EVENT in self.flags and (hook := self.hooks.get((ANY, ANY, source))) is not None: - result.extend(cast(Hook, hook).callbacks) - else: - if HookFlag.INSTANCE in self.flags: - if (hook := self.hooks.get((event, ANY, source))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.ANY_EVENT in self.flags and (hook := self.hooks.get((ANY, ANY, source))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.NAME in self.flags and (name := self.obj_map.get(source)) is not None: - if (hook := self.hooks.get((event, ANY, name))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.ANY_EVENT in self.flags and (hook := self.hooks.get((ANY, ANY, name))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.CLASS in self.flags: - for cls in (c for c in self.hookables if isinstance(source, c)): - if (hook := self.hooks.get((event, cls, ANY))) is not None: - result.extend(cast(Hook, hook).callbacks) - if HookFlag.ANY_EVENT in self.flags and (hook := self.hooks.get((ANY, cls, ANY))) is not None: - result.extend(cast(Hook, hook).callbacks) - return result
- -#: Hook manager -hook_manager: HookManager = HookManager() - -#: shortcut for `hook_manager.register_class()` -register_class = hook_manager.register_class -#: shortcut for `hook_manager.register_name()` -register_name = hook_manager.register_name -#: shortcut for `hook_manager.add_hook()` -add_hook = hook_manager.add_hook -#: shortcut for `hook_manager.get_callbacks()` -get_callbacks = hook_manager.get_callbacks -
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/logging.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/logging.html deleted file mode 100644 index 5b15cac..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/logging.html +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - - firebird.base.logging — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.logging

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/logging.py
-# DESCRIPTION:    Context-based logging
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""firebird-base - Context-based logging
-
-"""
-
-from __future__ import annotations
-from typing import Any, Dict, Tuple, Union, Hashable
-from enum import IntEnum, Flag, auto
-from collections.abc import Mapping
-from dataclasses import dataclass
-from logging import Logger, LoggerAdapter, getLogger, lastResort, Formatter
-from .types import UNDEFINED, DEFAULT, ANY, ALL, Distinct, CachedDistinct, Sentinel
-from .collections import Registry
-
-
[docs]class LogLevel(IntEnum): - """Shadow enumeration for logging levels. - """ - NOTSET = 0 - DEBUG = 10 - INFO = 20 - WARNING = 30 - ERROR = 40 - CRITICAL = 50 - FATAL = CRITICAL - WARN = WARNING
- -
[docs]class BindFlag(Flag): - """Internal flags used by `LoggingManager`. - """ - DIRECT = auto() - ANY_AGENT = auto() - ANY_CTX = auto() - ANY_ANY = auto()
- -
[docs]class FBLoggerAdapter(LoggerAdapter, CachedDistinct): - """`~logging.LoggerAdapter` that injects information about context, agent and topic - into `extra` and with **f-string** log message support. - """ -
[docs] def __init__(self, logger: Logger, agent: Any=UNDEFINED, context: Any=UNDEFINED, topic: str=''): - """ - Arguments: - logger: Adapted Logger instance. - agent: Agent for logger - context: Context for logger - topic: Topic of recorded information. - """ - #: Adapted Logger instance. - self.logger: Logger = logger - #: Agent for logger. - self.agent: Any = agent - #: Context for logger. - self.context: Any = context - #: Topic for logger. - self.topic: str = topic
-
[docs] @classmethod - def extract_key(cls, *args, **kwargs) -> Hashable: - """Returns instance key extracted from constructor arguments. - """ - return (args[1], args[2])
-
[docs] def get_key(self) -> Hashable: # pragma: no cover - """Returns instance key. - """ - return (self.topic, self.agent, self.context)
-
[docs] def process(self, msg, kwargs) -> Tuple[str, Dict]: - """Process the logging message and keyword arguments passed into - a logging call to insert contextual information. You can either - manipulate the message itself, the keyword args or both. Return - the message and kwargs modified (or not) to suit your needs. - """ - return msg, kwargs
-
[docs] def log(self, level, msg, *args, **kwargs): - """Delegate a log call to the underlying logger after processing. - - Interpolates the message as **f-string** using either `kwargs` or dict passed as - only one positional argument. If sole positional argument is not dictionary or - `args` has more than one item, adds `args` into namespace for interpolation. - - Moves 'context', 'agent' and 'topic' keyword arguments into `extra`. - - Strips out all keyword arguments not expected by `logging.Logger`. - """ - if self.isEnabledFor(level): - msg, kwargs = self.process(msg, kwargs) - if (args and len(args) == 1 and isinstance(args[0], Mapping) and args[0]): - ns = args[0] - else: - ns = kwargs - if args: - ns['args'] = args - msg = eval(f'f"""{msg}"""', globals(), ns) - args = () - if 'stacklevel' not in kwargs: - kwargs['stacklevel'] = 3 - kwargs.setdefault('extra', {}).update(topic=self.topic, agent=self.agent, - context=self.context) - self.logger.log(level, msg, *args, **{k: v for k, v in kwargs.items() - if k in ['exc_info', 'stack_info', - 'stacklevel', 'extra']})
- -@dataclass(order=True, frozen=True) -class BindInfo(Distinct): - """Information about Logger binding. - """ - topic: str - agent: str - context: str - logger: FBLoggerAdapter - def get_key(self) -> Any: - "Returns distinct key value = Tuple(topic, agent, context)." - return (self.topic, self.agent, self.context) - -
[docs]def get_logging_id(obj: Any) -> Any: - """Returns logging ID for object. - - Arguments: - obj: Any object - - Returns: - 1. `logging_id` attribute if `obj` does have it, or.. - 2. `__qualname__` attribute if `obj` does have it, or.. - 3. `str(obj)` - """ - return getattr(obj, 'logging_id', getattr(obj, '__qualname__', str(obj)))
- -
[docs]class LoggingIdMixin: - """Mixin class that adds `logging_id` property and `__str__` that returns `logging_id`. - """ - def __str__(self): - return self.logging_id - @property - def logging_id(self) -> str: - """Returns `_logging_id_` attribute if defined, else returns qualified class name. - """ - return getattr(self, '_logging_id_', self.__class__.__qualname__)
- -
[docs]class LoggingManager: - """Logger manager. - """ - def __init__(self): - self.loggers: Registry = Registry() - self.topics: Dict[str, int] = {} - self.bindings: BindFlag = BindFlag(0) - def _update_bindings(self, agent: Any, context: Any) -> None: - if agent is ANY: - self.bindings |= BindFlag.ANY_AGENT - if context is ANY: - self.bindings |= BindFlag.ANY_CTX - if (agent is ANY) and (context is ANY): - self.bindings |= BindFlag.ANY_ANY - if (agent is not ANY) and (context is not ANY): - self.bindings |= BindFlag.DIRECT - def _update_topics(self, topic: str) -> None: - if topic in self.topics: - self.topics[topic] += 1 - else: - self.topics[topic] = 1 -
[docs] def bind_logger(self, agent: Any, context: Any, logger: Union[str, Logger], topic: str='') -> None: - """Bind agent and context to specific logger. - - Arguments: - agent: Agent identification - context: Context identification - logger: Loger (instance or name) - topic: Topic of recorded information - - The identification of agent and context could be: - - 1. String - 2. Object instance. Uses `get_logging_id()` to retrieve its logging ID. - 3. Sentinel. The ANY sentinel matches any particular agent or context. You can - use sentinel `.UNDEFINED` to register a logger for cases when agent or - context are not specified in logger lookup. - - Important: - You SHOULD NOT use sentinel `.ALL` for `agent` or `context` identification! This - sentinel is used by `.unbind()`, so bindings that use ALL could not be removed - by `.unbind()`. - - """ - if isinstance(logger, str): - logger = getLogger(logger) - if not isinstance(agent, (str, Sentinel)): - agent = get_logging_id(agent) - if not isinstance(context, (str, Sentinel)): - context = get_logging_id(context) - if agent is not ANY and context is not ANY: - logger = FBLoggerAdapter(logger, agent, context) - self._update_bindings(agent, context) - self._update_topics(topic) - self.loggers.update(BindInfo(topic, agent, context, logger))
-
[docs] def unbind(self, agent: Any, context: Any, topic: str='') -> int: - """Drops logger bindings. - """ - if not isinstance(agent, (str, Sentinel)): - agent = get_logging_id(agent) - if not isinstance(context, (str, Sentinel)): - context = get_logging_id(context) - if topic in self.topics: - rm = [i for i in self.loggers - if i.topic == topic and ((i.agent == agent) or agent is ALL) - and ((i.context == context) or context is ALL)] - for item in rm: - self.loggers.remove(item) - # recalculate optimizations - self.topics.clear() - self.bindings = BindFlag(0) - for item in self.loggers: - self._update_bindings(item.agent, item.context) - self._update_topics(item.topic) - return len(rm) - return 0
-
[docs] def clear(self) -> None: - """Remove all logger bindings. - """ - self.loggers.clear() - self.topics.clear() - self.bindings = BindFlag(0)
-
[docs] def get_logger(self, agent: Any=UNDEFINED, context: Any=DEFAULT, topic: str='') -> FBLoggerAdapter: - """Return a logger for the specified agent and context combination. - - Arguments: - agent: Agent identification. - context: Context identification. - topic: Topic of recorded information. - - The identification of agent and context could be: - - 1. String - 2. Object instance. Uses `get_logging_id()` to retrieve its logging ID. - 3. Sentinel `.UNDEFINED` - 4. When `context` is sentinel `.DEFAULT`, uses `agent` attribute `log_context` - (if defined) or sentinel `.UNDEFINED` otherwise. - - The search for a suitable topic logger proceeds as follows: - - 1. Return logger registered for specified agent and context, or... - 2. Return logger registered for ANY agent and specified context, or... - 3. Return logger registered for specified agent and ANY context, or... - 4. Return logger registered for ANY agent and ANY context, or... - 5. Return the root logger. - """ - if context is DEFAULT: - context = getattr(agent, 'log_context', UNDEFINED) - if agent is not UNDEFINED and not isinstance(agent, str): - agent = get_logging_id(agent) - if context is not UNDEFINED and not isinstance(context, str): - context = get_logging_id(context) - result: BindInfo = None - if topic in self.topics: - if BindFlag.DIRECT in self.bindings and \ - (result := self.loggers.get((topic, agent, context))) is not None: - result = result.logger - elif BindFlag.ANY_AGENT in self.bindings and \ - (result := self.loggers.get((topic, ANY, context))) is not None: - result = result.logger - elif BindFlag.ANY_CTX in self.bindings and \ - (result := self.loggers.get((topic, agent, ANY))) is not None: - result = result.logger - elif BindFlag.ANY_ANY in self.bindings and \ - (result := self.loggers.get((topic, ANY, ANY))) is not None: - result = result.logger - else: - result = getLogger(topic) - else: - result = getLogger(topic) - return result if isinstance(result, FBLoggerAdapter) \ - else FBLoggerAdapter(result, agent, context, topic)
- -#: Logging Manager -logging_manager: LoggingManager = LoggingManager() - -#: shortcut for `logging_manager.bind_logger()` -bind_logger = logging_manager.bind_logger -#: shortcut for `logging_manager.get_logger()` -get_logger = logging_manager.get_logger - -# Install simple formatter for lastResort handler -if lastResort is not None and lastResort.formatter is None: - lastResort.setFormatter(Formatter('%(levelname)s: %(message)s')) - -
[docs]def install_null_logger(): - """Installs 'null' logger. - """ - log = getLogger('null') - log.propagate = False - log.disabled = True
-
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/protobuf.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/protobuf.html deleted file mode 100644 index a52556a..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/protobuf.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - firebird.base.protobuf — Firebird-base 1.6.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.protobuf

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/protobuf.py
-# DESCRIPTION:    Registry for Google Protocol Buffer messages and enums
-# CREATED:        27.12.2019
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2019 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________.
-
-"""Firebird Base - Registry for Google Protocol Buffer messages and enums
-"""
-
-from __future__ import annotations
-from typing import Dict, Any, Callable, cast
-from dataclasses import dataclass
-from importlib.metadata import entry_points
-from google.protobuf.message import Message as ProtoMessage
-from google.protobuf.descriptor import EnumDescriptor
-from google.protobuf.struct_pb2 import Struct as StructProto # pylint: disable=[E0611]
-from google.protobuf import json_format, struct_pb2, any_pb2, duration_pb2, empty_pb2, \
-     timestamp_pb2, field_mask_pb2
-from .types import Distinct
-from .collections import Registry
-
-#: Name of well-known EMPTY protobuf message (for use with `.create_message()`)
-PROTO_EMPTY = 'google.protobuf.Empty'
-#: Name of well-known ANY protobuf message (for use with `.create_message()`)
-PROTO_ANY = 'google.protobuf.Any'
-#: Name of well-known DURATION protobuf message (for use with `.create_message()`)
-PROTO_DURATION = 'google.protobuf.Duration'
-#: Name of well-known TIMESTAMP protobuf message (for use with `.create_message()`)
-PROTO_TIMESTAMP = 'google.protobuf.Timestamp'
-#: Name of well-known STRUCT protobuf message (for use with `.create_message()`)
-PROTO_STRUCT = 'google.protobuf.Struct'
-#: Name of well-known VALUE protobuf message (for use with `.create_message()`)
-PROTO_VALUE = 'google.protobuf.Value'
-#: Name of well-known LISTVALUE protobuf message (for use with `.create_message()`)
-PROTO_LISTVALUE = 'google.protobuf.ListValue'
-#: Name of well-known FIELDMASK protobuf message (for use with `.create_message()`)
-PROTO_FIELDMASK = 'google.protobuf.FieldMask'
-
-# Classes
-
[docs]@dataclass(eq=True, order=True, frozen=True) -class ProtoMessageType(Distinct): - """Google protobuf message type. - """ - name: str - constructor: Callable -
[docs] def get_key(self) -> Any: - """Returns `name`. - """ - return self.name
- -
[docs]@dataclass(eq=True, order=True, frozen=True) -class ProtoEnumType(Distinct): - """Google protobuf enum type - """ - descriptor: EnumDescriptor -
[docs] def get_key(self) -> Any: - """Returns `name`. - """ - return self.name
-
[docs] def __getattr__(self, name): - """Returns the value corresponding to the given enum name.""" - if name in self.descriptor.values_by_name: - return self.descriptor.values_by_name[name].number - raise AttributeError(f"Enum {self.name} has no value with name '{name}'")
-
[docs] def keys(self): - """Return a list of the string names in the enum. - - These are returned in the order they were defined in the .proto file. - """ - return [value_descriptor.name for value_descriptor in self.descriptor.values]
-
[docs] def values(self): - """Return a list of the integer values in the enum. - - These are returned in the order they were defined in the .proto file. - """ - return [value_descriptor.number for value_descriptor in self.descriptor.values]
-
[docs] def items(self): - """Return a list of the (name, value) pairs of the enum. - - These are returned in the order they were defined in the .proto file. - """ - return [(value_descriptor.name, value_descriptor.number) - for value_descriptor in self.descriptor.values]
-
[docs] def get_value_name(self, number: int) -> str: - """Returns a string containing the name of an enum value. - - Raises: - KeyError: If there is no value for specified name. - """ - if number in self.descriptor.values_by_number: - return self.descriptor.values_by_number[number].name - raise KeyError(f"Enum {self.name} has no name defined for value {number}")
- @property - def name(self) -> str: - """Full enum type name. - """ - return self.descriptor.full_name
- -_msgreg: Registry = Registry() -_enumreg: Registry = Registry() - -
[docs]def struct2dict(struct: StructProto) -> Dict: - """Unpacks `google.protobuf.Struct` message to Python dict value. - """ - return json_format.MessageToDict(struct)
- -
[docs]def dict2struct(value: Dict) -> StructProto: - """Returns dict packed into `google.protobuf.Struct` message. - """ - struct = StructProto() - struct.update(value) - return struct
- -
[docs]def create_message(name: str, serialized: bytes = None) -> ProtoMessage: - """Returns new protobuf message instance. - - Arguments: - name: Fully qualified protobuf message name. - serialized: Serialized message. - - Raises: - KeyError: When message type is not registered. - google.protobuf.message.DecodeError: When deserializations fails. - """ - if (msg := _msgreg.get(name)) is None: - raise KeyError(f"Unregistered protobuf message '{name}'") - result = cast(ProtoMessageType, msg).constructor() - if serialized is not None: - result.ParseFromString(serialized) - return result
- -def get_message_factory(name: str) -> Callable: - """Returns callable that creates new protobuf messages of specified name. - - Arguments: - name: Fully qualified protobuf message name. - - Raises: - KeyError: When message type is not registered. - """ - if (msg := _msgreg.get(name)) is None: - raise KeyError(f"Unregistered protobuf message '{name}'") - return cast(ProtoMessageType, msg).constructor - -
[docs]def is_msg_registered(name: str) -> bool: - """Returns True if specified `name` refers to registered protobuf message type. - """ - return name in _msgreg
- -
[docs]def is_enum_registered(name: str) -> bool: - """Returns True if specified `name` refers to registered protobuf enum type. - """ - return name in _enumreg
- -
[docs]def get_enum_type(name: str) -> ProtoEnumType: - """Returns wrapper instance for protobuf enum type with specified `name`. - - Raises: - KeyError: When enum type is not registered. - """ - if (e := _enumreg.get(name)) is None: - raise KeyError(f"Unregistered protobuf enum type '{name}'") - return e
- -
[docs]def get_enum_field_type(msg, field_name: str) -> str: - """Returns name of enum type for message enum field. - - Raises: - KeyError: When message does not have specified field. - """ - if (fdesc := msg.DESCRIPTOR.fields_by_name.get(field_name)) is None: - raise KeyError(f"Message does not have field '{field_name}'") - return fdesc.enum_type.full_name
- -
[docs]def get_enum_value_name(enum_type_name: str, value: int) -> str: - """Returns name for the enum value. - """ - return get_enum_type(enum_type_name).get_value_name(value)
- -
[docs]def register_decriptor(file_descriptor) -> None: - """Registers enums and messages defined by protobuf file DESCRIPTOR. - """ - for msg_desc in file_descriptor.message_types_by_name.values(): - if not msg_desc.full_name in _msgreg: - _msgreg.store(ProtoMessageType(msg_desc.full_name, msg_desc._concrete_class)) - for enum_desc in file_descriptor.enum_types_by_name.values(): - if not enum_desc.full_name in _enumreg: - _enumreg.store(ProtoEnumType(enum_desc))
- -
[docs]def load_registered(group: str) -> None: # pragma: no cover - """Load registered protobuf packages. - - Protobuf packages must register the pb2-file DESCRIPTOR in `entry_points` section of - `setup.cfg` or `pyproject.toml` file. - - Arguments: - group: Entry-point group name. - - Example: - :: - - # setup.cfg: - - [options.entry_points] - firebird.base.protobuf = - firebird.base.lib_a = firebird.base.lib_a_pb2:DESCRIPTOR - firebird.base.lib_b = firebird.base.lib_b_pb2:DESCRIPTOR - firebird.base.lib_c = firebird.base.lib_c_pb2:DESCRIPTOR - - # pyproject.toml - - [project.entry-points."firebird.base.protobuf"] - "firebird.base.lib_a" = "firebird.base.lib_a_pb2:DESCRIPTOR" - "firebird.base.lib_b" = "firebird.base.lib_b_pb2:DESCRIPTOR" - "firebird.base.lib_c" = "firebird.base.lib_c_pb2:DESCRIPTOR" - - # will be loaded with: - - load_registered('firebird.base.protobuf') - """ - for desc in (entry.load() for entry in entry_points().get(group, [])): - register_decriptor(desc)
- -for well_known in [any_pb2, struct_pb2, duration_pb2, empty_pb2, timestamp_pb2, field_mask_pb2]: - register_decriptor(well_known.DESCRIPTOR) -del any_pb2, struct_pb2, duration_pb2, empty_pb2, timestamp_pb2, field_mask_pb2 -
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2023, The Firebird Project.
- Created using Sphinx 5.3.0.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/signal.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/signal.html deleted file mode 100644 index 01ba552..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/signal.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - firebird.base.signal — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.signal

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/signal.py
-# DESCRIPTION:    Callback system based on Signals and Slots, and "Delphi events"
-# CREATED:        22.11.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2016 Dhruv Govil, PySignal 1.1.4, original code
-# fork source: https://github.com/dgovil/PySignal
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org), after fork
-# All Rights Reserved.
-#
-# Contributor(s): PySignal 1.1.4 contributors: John Hood, Jason Viloria, Adric Worley,
-#                 Alex Widener
-#                 Pavel Císař - fork and reduction & adaptation for firebird-base and Python 3.8
-#                 ______________________________________
-
-"""firebird-base - Callback system based on Signals and Slots, and "Delphi events"
-
-
-"""
-
-from __future__ import annotations
-from typing import Callable, List
-from inspect import Signature, ismethod
-from weakref import ref, WeakKeyDictionary
-from functools import partial
-
-
[docs]class Signal: - """The Signal is the core object that handles connection with slots and emission. - - Slots are callables that are called when signal is emitted (the return value is ignored). - They could be functions, instance or class methods, partials and lambda functions. - """ -
[docs] def __init__(self, signature: Signature): - """ - Arguments: - signature: Signature for slots. - - Important: - Only slots that match the signature could be connected to signal. The check is - performed only on parameters, and not on return value type (as signals does - not have/ignore return values). - - The match must be exact, including type annotations, parameter names, order, - parameter type etc. The sole exception to this rule are excess slot keyword - arguments with default values. - - Note: - Signal functions with signatures different from signal could be adapted using - `functools.partial`. However, you can "mask" only keyword arguments (without - default) and leading positional arguments (as any positional argument binded - by name will not mask-out parameter from signature introspection). - """ - self._sig: Signature = signature.replace(parameters=[p for p in signature.parameters.values() - if p.name != 'self'], - return_annotation=Signature.empty) - #: Toggle to block / unblock signal transmission - self.block: bool = False - self._slots: List[Callable] = [] - self._islots: WeakKeyDictionary = WeakKeyDictionary()
- def __call__(self, *args, **kwargs): - self.emit(*args, **kwargs) - def _kw_test(self, sig: Signature) -> bool: - p = sig.parameters - result = False - for k in set(p).difference(set(self._sig.parameters)): - result = True - if p[k].default is Signature.empty: - return False - return result -
[docs] def emit(self, *args, **kwargs) -> None: - """Calls all the connected slots with the provided args and kwargs unless block - is activated. - """ - if self.block: - return - for slot in self._slots: - if not slot: - continue - if isinstance(slot, partial): - slot(*args, **kwargs) - elif isinstance(slot, WeakKeyDictionary): - # For class methods, get the class object and call the method accordingly. - for obj, method in slot.items(): - method(obj, *args, **kwargs) - elif isinstance(slot, ref): - # If it's a weakref, call the ref to get the instance and then call the func - # Don't wrap in try/except so we don't risk masking exceptions from the actual func call - if (t_slot := slot()) is not None: - t_slot(*args, **kwargs) - else: - # Else call it in a standard way. Should be just lambdas at this point - slot(*args, **kwargs) - for obj, method in self._islots.items(): - method(obj, *args, **kwargs)
-
[docs] def connect(self, slot: Callable) -> None: - """Connects the signal to callable that will receive the signal when emitted. - - Arguments: - slot: Callable with signature that match the signature defined for signal. - - Raises: - ValueError: When callable signature does not match the signature of signal. - """ - if not callable(slot): - raise ValueError(f"Connection to non-callable '{slot.__class__.__name__}' object failed") - # Verify signatures - sig = Signature.from_callable(slot).replace(return_annotation=Signature.empty) - if str(sig) != str(self._sig): - # Check if the difference is only in keyword arguments with defaults. - if not self._kw_test(sig): - raise ValueError("Callable signature does not match the signal signature") - if isinstance(slot, partial) or slot.__name__ == '<lambda>': - # If it's a partial, a Signal or a lambda. - if slot not in self._slots: - self._slots.append(slot) - elif ismethod(slot): - # Check if it's an instance method and store it with the instance as the key - self._islots[slot.__self__] = slot.__func__ - else: - # If it's just a function then just store it as a weakref. - newSlotRef = ref(slot) - if newSlotRef not in self._slots: - self._slots.append(newSlotRef)
-
[docs] def disconnect(self, slot) -> None: - """Disconnects the slot from the signal. - """ - if not callable(slot): - return - - if ismethod(slot): - # If it's a method, then find it by its instance - self._islots.pop(slot.__self__, None) - elif isinstance(slot, partial) or slot.__name__ == '<lambda>': - # If it's a partial, a Signal or lambda, try to remove directly - try: - self._slots.remove(slot) - except ValueError: - pass - else: - # It's probably a function, so try to remove by weakref - try: - self._slots.remove(ref(slot)) - except ValueError: - pass
-
[docs] def clear(self) -> None: - """Clears the signal of all connected slots. - """ - self._slots.clear()
- - -
[docs]class signal: - """Decorator that defines signal as read-only property. The decorated function/method - is used to define the signature required for slots to successfuly register to signal, - and does not need to have a body as it's never executed. - - The usage is similar to builtin `property`, except that it does not support custom - setter and deleter. - """ - def __init__(self, fget, doc=None): - self._sig_ = Signature.from_callable(fget) - self._map = WeakKeyDictionary() - if doc is None and fget is not None: - doc = fget.__doc__ - self.__doc__ = doc - def __get__(self, obj, objtype): - if obj is None: - return self - if obj not in self._map: - self._map[obj] = Signal(self._sig_) - return self._map[obj] - def __set__(self, obj, val): - raise AttributeError("can't set signal") - def __delete__(self, obj): - raise AttributeError("can't delete signal")
- -
[docs]class _EventSocket: - """Internal EventSocket handler. - """ - def __init__(self, slot: Callable=None): - self._slot: Callable = None - self._weak = False - if slot is not None: - if isinstance(slot, partial) or slot.__name__ == '<lambda>': - self._slot = slot - self._weak = False - elif ismethod(slot): - self._slot = slot.__func__ - self._weak = ref(slot.__self__) - else: - self._slot = ref(slot) - self._weak = True - def __call__(self, *args, **kwargs): # pylint: disable=[R1710] - if self._slot is not None: - if isinstance(self._weak, ref): - if (obj := self._weak()): - return self._slot(obj, *args, **kwargs) - elif self._weak and (slot := self._slot()): - return slot(*args, **kwargs) - else: - return self._slot(*args, **kwargs) -
[docs] def is_set(self) -> bool: - """Returns True if slot is assigned to eventsocket. - """ - if isinstance(self._weak, ref): - return self._weak() is not None - if self._weak: - return self._slot() is not None - return self._slot is not None
- -
[docs]class eventsocket: - """The `eventsocket` is like read/write property that handles connection and call - delegation to single slot. It basically works like Delphi event. - - The Slot could be function, instance or class method, partial and lambda function. - - Important: - Only slot that match the signature could be connected to eventsocket. The check is - performed on parameters and return value type (as events may have return values). - - The match must be exact, including type annotations, parameter names, order, - parameter type etc. The sole exception to this rule are excess slot keyword - arguments with default values. - - Note: - Eventsocket functions with signatures different from event could be adapted - using `functools.partial`. However, you can "mask" only keyword arguments - (without default) and leading positional arguments (as any positional argument - binded by name will not mask-out parameter from signature introspection). - - To call the event, simply call the eventsocket property with required parameters. - To check whether slot is assigned to eventsocket, use `is_set()` bool function - defined on property. - """ - _empty = _EventSocket() - def __init__(self, fget, doc=None): - s = Signature.from_callable(fget) - # Remove 'self' from list of parameters - self._sig: Signature = s.replace(parameters=[v for k,v in s.parameters.items() if k.lower() != 'self']) - # Key: instance of class where this eventsocket instance is used to define a property - # Value: _EventSocket - self._map = WeakKeyDictionary() - if doc is None and fget is not None: - doc = fget.__doc__ - self.__doc__ = doc - def _kw_test(self, sig: Signature) -> bool: - set_p = set(sig.parameters) - set_t = set(self._sig.parameters) - for k in set_p.difference(set_t): - if sig.parameters[k].default is Signature.empty: - return False - for k in set_t.difference(set_p): - if self._sig.parameters[k].default is Signature.empty: - return False - return sig.return_annotation == self._sig.return_annotation - def __get__(self, obj, objtype): - if obj is None: - return self - return self._map.get(obj, eventsocket._empty) - def __set__(self, obj, value): - if value is None: - if obj in self._map: - del self._map[obj] - return - if not callable(value): - raise ValueError(f"Connection to non-callable '{value.__class__.__name__}' object failed") - # Verify signatures - sig = Signature.from_callable(value) - if str(sig) != str(self._sig): - # Check if the difference is only in keyword arguments with defaults. - if not self._kw_test(sig): - raise ValueError("Callable signature does not match the event signature") - self._map[obj] = _EventSocket(value) - def __delete__(self, obj): - raise AttributeError("can't delete eventsocket")
-
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/strconv.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/strconv.html deleted file mode 100644 index dd1e3e5..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/strconv.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - - - firebird.base.strconv — Firebird-base 1.4.2 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.strconv

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/strconv.py
-# DESCRIPTION:    Data conversion from/to string
-# CREATED:        4.6.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""firebird-base - Data conversion from/to string
-"""
-
-from __future__ import annotations
-from typing import Hashable, Callable, Any, Type, Union
-from dataclasses import dataclass
-from decimal import Decimal, DecimalException
-from enum import Enum, IntEnum, IntFlag
-from uuid import UUID
-from .types import Distinct, MIME, ZMQAddress
-from .collections import Registry
-
-#: Function that converts typed value to its string representation.
-TConvertToStr = Callable[[Any], str]
-#: Function that converts string representation of typed value to typed value.
-TConvertFromStr = Callable[[Type, str], Any]
-
-
[docs]@dataclass -class Convertor(Distinct): - """Data convertor registry entry. - """ - cls: Type - to_str: TConvertToStr - from_str: TConvertFromStr -
[docs] def get_key(self) -> Hashable: - """Returns instance key. - """ - return self.cls
- @property - def name(self) -> str: - """Type name. - """ - return self.cls.__name__ - @property - def full_name(self) -> str: - """Type name including source module. - """ - return f'{self.cls.__module__}.{self.cls.__name__}'
- -_convertors: Registry = Registry() -_classes = {} - -# Convertors - -#: Valid string literals for True value. -TRUE_STR = ['yes', 'true', 'on', 'y', '1'] -#: Valid string literals for False value. -FALSE_STR = ['no', 'false', 'off', 'n', '0'] - -
[docs]def any2str(value: Any) -> str: - """Converts value to string using `str(value)`. - """ - return str(value)
- -
[docs]def str2any(cls: Type, value: str) -> Any: - """Converts string to data type value using `type(value)`. - """ - return cls(value)
- -
[docs]def register_convertor(cls: Type, *, - to_str: TConvertToStr=any2str, - from_str: TConvertFromStr=str2any): - """Registers convertor function(s). - - Arguments: - cls: Class or class name - to_str: Function that converts `cls` value to `str` - from_str: Function that converts `str` to value of `cls` data type - """ - _convertors.store(Convertor(cls, to_str, from_str))
- -
[docs]def register_class(cls: Type) -> None: - """Registers class for name lookup. - - .. seealso:: `has_convertor()`, `get_convertor()` - - Raises: - TypeError: When class name is already registered. - """ - if cls.__name__ in _classes: - raise TypeError(f"Class '{cls.__name__}' already registered as '{_classes[cls.__name__]!r}'") - _classes[cls.__name__] = cls
- -def _get_convertor(cls: Union[Type, str]) -> Convertor: - if isinstance(cls, str): - cls = _classes.get(cls, cls) - if isinstance(cls, str): - conv = list(_convertors.filter(f"item.{'full_name' if '.' in cls else 'name'} == '{cls}'")) - conv = conv.pop(0) if conv else None - else: - if (conv := _convertors.get(cls)) is None: - for base in cls.__mro__: - conv = _convertors.get(base) - if conv is not None: - break - return conv - -
[docs]def has_convertor(cls: Union[Type, str]) -> bool: - """Returns True if class has a convertor. - - Arguments: - cls: Type or type name. The name could be simple class name, or full name that includes - the module name. - - Note: - When `cls` is a name: - - 1. If class name is NOT registered via `register_class()`, it's not possible to perform - lookup for bases classes. - 2. If simple class name is provided and multiple classes of the same name but from - different modules have registered convertors, the first one found is used. If you - want to avoid this situation, use full names. - """ - return _get_convertor(cls) is not None
- -
[docs]def update_convertor(cls: Union[Type, str], *, - to_str: TConvertToStr=None, - from_str: TConvertFromStr=None): - """Update convertor function(s). - - Arguments: - cls: Class or class name - to_str: Function that converts `cls` value to `str` - from_str: Function that converts `str` to value of `cls` data type - - Raises: - KeyError: If data type has not registered convertor. - """ - conv = get_convertor(cls) - if to_str: - conv.to_str = to_str - if from_str: - conv.from_str = from_str
- -
[docs]def convert_to_str(value: Any) -> str: - """Converts value to string using registered convertor. - - Arguments: - value: Value to be converted. - - If there is no convertor for value's class, uses MRO to locate alternative convertor. - - Raises: - TypeError: If there is no convertor for value's class or any from its bases classes. - """ - return get_convertor(value.__class__).to_str(value)
- - -
[docs]def convert_from_str(cls: Union[Type, str], value: str) -> Any: - """Converts value from string to data type using registered convertor. - - Arguments: - cls: Type or type name. The name could be simple class name, or full name that includes - the module name. - value: String value to be converted - - Note: - When `cls` is a type name: - - 1. If class name is NOT registered via `register_class()`, it's not possible to perform - lookup for bases classes. - 2. If simple class name is provided and multiple classes of the same name but from - different modules have registered convertors, the first one found is used. If you - want to avoid this situation, use full names. - - Raises: - TypeError: If there is no convertor for `cls` or any from its bases classes. - """ - return get_convertor(cls).from_str(cls, value)
- -
[docs]def get_convertor(cls: Union[Type, str]) -> Convertor: - """Returns Convertor for data type. - - Arguments: - cls: Type or type name. The name could be simple class name, or full name that includes - the module name. - - Note: - When `cls` is a type name: - - 1. If class name is NOT registered via `register_class()`, it's not possible to perform - lookup for bases classes. - 2. If simple class name is provided and multiple classes of the same name but from - different modules have registered convertors, the first one found is used. If you - want to avoid this situation, use full names. - - Raises: - TypeError: If there is no convertor for `cls` or any from its bases classes. - """ - if (conv := _get_convertor(cls)) is None: - raise TypeError(f"Type '{cls.__name__ if isinstance(cls, type) else cls}' has no Convertor") - return conv
- -def _register(): - """Internal function for registration of builtin converters.""" - - def bool2str(value: bool) -> str: - return TRUE_STR[0] if value else FALSE_STR[0] - def str2bool(type_: Type, value: str) -> bool: # pylint: disable=[W0613] - if (v := value.lower()) in TRUE_STR: - return True - if v not in FALSE_STR: - raise ValueError("Value is not a valid bool string constant") - return False - def str2decimal(type_: Type, value: str) -> Decimal: - try: - return type_(value) - except DecimalException as exc: - raise ValueError(f"could not convert string to {type_.__name__}: '{value}'") from exc - def enum2str(value: Enum) -> str: - "Converts any Enum/Flag value to string" - return value.name - def str2enum(cls: Type, value: str) -> Enum: - "Converts string to Enum/Flag value" - return {k.lower(): v for k, v in cls.__members__.items()}[value.lower()] - - register_convertor(str) - register_convertor(int) - register_convertor(float) - register_convertor(complex) - register_convertor(Decimal, from_str=str2decimal) - register_convertor(UUID) - register_convertor(MIME) - register_convertor(ZMQAddress) - register_convertor(bool, to_str=bool2str, from_str=str2bool) - register_convertor(Enum, to_str=enum2str, from_str=str2enum) - # We must register IntEnum and IntFlag because 'int' is before Enum in MRO - register_convertor(IntEnum, to_str=enum2str, from_str=str2enum) - register_convertor(IntFlag, to_str=enum2str, from_str=str2enum) - -_register() -del _register -
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2022, The Firebird Project.
- Created using Sphinx 5.2.3.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/trace.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/trace.html deleted file mode 100644 index bb7dfa0..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/trace.html +++ /dev/null @@ -1,655 +0,0 @@ - - - - - - - firebird.base.trace — Firebird-base 1.6.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.trace

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/trace.py
-# DESCRIPTION:    Trace/audit for class instances
-# CREATED:        5.6.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""firebird-base - Trace/audit for class instances
-"""
-
-from __future__ import annotations
-from typing import Any, Type, Hashable, List, Dict, Callable
-import os
-from inspect import signature, Signature, isfunction
-from dataclasses import dataclass, field
-from enum import IntFlag, auto
-from functools import wraps, partial
-from time import monotonic
-from decimal import Decimal
-from configparser import ConfigParser
-from .types import Error, Distinct, DEFAULT, UNLIMITED, load
-from .collections import Registry
-from .strconv import convert_from_str
-from .config import StrOption, IntOption, BoolOption, ListOption, FlagOption, EnumOption, \
-     ConfigListOption, Config
-from .logging import LogLevel, FBLoggerAdapter, get_logger
-
-
[docs]class TraceFlag(IntFlag): - """`LoggingManager` trace/audit flags. - """ - NONE = 0 - ACTIVE = auto() - BEFORE = auto() - AFTER = auto() - FAIL = auto()
- -@dataclass -class TracedItem(Distinct): - """Class method trace specification. - """ - method: str - decorator: Callable - args: List = field(default_factory=list) - kwargs: Dict = field(default_factory=dict) - def get_key(self) -> Hashable: - """Returns Distinct key for traced item [method].""" - return self.method - -@dataclass -class TracedClass(Distinct): - """Traced class registry entry. - """ - cls: Type - traced: Registry = field(default_factory=Registry) - def get_key(self) -> Hashable: - """Returns Distinct key for traced item [cls].""" - return self.cls - -_traced: Registry = Registry() - -class TracedMeta(type): - """Metaclass that instruments instances on creation. - """ - def __call__(cls: Type, *args, **kwargs): - return trace_object(super().__call__(*args, **kwargs), strict=True) - -
[docs]class TracedMixin(metaclass=TracedMeta): - """Mixin class that automatically registers descendants for trace and instruments - instances on creation. - """ - def __init_subclass__(cls: Type, /, **kwargs) -> None: - super().__init_subclass__(**kwargs) - trace_manager.register(cls)
- -
[docs]class traced: # pylint: disable=[R0902] - """Base decorator for logging of callables, suitable for trace/audit. - - It's not applied on decorated function/method if `FBASE_TRACE` environment variable is - set to False, or if `FBASE_TRACE` is not defined and `__debug__` is False (optimized - Python code). - - Both positional and keyword arguments of decorated callable are available by name for - f-string type message interpolation as `dict` passed to logger as positional argument. - """ -
[docs] def __init__(self, *, agent: Any=DEFAULT, context: Any=DEFAULT, topic: str='trace', - msg_before: str=DEFAULT, msg_after: str=DEFAULT, msg_failed: str=DEFAULT, - flags: TraceFlag=TraceFlag(0), level: LogLevel=LogLevel.DEBUG, - max_param_length: int=UNLIMITED, extra: Dict=None, - callback: Callable[[Any], bool]=None, has_result: bool=DEFAULT, - with_args: bool=True): - """ - Arguments: - agent: Agent identification - context: Context identification - topic: Trace/audit logging topic - msg_before: Trace/audit message logged before decorated function - msg_after: Trace/audit message logged after decorated function - msg_failed: Trace/audit message logged when decorated function raises an exception - flags: Trace flags override - level: Logging level for trace/audit messages - max_param_length: Max. length of parameters (longer will be trimmed) - extra: Extra data for `LogRecord` - callback: Callback function that gets the agent identification as argument, - and must return True/False indicating whether trace is allowed. - has_result: Indicator whether function has result value. If True, `_result_` - is available for interpolation in `msg_after`. The `DEFAULT` value means, - that value for this argument should be decided from function return value - annotation. - with_args: If True, function arguments are available for interpolation in - `msg_before`. - """ - #: Trace/audit message logged before decorated function - self.msg_before: str = msg_before - #: Trace/audit message logged after decorated function - self.msg_after: str = msg_after - #: Trace/audit message logged when decorated function raises an exception - self.msg_failed: str = msg_failed - #: Agent identification - self.agent: Any = agent - #: Context identification - self.context: Any = context - #: Trace/audit logging topic - self.topic: str = topic - #: Trace flags override - self.flags: TraceFlag = flags - #: Logging level for trace/audit messages - self.level: LogLevel = level - #: Max. length of parameters (longer will be trimmed) - self.max_len: int = max_param_length - #: Extra data for `LogRecord` - self.extra: Dict = extra - #: Callback function that gets the agent identification as argument, - #: and must return True/False indicating whether trace is allowed. - self.callback: Callable[[Any], bool] = self.__callback if callback is None else callback - #: Indicator whether function has result value. If True, `_result_` is available - #: for interpolation in `msg_after`. - self.has_result: bool = has_result - #: If True, function arguments are available for interpolation in `msg_before` - self.with_args: bool = with_args
- def __callback(self, agent: Any) -> bool: # pylint: disable=[W0613] - """Default callback, does nothing. - """ - return True -
[docs] def set_before_msg(self, fn: Callable, sig: Signature) -> None: - """Sets the DEFAULT before message f-string template. - """ - if self.with_args: - self.msg_before = f">>> {fn.__name__}({', '.join(f'{{{x}=}}' for x in sig.parameters if x != 'self')})" - else: - self.msg_before = f">>> {fn.__name__}"
-
[docs] def set_after_msg(self, fn: Callable, sig: Signature) -> None: # pylint: disable=[W0613] - """Sets the DEFAULT after message f-string template. - """ - self.msg_after = f"<<< {fn.__name__}[{{_etime_}}] Result: {{_result_}}" \ - if self.has_result else f"<<< {fn.__name__}[{{_etime_}}]"
-
[docs] def set_fail_msg(self, fn: Callable, sig: Signature) -> None: # pylint: disable=[W0613] - """Sets the DEFAULT fail message f-string template. - """ - self.msg_failed = f"<-- {fn.__name__}[{{_etime_}}] {{_exc_}}"
-
[docs] def log_before(self, logger: FBLoggerAdapter, params: Dict) -> None: - """Executed before decorated callable. - """ - logger.log(self.level, self.msg_before, params, stacklevel=2)
-
[docs] def log_after(self, logger: FBLoggerAdapter, params: Dict) -> None: - """Executed after decorated callable. - """ - logger.log(self.level, self.msg_after, params, stacklevel=2)
-
[docs] def log_failed(self, logger: FBLoggerAdapter, params: Dict) -> None: - """Executed when decorated callable raises an exception. - """ - logger.log(self.level, self.msg_failed, params, stacklevel=2)
- def __call__(self, fn: Callable): # pylint: disable=[R0915] - @wraps(fn) - def wrapper(*args, **kwargs): # pylint: disable=[R0912] - flags = trace_manager.flags | self.flags - if enabled := ((TraceFlag.ACTIVE in flags) and int(flags) > 1): # pylint: disable=[R1702] - params = {} - bound = sig.bind_partial(*args, **kwargs) - # If it's not a bound method, look for 'self' - log = get_logger(bound.arguments.get('self', 'function') if self.agent is None - else self.agent, self.context, self.topic) - if enabled := (log.isEnabledFor(self.level) and self.callback(self.agent)): - if self.with_args: - bound.apply_defaults() - params.update(bound.arguments) - if self.max_len is not UNLIMITED: - for k, v in params.items(): - s = str(v) - if (i := len(s)) > self.max_len: - params[k] = f'{s[:self.max_len]}..[{i - self.max_len}]' - if self.extra is not None: - params.update(self.extra) - params['_fname_'] = fn.__name__ - params['_result_'] = None - # - if TraceFlag.BEFORE in flags: - self.log_before(log, params) - result = None - start = monotonic() - try: - result = fn(*args, **kwargs) - except Exception as exc: - if enabled and TraceFlag.FAIL | TraceFlag.ACTIVE in flags: - e = str(Decimal(monotonic() - start)) - params['_etime_'] = e[:e.find('.')+6] - params['_exc_'] = f'{exc.__class__.__qualname__}: {exc}' - self.log_failed(log, params) - raise - else: - if enabled and TraceFlag.AFTER | TraceFlag.ACTIVE in flags: - e = str(Decimal(monotonic() - start)) - params['_etime_'] = e[:e.find('.')+6] - if self.has_result: - params['_result_'] = result - if self.max_len is not UNLIMITED: - s = str(result) - if (i := len(s)) > self.max_len: - params['_result_'] = f'{s[:self.max_len]}..[{i - self.max_len}]' - self.log_after(log, params) - return result - - if (trace := os.getenv('FBASE_TRACE')) is not None: - if not convert_from_str(bool, trace): - return fn - elif not __debug__: - return fn - if self.agent is DEFAULT: - self.agent = getattr(fn, '__self__', None) - sig = signature(fn) - if self.has_result is DEFAULT: - self.has_result = sig.return_annotation != 'None' - if self.msg_before is DEFAULT: - self.set_before_msg(fn, sig) - if self.msg_after is DEFAULT: - self.set_after_msg(fn, sig) - if self.msg_failed is DEFAULT: - self.set_fail_msg(fn, sig) - return wrapper
- - -
[docs]class BaseTraceConfig(Config): # pylint: disable=[R0902] - """Base configuration for trace. - """ - def __init__(self, name: str): - super().__init__(name) - #: Agent identification - self.agent: StrOption = \ - StrOption('agent', "Agent identification") - #: Context identification - self.context: StrOption = \ - StrOption('context', "Context identification") - #: Trace/audit logging topic - self.topic: StrOption = \ - StrOption('topic', "Trace/audit logging topic") - #: Trace/audit message logged before decorated function - self.msg_before: StrOption = \ - StrOption('msg_before', "Trace/audit message logged before decorated function") - #: Trace/audit message logged after decorated function - self.msg_after: StrOption = \ - StrOption('msg_after', "Trace/audit message logged after decorated function") - #: Trace/audit message logged when decorated function raises an exception - self.msg_failed: StrOption = \ - StrOption('msg_failed', "Trace/audit message logged when decorated function raises an exception") - #: Trace flags override - self.flags: FlagOption = \ - FlagOption('flags', TraceFlag, "Trace flags override") - #: Logging level for trace/audit messages - self.level: EnumOption = \ - EnumOption('level', LogLevel, "Logging level for trace/audit messages") - #: Max. length of parameters (longer will be trimmed) - self.max_param_length: IntOption = \ - IntOption('max_param_length', "Max. length of parameters (longer will be trimmed)") - #: Indicator whether function has result value - self.has_result: BoolOption = \ - BoolOption('has_result', "Indicator whether function has result value") - #: If True, function arguments are available for interpolation in `msg_before` - self.with_args: BoolOption = \ - BoolOption('with_args', - "If True, function arguments are available for interpolation in `msg_before`")
- -
[docs]class TracedMethodConfig(BaseTraceConfig): - """Configuration of traced Python method. - """ - def __init__(self, name: str): - super().__init__(name) - #: Class method name [required] - self.method: StrOption = \ - StrOption('method', "Class method name", required=True)
- -
[docs]class TracedClassConfig(BaseTraceConfig): - """Configuration of traced Python class. - """ - def __init__(self, name: str): - super().__init__(name) - #: Fully qualified class name [required] - self.source: StrOption = \ - StrOption('source', "Fully qualified class name", required=True) - #: Names of traced class methods - self.methods: ListOption = \ - ListOption('methods', str, "Names of traced class methods") - #: Configuration sections with extended config of traced class methods - self.special: ConfigListOption = \ - ConfigListOption('special', - "Configuration sections with extended config of traced class methods", - TracedMethodConfig) - #: Wherher configuration should be applied also to all registered descendant classes [default: True]. - self.apply_to_descendants: BoolOption = \ - BoolOption('apply_to_descendants', - "Configuration should be applied also to all registered descendant classes", - default=True)
- -
[docs]class TraceConfig(BaseTraceConfig): - """Trace manager configuration. - """ - def __init__(self, name: str): - super().__init__(name) - #: When True, unregistered classes are registered automatically [default: True]. - self.autoregister: BoolOption = \ - BoolOption('autoregister', - "When True, unregistered classes are registered automatically", - default=True) - #: Configuration sections with traced Python classes [required]. - self.classes: ConfigListOption = \ - ConfigListOption('classes', - "Configuration sections with traced Python classes", - TracedClassConfig, required=True)
- -
[docs]class TraceManager: - """Trace manager. - """ - def __init__(self): - #: Decorator that should be used for trace instrumentation (via `add_trace`), - #: default: `traced`. - self.decorator: Callable = traced - self._traced: Registry = Registry() - self._flags: TraceFlag = TraceFlag.NONE - self.trace_active = convert_from_str(bool, os.getenv('FBASE_TRACE', str(__debug__))) - if convert_from_str(bool, os.getenv('FBASE_TRACE_BEFORE', 'no')): # pragma: no cover - self.set_flag(TraceFlag.BEFORE) - if convert_from_str(bool, os.getenv('FBASE_TRACE_AFTER', 'no')): # pragma: no cover - self.set_flag(TraceFlag.AFTER) - if convert_from_str(bool, os.getenv('FBASE_TRACE_FAIL', 'yes')): - self.set_flag(TraceFlag.FAIL) -
[docs] def is_registered(self, cls: Type) -> bool: - """Return True if class is registered. - """ - return cls in self._traced
-
[docs] def clear(self) -> None: - """Removes all trace specifications. - """ - for cls in self._traced: - cls.traced.clear()
-
[docs] def register(self, cls: Type) -> None: - """Register class for trace. - - Arguments: - cls: Class to be registered. - - Does nothing if class is already registered. - """ - if cls not in self._traced: - self._traced.store(TracedClass(cls))
-
[docs] def add_trace(self, cls: Type, method: str, / , *args, **kwargs) -> None: - """Add/update trace specification for class method. - - Arguments: - cls: Registered traced class - method: Name of class method that should be instrumented for trace - args: Positional arguments for decorator - kwargs: Keyword arguments for decorator - """ - self._traced[cls].traced.update(TracedItem(method, self.decorator, args, kwargs))
-
[docs] def remove_trace(self, cls: Type, method: str) -> None: - """Remove trace specification for class method. - - Arguments: - cls: Registered traced class - method: Name of class method - """ - del self._traced[cls].traced[method]
-
[docs] def trace_object(self, obj: Any, *, strict: bool=False) -> Any: - """Instruments object's methods with decorator according to trace configuration. - - Arguments: - strict: Determines the response if the object class is not registered for trace. - Raises exception when True, or return the instance as is when False [default]. - - Only methods registered with `.add_trace()` are instrumented. - - Returns: - Decorated instance. - - Raises: - TypeError: When object class is not registered and `strict` is True. - """ - if (trace := os.getenv('FBASE_TRACE')) is not None: - if not convert_from_str(bool, trace): - return obj - elif not __debug__: - return obj - entry: TracedClass = self._traced.get(obj.__class__) - if entry is None: - if strict: - raise TypeError(f"Class '{obj.__class__.__name__}' not registered for trace!") - return obj - for item in entry.traced: - setattr(obj, item.method, item.decorator(*item.args, **item.kwargs)(getattr(obj, item.method))) - return obj
-
[docs] def load_config(self, config: ConfigParser, section: str='trace') -> None: - """Update trace from configuration. - - Arguments: - config: ConfigParser instance with trace configuration. - section: Name of ConfigParser section that should be used to get trace - configuration. - - Uses `.TraceConfig`, `.TracedClassConfig` and `.TracedMethodConfig` to process - the configuration. - - Note: - Does not `.clear()` existing trace specifications. - """ - def build_kwargs(from_cfg: BaseTraceConfig) -> Dict[str, Any]: - result = {} - for item in ['agent', 'context', 'topic', 'msg_before', 'msg_after', - 'msg_failed', 'flags', 'level', 'max_param_length', - 'has_result', 'with_args']: - if (value := getattr(from_cfg, item).value) is not None: - result[item] = value - return result - - def apply_on(cls): - if (items := cls_cfg.methods.value) is not None: - if (len(items) == 1) and (items[0] == '*'): - items = [i for i in dir(cls) if not i.startswith('_') and isfunction(getattr(cls, i))] - for item in items: - self.add_trace(cls, item, *[], **cls_kwargs) - if (items := cls_cfg.special.value) is not None: - for mcfg in items: - method = mcfg.method.value - kwargs = {} - kwargs.update(cls_kwargs) - kwargs.update(build_kwargs(mcfg)) - self.add_trace(cls, method, *[], **kwargs) - def with_name(name: str, obj: Any) -> bool: - return f'{obj.cls.__module__}.{obj.cls.__name__}' == name - - cfg = TraceConfig('trace') - cfg.load_config(config, section) - self.flags = cfg.flags.value - global_kwargs = build_kwargs(cfg) - for cls_cfg in cfg.classes.value: - cls_name = cls_cfg.source.value - cls_kwargs = {} - cls_kwargs.update(global_kwargs) - cls_kwargs.update(build_kwargs(cls_cfg)) - if (cls_desc := self._traced.find(partial(with_name, cls_name))) is None: - if cfg.autoregister.value: - cls = load(':'.join(cls_name.rsplit('.', 1))) - self.register(cls) - else: - raise Error(f"Class '{cls_name}' is not registered for trace.") - else: - cls = cls_desc.cls - apply_on(cls) - if cls_cfg.apply_to_descendants.value: - for cls_desc in self._traced.values(): - if (cls_desc.cls is not cls) and issubclass(cls_desc.cls, cls): - apply_on(cls_desc.cls)
-
[docs] def set_flag(self, flag: TraceFlag) -> None: - """Set flag specified by `flag` mask. - """ - self._flags |= flag
-
[docs] def clear_flag(self, flag: TraceFlag) -> None: - """Clear flag specified by `flag` mask. - """ - self._flags &= ~flag
- @property - def flags(self) -> TraceFlag: - """Trace flags. - """ - return self._flags - @flags.setter - def flags(self, value: TraceFlag) -> None: - self._flags = value if isinstance(value, TraceFlag) else TraceFlag(value) - @property - def trace_active(self) -> bool: - """True if trace is active. - """ - return TraceFlag.ACTIVE in self._flags - @trace_active.setter - def trace_active(self, value: bool) -> None: - if value: - self._flags |= TraceFlag.ACTIVE - else: - self._flags &= ~TraceFlag.ACTIVE
- -#: Trace manager -trace_manager: TraceManager = TraceManager() - -#: shortcut for `trace_manager.add_trace()` -add_trace = trace_manager.add_trace -#: shortcut for `trace_manager.remove_trace()` -remove_trace = trace_manager.remove_trace -#: shortcut for `trace_manager.trace_object()` -trace_object = trace_manager.trace_object -
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2023, The Firebird Project.
- Created using Sphinx 5.3.0.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/types.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/types.html deleted file mode 100644 index d840ea0..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/firebird/base/types.html +++ /dev/null @@ -1,601 +0,0 @@ - - - - - - - firebird.base.types — Firebird-base 1.6.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- -

Source code for firebird.base.types

-#coding:utf-8
-#
-# PROGRAM/MODULE: firebird-base
-# FILE:           firebird/base/types.py
-# DESCRIPTION:    Types
-# CREATED:        14.5.2020
-#
-# The contents of this file are subject to the MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (c) 2020 Firebird Project (www.firebirdsql.org)
-# All Rights Reserved.
-#
-# Contributor(s): Pavel Císař (original code)
-#                 ______________________________________
-
-"""Firebird Base - Types
-"""
-
-from __future__ import annotations
-from typing import Any, Dict, Hashable, Callable, AnyStr, cast, Type
-from abc import ABC, ABCMeta, abstractmethod
-import sys
-from importlib import import_module
-from enum import Enum, IntEnum
-from weakref import WeakValueDictionary
-
-# Exceptions
-
-
[docs]class Error(Exception): - """Exception that is intended to be used as a base class of all **application-related** - errors. The important difference from `Exception` class is that `Error` accepts keyword - arguments, that are stored into instance attributes with the same name. - - Important: - Attribute lookup on this class never fails, as all attributes that are not actually - set, have `None` value. - - Example:: - - try: - if condition: - raise Error("Error message", err_code=1) - else: - raise Error("Unknown error") - except Error as e: - if e.err_code is None: - ... - elif e.err_code == 1: - ... - - Note: - Warnings are not considered errors and thus should not use this class as base. - """ - def __init__(self, *args, **kwargs): - super().__init__(*args) - for name, value in kwargs.items(): - setattr(self, name, value) - def __getattr__(self, name): - return None
- -# Singletons - -_singletons_ = {} - -
[docs]class SingletonMeta(type): - """Metaclass for `Singleton` classes. - - Manages internal cache of class instances. If instance for a class is in cache, it's - returned without calling the constructor, otherwise the instance is created normally - and stored in cache for later use. - """ - def __call__(cls: Singleton, *args, **kwargs): - name = f"{cls.__module__}.{cls.__qualname__}" - obj = _singletons_.get(name) - if obj is None: - obj = super().__call__(*args, **kwargs) - _singletons_[name] = obj - return obj
- -
[docs]class Singleton(metaclass=SingletonMeta): - """Base class for singletons. - - Important: - If you create a descendant class that uses constructor arguments, these arguments - are meaningful ONLY on first call, because all subsequent calls simply return - an instance stored in cache without calling the constructor. - """
- -# Sentinels - -
[docs]class SentinelMeta(type): - """Metaclass for `Sentinel`. - """ - def __call__(cls: Sentinel, *args, **kwargs): - name = args[0].upper() - obj = cls.instances.get(name) - if obj is None: - obj = super().__call__(*args, **kwargs) - cls.instances[name] = obj - return obj
- -
[docs]class Sentinel(metaclass=SentinelMeta): - """Simple sentinel object. - - Important: - All sentinels have name, that is **always in capital letters**. Sentinels with - the same name are singletons. - """ - #: Class attribute with defined sentinels. There is no need to access or manipulate it. - instances = {} -
[docs] def __init__(self, name: str): - """ - Arguments: - name: Sentinel name. - """ - #: Sentinel name. - self.name = name.upper()
-
[docs] def __str__(self): - """Returns name. - """ - return self.name
-
[docs] def __repr__(self): - """Returns Sentinel('name'). - """ - return f"Sentinel('{self.name}')"
- -# Useful sentinel objects - -#: Sentinel that denotes default value -DEFAULT: Sentinel = Sentinel('DEFAULT') -#: Sentinel that denotes infinity value -INFINITY: Sentinel = Sentinel('INFINITY') -#: Sentinel that denotes unlimited value -UNLIMITED: Sentinel = Sentinel('UNLIMITED') -#: Sentinel that denotes unknown value -UNKNOWN: Sentinel = Sentinel('UNKNOWN') -#: Sentinel that denotes a condition when value was not found -NOT_FOUND: Sentinel = Sentinel('NOT_FOUND') -#: Sentinel that denotes explicitly undefined value -UNDEFINED: Sentinel = Sentinel('UNDEFINED') -#: Sentinel that denotes any value -ANY: Sentinel = Sentinel('ANY') -#: Sentinel that denotes all possible values -ALL: Sentinel = Sentinel('ALL') -#: Sentinel that denotes suspend request (in message queue) -SUSPEND: Sentinel = Sentinel('SUSPEND') -#: Sentinel that denotes resume request (in message queue) -RESUME: Sentinel = Sentinel('RESUME') -#: Sentinel that denotes stop request (in message queue) -STOP: Sentinel = Sentinel('STOP') - -# Distinct objects -
[docs]class Distinct(ABC): - """Abstract base class for classes (incl. dataclasses) with distinct instances. - """ -
[docs] @abstractmethod - def get_key(self) -> Hashable: - """Returns instance key. - - Important: - The key is used for instance hash computation that by default uses the `hash` - function. If the key is not suitable argument for `hash`, you must provide your - own `__hash__` implementation as well! - """
- __hash__ = lambda self: hash(self.get_key()) # pylint: disable=[C3001]
- -
[docs]class CachedDistinctMeta(ABCMeta): - """Metaclass for CachedDistinct. - """ - def __call__(cls: CachedDistinct, *args, **kwargs): - key = cls.extract_key(*args, **kwargs) - obj = cls._instances_.get(key) - if obj is None: - obj = super().__call__(*args, **kwargs) - cls._instances_[key] = obj - return obj
- -
[docs]class CachedDistinct(Distinct, metaclass=CachedDistinctMeta): - """Abstract `Distinct` descendant that caches instances. - - All created instances are cached in `~weakref.WeakValueDictionary`. - """ - def __init_subclass__(cls: Type, /, **kwargs) -> None: - super().__init_subclass__(**kwargs) - setattr(cls, '_instances_', WeakValueDictionary()) -
[docs] @classmethod - @abstractmethod - def extract_key(cls, *args, **kwargs) -> Hashable: - """Returns key from arguments passed to `__init__()`. - - Important: - The key is used to store instance in cache. It should be the same as key - returned by instance `Distinct.get_key()`! - """
- -# Enums -
[docs]class ByteOrder(Enum): - """Byte order for storing numbers in binary `.MemoryBuffer`. - """ - LITTLE = 'little' - BIG = 'big' - NETWORK = BIG
- -
[docs]class ZMQTransport(IntEnum): - """ZeroMQ transport protocol. - """ - UNKNOWN = 0 # Not a valid option, defined only to handle undefined values - INPROC = 1 - IPC = 2 - TCP = 3 - PGM = 4 - EPGM = 5 - VMCI = 6
- -
[docs]class ZMQDomain(IntEnum): - """ZeroMQ address domain. - """ - UNKNOWN = 0 # Not a valid option, defined only to handle undefined values - LOCAL = 1 # Within process (inproc) - NODE = 2 # On single node (ipc or tcp loopback) - NETWORK = 3 # Network-wide (ip address or domain name)
- -# Enhanced string types -
[docs]class ZMQAddress(str): - """ZeroMQ endpoint address. - - It behaves like `str`, but checks that value is valid ZMQ endpoint address, has - additional R/O properties and meaningful `repr()`. - - Raises: - ValueError: When string value passed to constructor is not a valid ZMQ endpoint address. - """ - def __new__(cls, value: AnyStr): - if isinstance(value, bytes): - value = cast(bytes, value).decode('utf8') - if '://' in value: - protocol, _ = value.split('://', 1) - if protocol.upper() not in ZMQTransport._member_map_: - raise ValueError(f"Unknown protocol '{protocol}'") - if protocol.upper() == 'UNKNOWN': - raise ValueError("Invalid protocol") - else: - raise ValueError("Protocol specification required") - return str.__new__(cls, value.lower()) - def __repr__(self): - return f"ZMQAddress('{self}')" - @property - def protocol(self) -> ZMQTransport: - """Transport protocol. - """ - protocol, _ = self.split('://', 1) - return ZMQTransport._member_map_[protocol.upper()] - @property - def address(self) -> str: - """Endpoint address. - """ - _, address = self.split('://', 1) - return address - @property - def domain(self) -> ZMQDomain: - """Endpoint address domain. - """ - if self.protocol == ZMQTransport.INPROC: - return ZMQDomain.LOCAL - if self.protocol == ZMQTransport.IPC: - return ZMQDomain.NODE - if self.protocol == ZMQTransport.TCP: - if self.address.startswith('127.0.0.1') or self.address.lower().startswith('localhost'): - return ZMQDomain.NODE - return ZMQDomain.NETWORK - # PGM, EPGM and VMCI - return ZMQDomain.NETWORK
- -
[docs]class MIME(str): - """MIME type specification. - - It behaves like `str`, but checks that value is valid MIME type specification, has - additional R/O properties and meaningful `repr()`. - - """ - #: Supported MIME types - MIME_TYPES = ['text', 'image', 'audio', 'video', 'application', 'multipart', 'message'] - def __new__(cls, value: AnyStr): - dfm = list(value.split(';')) - mime_type: str = dfm.pop(0) - if (i := mime_type.find('/')) == -1: - raise ValueError("MIME type specification must be 'type/subtype[;param=value;...]'") - if mime_type[:i] not in cls.MIME_TYPES: - raise ValueError(f"MIME type '{mime_type[:i]}' not supported") - if [i for i in dfm if '=' not in i]: - raise ValueError("Wrong specification of MIME type parameters") - obj = str.__new__(cls, value) - obj._bs_: int = obj.find('/') - obj._fp_: int = obj.find(';') - return obj - def __repr__(self): - return f"MIME('{self}')" - @property - def mime_type(self) -> str: - """MIME type specification: <type>/<subtype>. - """ - if self._fp_ != -1: - return self[:self._fp_] - return self - @property - def type(self) -> str: - """MIME type. - """ - return self[:self._bs_] - @property - def subtype(self) -> str: - """MIME subtype. - """ - if self._fp_ != -1: - return self[self._bs_ + 1:self._fp_] - return self[self._bs_ + 1:] - @property - def params(self) -> Dict[str, str]: - """MIME parameters. - """ - if self._fp_ != -1: - return {k.strip(): v.strip() for k, v - in (x.split('=') for x in self[self._fp_+1:].split(';'))} - return {}
- -
[docs]class PyExpr(str): - """Source code for Python expression. - - It behaves like `str`, but checks that value is a valid Python expression, and provides - direct access to compiled code. - - Raises: - SyntaxError: When string value is not a valid Python expression. - """ - _expr_ = None - def __new__(cls, value: str): - expr = compile(value, "PyExpr", 'eval') - new = str.__new__(cls, value) - new._expr_ = expr - return new - def __repr__(self): - return f"PyExpr('{self}')" -
[docs] def get_callable(self, arguments: str='', namespace: Dict[str, Any]=None) -> Callable: - """Returns expression as callable function ready for execution. - - Arguments: - arguments: String with arguments (names separated by coma) for returned function. - namespace: Dictionary with namespace elements available for expression. - """ - ns = {} - if namespace: - ns.update(namespace) - code = compile(f"def expr({arguments}):\n return {self}", - "PyExpr", 'exec') - eval(code, ns) # pylint: disable=[W0123] - return ns['expr']
- @property - def expr(self): - "Expression code ready to be appased to `eval`." - return self._expr_
- -
[docs]class PyCode(str): - """Python source code. - - It behaves like `str`, but checks that value is a valid Python code block, and provides - direct access to compiled code. - - Raises: - SyntaxError: When string value is not a valid Python code block. - """ - _code_ = None - def __new__(cls, value: str): - code = compile(value, "PyCode", 'exec') - new = str.__new__(cls, value) - new._code_ = code - return new - @property - def code(self): - """Python code ready to be appased to `exec`. - """ - return self._code_
- -
[docs]class PyCallable(str): - """Source code for Python callable. - - It behaves like `str`, but checks that value is a valid Python callable (function of class - definition), and acts like a callable (i.e. you can directly call the PyCallable value). - - Raises: - ValueError: When string value does not contains the function or class definition. - SyntaxError: When string value is not a valid Python callable. - """ - _callable_ = None - #: Name of the callable (function). - name: str = None - def __new__(cls, value: str): - callable_name = None - for line in value.split('\n'): - if line.lower().startswith('def '): - callable_name = line[4:line.find('(')].strip() - break - if callable_name is None: - for line in value.split('\n'): - if line.lower().startswith('class '): - callable_name = line[6:line.find('(')].strip() - break - if callable_name is None: - raise ValueError("Python function or class definition not found") - ns = {} - eval(compile(value, "PyCallable", 'exec'), ns) # pylint: disable=[W0123] - new = str.__new__(cls, value) - new._callable_ = ns[callable_name] - new.name = callable_name - return new - def __call__(self, *args, **kwargs): - return self._callable_(*args, **kwargs)
- -# Metaclasses -
[docs]def Conjunctive(name, bases, attrs): - """Returns a metaclass that is conjunctive descendant of all metaclasses used by parent - classes. - - Example: - - class A(type): pass - - class B(type): pass - - class AA(metaclass=A):pass - - class BB(metaclass=B):pass - - class CC(AA, BB, metaclass=Conjunctive): pass - """ - basemetaclasses = [] - for base in bases: - metacls = type(base) - if isinstance(metacls, type) and metacls is not type and not metacls in basemetaclasses: - basemetaclasses.append(metacls) - dynamic = type(''.join(b.__name__ for b in basemetaclasses), tuple(basemetaclasses), {}) - return dynamic(name, bases, attrs)
- -# Functions -
[docs]def load(spec: str) -> Any: - """Return object from module. Module is imported if necessary. - - Arguments: - spec: Object specification in format `module[.submodule...]:object_name[.object_name...]` - - """ - module_spec, name = spec.split(':') - if module_spec in sys.modules: - module = sys.modules[module_spec] - else: - module = import_module(module_spec) - result = module - for item in name.split('.'): - result = getattr(result, item) - return result
- -
- -
- -
-
-
-
-

- Back to top - -

-

- © Copyright 2020-2023, The Firebird Project.
- Created using Sphinx 5.3.0.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/index.html b/docs/firebird-base.docset/Contents/Resources/Documents/_modules/index.html deleted file mode 100644 index 883c471..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_modules/index.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - Overview: module code — Firebird-base 1.6.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

- Back to top - -

-

- © Copyright 2020-2023, The Firebird Project.
- Created using Sphinx 5.3.0.
-

-
-
- - \ No newline at end of file diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/buffer.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/buffer.txt deleted file mode 100644 index fb8ce88..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/buffer.txt +++ /dev/null @@ -1,23 +0,0 @@ -.. module:: firebird.base.buffer - :synopsis: Memory buffer manager - -############################## -buffer - Memory buffer manager -############################## - -Overview -======== - -This module provides a raw memory buffer manager with convenient methods to read/write -data of various data type. - -MemoryBuffer -============ -.. autoclass:: MemoryBuffer - -Buffer factories -================ -.. autoclass:: BufferFactory -.. autoclass:: BytesBufferFactory -.. autoclass:: CTypesBufferFactory - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/changelog.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/changelog.txt deleted file mode 100644 index 08221a1..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/changelog.txt +++ /dev/null @@ -1,206 +0,0 @@ -######### -Changelog -######### - -Version 1.6.0 -============= - -* `~firebird.base.protobuf` module: - - - Registration of already registered protobuf registration is now ignored instead - raising exception. - -* `~firebird.base.config` module: - - - `.Config.get_config()` and `.Option.get_config()` now provides `plain` bool argument - to return configuration text without comments. Deafult is False. - -* `~firebird.base.trace` module: - - - Fixed bug in `.TraceManager.load_config()`. - - -Version 1.5.0 -============= - -* Move away from setup.cfg to pyproject.toml, new source tree layout. - -Version 1.4.3 -============= - -* `~firebird.base.types` module: - - - Added internal functions `_decompose` and `_power_of_two` from stdlib `.enum` module, - because they were removed in Python 3.11. - -* `~firebird.base.protobuf` module: - - - Use :ref:`importlib.metadata.entry_points ` instead `pkg_resources.iter_entry_points`. - -* Improved documentation. - -Version 1.4.2 -============= - -* Optimizations. -* Cleanup of pylint warnings. -* Updated documentation. -* Fixed unregistered bugs: - - - Signature in `firebird.base.config.IntOption.clear`. - - Signature in `firebird.base.trace.TraceManager.add_trace`. Keyword argument `decorator` - (with default) could not be used with args/kwargs, so it was removed. New - `~firebird.base.trace.TraceManager.decorator` attribute was added to - `~firebird.base.trace.TraceManager` that could be used to change trace decorator used - for intrumentation. - -Version 1.4.1 -============= - -* Fix: uregistered bug in trace.TraceConfig - redundant `flags` definition. -* New: Documentation is now also provided as Dash_ / Zeal_ docset, downloadable from releases_ at github. - -Version 1.4.0 -============= - -* Upgrade to protobuf 4.21.1. As this upgrade has consequences, please read - https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates - -Version 1.3.1 -============= - -* `~firebird.base.buffer` module: - - - Added `.MemoryBuffer.write_sized_string` for symetry with `.read_sized_string`. - - Now `.MemoryBuffer` string functions has also `errors` parameter in addition to `encoding`. - -* `~firebird.base.config` module: - - - Direct assignment to `.Config` option raises a `ValueError` exception with message - "Cannot assign values to option itself, use `option.value` instead". - -Version 1.3.0 -============= - -* `~firebird.base.config` module: - - - Layout produced by `~firebird.base.config.get_config()` was changed. - - `.Config` has new constructor keyword-only argument `description`. - - Fix: uregistered bug in config.ListOption - value and default was the same instance - -Version 1.2.0 -============= - -* Build scheme changed to `PEP 517`. -* Various changes to documentation and type hint adjustments. -* `~firebird.base.config` module: - - - **BREAKING CHANGE**: `.ApplicationDirectoryScheme` was replaced by - `~firebird.base.config.DirectoryScheme` class, and - `~firebird.base.config.get_directory_scheme()` has changed signature. - - Directory scheme was reworked and now also supports concept of HOME directory. - - New MacOS directory scheme support. As I don't have access to MacOS, this support - should be considered EXPERIMENTAL. Any feedback about it's correctness is welcome. - - Added: New `.Config` constructor keyword-only `bool` argument `optional` and - associated `~Config.optional` read-only property. - - Added: `.Config.has_value()` function. - - New class: `.PathOption` for Configuration options with `pathlib.Path` value. -* `~firebird.base.protobuf` module: - - - Added: function `.get_message_factory`. -* `~firebird.base.signal` module: - - - Fix: Bug in `eventsocket` signature handling. -* `~firebird.base.trace` module: - - - Added: `apply_to_descendants` boolean configuration option to apply configuration also - to all registered descendant classes. The default value is `True`. - -Version 1.1.0 -============= - -* New module: `signal` - Callback system based on Signals and Slots, and "Delphi events" -* `~firebird.base.types` module: - - - `~firebird.base.types.load` function now supports `object_name[.object_name...]` - specifications instead single `object_name`. -* `~firebird.base.config` module: - - - New class `.ApplicationDirectoryScheme` - - `~firebird.base.config.Config.load_config()`: raises error when section is missing, - better error handling when exception is raised while loading options - - `~firebird.base.config.PyCallableOption` `signature` argument could be - `inspect.Signature` or Callable - - Introduced `.PROTO_CONFIG` constant with fully qualified name for `ConfigProto` protobuf - - Optional argument `to_default` in `~firebird.base.config.Option.clear()` is now keyword-only. -* `~firebird.base.logging` module: - - - `.get_logging_id()` uses `__qualname__` instead `__name__` -* `~firebird.base.protobuf` module: - - - Added direct support for key well-known data types `Empty`, `Any`, `Duration`, - `Timestamp`, `Struct`, `Value`, `ListValue` and `FieldMask`. They are automatically - registered. New constants 'PROTO_' with fully qualified names. - - `~firebird.base.protobuf.create_message()` has new optional `serialized` argument with - `bytes` that should be parsed into newly created message instance. - - New functions `~firebird.base.protobuf.struct2dict()` and `~firebird.base.protobuf.dict2struct()` -* `~firebird.base.trace` module: - - - `~firebird.base.trace.TraceFlag` value `DISABLED` was renamed to `NONE`. - - Added support for trace configuration based on `~firebird.base.config`, using new - classes `~firebird.base.trace.BaseTraceConfig`, `~firebird.base.trace.TracedMethodConfig`, - `~firebird.base.trace.TracedClassConfig` and `~firebird.base.trace.TraceConfig`. - - New methods in `~firebird.base.trace.TraceManager`: - - - `~firebird.base.trace.TraceManager.load_config()` to update trace from configuration. - - `~firebird.base.trace.TraceManager.set_flag()` and - `~firebird.base.trace.TraceManager.clear_flag()`. -* `~firebird.base.types` module: - - - `~firebird.base.types.MIME` now handles access to properties more efficiently and faster. - - New function `~firebird.base.types.load()`. -* Changes in documentation. - -Version 1.0.0 -============= - -* Documentation: new examples for :doc:`trace`, :doc:`logging` and :doc:`hooks` -* Documentation: adjustments to css -* DataList is now generic class -* `.DataList.extract()` has new 'copy' argument. - -Version 0.6.1 -============= - -* Promoted to stable -* More documentation - -Version 0.6.0 -============= - -* New module: `~firebird.base.strconv` - Data conversion from/to string -* New module: `~firebird.base.trace` - Trace/audit for class instances -* Reworked module: `~firebird.base.config` - Classes for configuration definitions - - - New class: `.ConfigOption` - Configuration option with `Config` value - - New class: `.ConfigListOption` - Configuration option with list of `Config` values - - New class: `.DataclassOption` - Configuration option with a dataclass value -* Changed module: `~firebird.base.types` - - - New class: `.MIME` - MIME type specification - - New class: `.PyExpr` - Source code for Python expression - - New class: `.PyCode` - Python source code - - New class: `.PyCallable` - Source code for Python callable - - Removed function: str2bool -* Changed module: `~firebird.base.logging` - - - Trace/audit functionality removed (into new module `~firebird.base.trace`) - -Version 0.5.0 -============= - -Initial release. - -.. _releases: https://github.com/FirebirdSQL/python3-base/releases -.. _Dash: https://kapeli.com/dash -.. _Zeal: https://zealdocs.org/ diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/collections.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/collections.txt deleted file mode 100644 index 7abe374..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/collections.txt +++ /dev/null @@ -1,52 +0,0 @@ -.. module:: firebird.base.collections - :synopsis: Various collection types - -###################################### -collections - Various collection types -###################################### - -Overview -======== - -This module provides data structures that behave much like builtin `list` and `dict` types, -but with direct support of operations that can use structured data stored in container, and -which would normally require utilization of `operator`, `functools` or other means. - -All containers provide next operations: - -* `filter` and `filterfalse` that return generator that yields items for which `expr` is - evaluated as True (or False). -* `find` that returns first item for which `expr` is evaluated as True, or default. -* `contains` that returns True if there is any item for which `expr` is evaluated as True. -* `occurrence` that returns number of items for which `expr` is evaluated as True. -* `all` and `any` that return True if `expr` is evaluated as True for all or any list element(s). -* `report` that returns generator that yields data produced by expression(s) evaluated on - list items. - -Individual collection types provide additional operations like splitting and extracting -based on expression etc. - -Expressions used by these methods could be strings that contain Python expression -referencing the collection item(s), or lambda functions. - -Types for type hints & annotations -================================== - -.. autodata:: Item -.. autodata:: TypeSpec -.. autodata:: ItemExpr -.. autodata:: FilterExpr -.. autodata:: CheckExpr - -Collections -=========== -.. autoclass:: BaseObjectCollection -.. autoclass:: DataList -.. autoclass:: Registry - -Functions -========= -.. autofunction:: make_lambda - - - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/config.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/config.txt deleted file mode 100644 index dc79f62..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/config.txt +++ /dev/null @@ -1,363 +0,0 @@ -.. module:: firebird.base.config - :synopsis: Configuration definitions - -################################## -config - Configuration definitions -################################## - -Overview -======== - -Complex applications (and some library modules like `logging`) could be often parametrized -via configuration. This module provides a framework for unified structured configuration -that supports: - -* configuration options of various data type, including lists and other complex types -* validation -* direct manipulation of configuration values -* reading from (and writing into) configuration in `configparser` format -* exchanging configuration (for example between processes) using Google protobuf messages - -Architecture ------------- - -The framework is based around two classes: - -* `.Config` - Collection of configuration options and sub-collections. Particular - configuration is then realized as descendant from this class, that defines configuration - options in constructor, and customize the validation when required. -* `.Option` - Abstract base class for configuration options, where descendants implement - handling of particular data type. This module provides implementation for next data - types: `str`, `int`, `float`, `bool`, `~decimal.Decimal`, `~enum.Enum`, `~enum.Flag`, - `~uuid.UUID`, `.MIME`, `.ZMQAddress`, `list`, `~dataclasses.dataclass`, `.PyExpr`, - `.PyCode` and `.PyCallable`. It also provides special options `ConfigOption` and - `ConfigListOption`. - -Additionally, the `.ApplicationDirectoryScheme` abstract base class defines set of mostly -used application directories. The function `.get_directory_scheme()` could be then used -to obtain instance that implements platform-specific standards for file-system location -for these directories. Currently, only "Windows", "Linux" and "MacOS" directory schemes -are supported. - -.. note:: - You may use `platform.system` call to determine the scheme name suitable for platform - where your application is running. - -Usage ------ -First, you need to define your own configuration. - -.. code-block:: - - from enum import IntEnum - from firebird.base.config import Config, StrOption, IntOption, ListOption - - class SampleEnum(IntEnum): - "Enum for testing" - UNKNOWN = 0 - READY = 1 - RUNNING = 2 - WAITING = 3 - SUSPENDED = 4 - FINISHED = 5 - ABORTED = 6 - - class DbConfig(Config): - "Simple database config" - def __init__(self, name: str): - super().__init__(name) - # options - self.database: StrOption = StrOption('database', 'Database connection string', - required=True) - self.user: StrOption = StrOption('user', 'User name', required=True, - default='SYSDBA') - self.password: StrOption = StrOption('password', 'User password') - - class SampleConfig(Config): - """Sample Config. - - Has three options and two sub-configs. - """ - def __init__(self): - super().__init__('sample-config') - # options - self.opt_str: StrOption = StrOption('opt_str', "Sample string option") - self.opt_int: IntOption = StrOption('opt_int', "Sample int option") - self.enum_list: ListOption = ListOption('enum_list', "List of enum values", - item_type=SampleEnum) - # sub configs - self.master_db: DbConfig = DbConfig('master-db') - self.backup_db: DbConfig = DbConfig('backup-db') - -.. important:: - - Option must be assigned to Config attributes with the same name as option name. - - -Typically you need only one instance of your configuration class in application. - -.. code-block:: - - app_config: SampleConfig = SampleConfig() - -Typically, your application is configured using file(s) in `configparser` format. You may -create initial one using `Config.get_config()` method. - -.. note:: - - `Config.get_config()` works with current configuration values. When called on "empty" - instance it returns "default" configuration. Option values that match the default are - returned as commented out. - -.. code-block:: - - >>> print(app_config.get_config()) - - [sample-config] - ; - ; Sample Config. - ; - ; Has three options and two sub-configs. - ; - - ; opt_str - ; ------- - ; - ; data type: str - ; - ; [optional] Sample string option - ; - ;opt_str = - - ; opt_int - ; ------- - ; - ; data type: str - ; - ; [optional] Sample int option - ; - ;opt_int = - - ; enum_list - ; --------- - ; - ; data type: list - ; - ; [optional] List of enum values - ; - ;enum_list = - - [master-db] - ; - ; Simple DB config - ; - - ; database - ; -------- - ; - ; data type: str - ; - ; [REQUIRED] Database connection string - ; - ;database = - - ; user - ; ---- - ; - ; data type: str - ; - ; [REQUIRED] User name - ; - ;user = SYSDBA - - ; password - ; -------- - ; - ; data type: str - ; - ; [optional] User password - ; - ;password = - - [backup-db] - ; - ; Simple DB config - ; - - ; database - ; -------- - ; - ; data type: str - ; - ; [REQUIRED] Database connection string - ; - ;database = - - ; user - ; ---- - ; - ; data type: str - ; - ; [REQUIRED] User name - ; - ;user = SYSDBA - - ; password - ; -------- - ; - ; data type: str - ; - ; [optional] User password - ; - ;password = - -To read the configuration from file, use the `~configparser.ConfigParser` and pass it -to `Config.load_config()` method. - -Example configuration file:: - - ; myapp.cfg - - [DEFAULT] - password = masterkey - - [sample-config] - opt_str = Lorem ipsum - enum_list = ready, finished, aborted - - [master-db] - database = primary - user = tester - password = lockpick - - [backup-db] - database = secondary - -.. code-block:: - - from configparser import ConfigParser - - cfg = ConfigParser() - cfg.read('myapp.cfg') - app_config.load_config(cfg) - -Access to configuration values is through attributes on your `Config` instance, and -their `value` attribute. - -.. code-block:: - - >>> app_config.opt_str.value - Lorem ipsum - >>> app_config.opt_int.value - >>> app_config.enum_list.value - [READY, FINISHED, ABORTED] - >>> app_config.master_db.database.value - primary - >>> app_config.master_db.user.value - tester - >>> app_config.master_db.password.value - lockpick - >>> app_config.backup_db.database.value - secondary - >>> app_config.backup_db.user.value - SYSDBA - >>> app_config.backup_db.password.value - masterkey - -ConfigProto -=========== - -You can transfer configuration (state) between instances of your `Config` classes using -Google Protocol Buffer message `firebird.base.ConfigProto` and methods -`~Config.save_proto()` and `~Config.load_proto()`. - -The protobuf message is defined in :file:`/proto/config.proto`. - -.. literalinclude:: ../proto/config.proto - :language: proto - :lines: 30- - -.. note:: - - You can use it directly or via `.protobuf` registry. - - .. code-block:: - - # Direct use - from firebird.base.config import ConfigProto - cfg_msg = ConfigProto() - - Because the proto file is NOT registered in `.protobuf` registry, you must register - it manually. The proto file is listed in `setup.cfg` under *"firebird.base.protobuf"* - entrypoint, so use `load_registered('firebird.base.protobuf')` for its registration. - - .. code-block:: - - from firebird.base.protobuf import load_registered, create_message - load_registered('firebird.base.protobuf') - cfg_msg = create_message('firebird.base.ConfigProto') - -.. important:: - - Although `Option` also provides methods `~Option.save_proto()` and `~Option.load_proto()` - to transfer option value in/out ConfigProto message, you should always use methods - on `Config` instance because option's serialization may relly on `Config` instance that - owns them. - - .. seealso:: `.ConfigOption`, `.ConfigListOption` - -Constants -========= - -.. data:: PROTO_CONFIG - :annotation: Fully qualified name for `ConfigProto`_ protobuf. - -.. tip:: - - To address `ConfigProto`_ in functions like `~firebird.base.protobuf.create_message()`, - use `PROTO_CONFIG` constant. - - -Application Directory Scheme -============================ - -.. versionadded:: 1.1.0 - -.. versionchanged:: 1.2.0 - -.. autoclass:: DirectoryScheme -.. autoclass:: WindowsDirectoryScheme -.. autoclass:: LinuxDirectoryScheme -.. autoclass:: MacOSDirectoryScheme -.. autofunction:: get_directory_scheme - -Config -====== -.. autoclass:: Config - -Options -======= -.. autoclass:: Option -.. autoclass:: StrOption -.. autoclass:: IntOption -.. autoclass:: FloatOption -.. autoclass:: DecimalOption -.. autoclass:: BoolOption -.. autoclass:: ZMQAddressOption -.. autoclass:: EnumOption -.. autoclass:: FlagOption -.. autoclass:: UUIDOption -.. autoclass:: MIMEOption -.. autoclass:: ListOption -.. autoclass:: DataclassOption -.. autoclass:: PathOption -.. autoclass:: PyExprOption -.. autoclass:: PyCodeOption -.. autoclass:: PyCallableOption -.. autoclass:: ConfigOption -.. autoclass:: ConfigListOption - -Functions -========= -.. autofunction:: create_config - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/hooks.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/hooks.txt deleted file mode 100644 index 5fe38eb..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/hooks.txt +++ /dev/null @@ -1,157 +0,0 @@ -.. module:: firebird.base.hooks - :synopsis: Hook manager - -#################### -hooks - Hook manager -#################### - -Overview -======== - -This module provides a general framework for callbacks and "hookable" events. - -Architecture ------------- - -The callback extension mechanism is based on the following: - -* The `Event source` provides one or more "hookable events" that work like connection points. - The event source represents "origin of event" and is always identified by class, class - instance or name. Event sources that are identified by classes (or their instances) must - be registered along with events they provide. -* `Event` is typically linked to particular event source, but it's not mandatory and it's - possible to define global events. Event is represented as value of any type, that must - be unique in used context (particular event source or global). - - Each event should be properly documented along with required signature for callback - function. -* `Event provider` is a class or function that implements the event for event source, and - asks the `.hook_manager` for list of event consumers (callbacks) registered for particular - event and source. -* `Event consumer` is a function or class method that implements the callback for particular - event. The callback must be registered in `.hook_manager` before it could be called by - event providers. - - -The architecture supports multiple usage strategies: - -* If event provider uses class instance to identify the event source, it's possible to - register callbacks to all instances (by registering to class), or particular instance(s). -* It's possible to register callback to particular instance by name, if instance is associated - with name by `register_name()` function. -* It's possible to register callback to `.ANY` event from particular source, or particular - event from `.ANY` source, or even to `.ANY` event from `.ANY` source. - -Example -------- - -.. code-block:: python - - from __future__ import annotations - from enum import Enum, auto - from firebird.base.types import * - from firebird.base.hooks import hook_manager - - class MyEvents(Enum): - "Sample definition of events" - CREATE = auto() - ACTION = auto() - - class MyHookable: - "Example of hookable class, i.e. a class that calls hooks registered for events." - def __init__(self, name: str): - self.name: str = name - for hook in hook_manager.get_callbacks(MyEvents.CREATE, self): - try: - hook(self, MyEvents.CREATE) - except Exception as e: - print(f"{self.name}.CREATE hook call outcome: ERROR ({e.args[0]})") - else: - print(f"{self.name}.CREATE hook call outcome: OK") - def action(self): - print(f"{self.name}.ACTION!") - for hook in hook_manager.get_callbacks(MyEvents.ACTION, self): - try: - hook(self, MyEvents.ACTION) - except Exception as e: - print(f"{self.name}.ACTION hook call outcome: ERROR ({e.args[0]})") - else: - print(f"{self.name}.ACTION hook call outcome: OK") - - class MyHook: - "Example of hook implementation" - def __init__(self, name: str): - self.name: str = name - def callback(self, subject: MyHookable, event: MyEvents): - print(f"Hook {self.name} event {event.name} called by {subject.name}") - def err_callback(self, subject: MyHookable, event: MyEvents): - self.callback(subject, event) - raise Exception("Error in hook") - - - # Example code that installs and uses hooks - - hook_manager.register_class(MyHookable, MyEvents) - hook_A: MyHook = MyHook('Hook-A') - hook_B: MyHook = MyHook('Hook-B') - hook_C: MyHook = MyHook('Hook-C') - - print("Install hooks") - hook_manager.add_hook(MyEvents.CREATE, MyHookable, hook_A.callback) - hook_manager.add_hook(MyEvents.CREATE, MyHookable, hook_B.err_callback) - hook_manager.add_hook(MyEvents.ACTION, MyHookable, hook_C.callback) - - print("Create event sources, emits CREATE") - src_A: MyHookable = MyHookable('Source-A') - src_B: MyHookable = MyHookable('Source-B') - - print("Install instance hooks") - hook_manager.add_hook(MyEvents.ACTION, src_A, hook_A.callback) - hook_manager.add_hook(MyEvents.ACTION, src_B, hook_B.callback) - - print("And action!") - src_A.action() - src_B.action() - - -Output from sample code:: - - Install hooks - Create event sources, emits CREATE - Hook Hook-A event CREATE called by Source-A - Source-A.CREATE hook call outcome: OK - Hook Hook-B event CREATE called by Source-A - Source-A.CREATE hook call outcome: ERROR (Error in hook) - Hook Hook-A event CREATE called by Source-B - Source-B.CREATE hook call outcome: OK - Hook Hook-B event CREATE called by Source-B - Source-B.CREATE hook call outcome: ERROR (Error in hook) - Install instance hooks - And action! - Source-A.ACTION! - Hook Hook-A event ACTION called by Source-A - Source-A.ACTION hook call outcome: OK - Hook Hook-C event ACTION called by Source-A - Source-A.ACTION hook call outcome: OK - Source-B.ACTION! - Hook Hook-B event ACTION called by Source-B - Source-B.ACTION hook call outcome: OK - Hook Hook-C event ACTION called by Source-B - Source-B.ACTION hook call outcome: OK - - -Functions -========= -.. autofunction:: register_class -.. autofunction:: register_name -.. autofunction:: add_hook -.. autofunction:: get_callbacks - -Classes -======= -.. autoclass:: HookManager - -Globals -======= -.. autodata:: hook_manager - :no-value: diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/index.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/index.txt deleted file mode 100644 index 86384c6..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/index.txt +++ /dev/null @@ -1,48 +0,0 @@ - -#################################### -The Firebird Base library for Python -#################################### - -The `firebird-base` package provides common Python 3 modules used by `Firebird Project`_ -in various development projects. However, these modules have general applicability outside -the scope of development for Firebird RDBMS. - -Topic covered by `firebird-base` package: - -- General data types like `singletons`, `sentinels` and objects with identity. -- Unified system for data conversion from/to string. -- `DataList` and `Registry` collection types with advanced data-processing cappabilities. -- Work with structured binary buffers. -- Global registry of Google `protobuf` messages and enumerations. -- Extended configuration system based on `ConfigParser`. -- Context-based logging. -- Trace/audit for class instances. -- General "hook" mechanism. -- Callback system based on Signals and Slots, and "Delphi events". - - -.. note:: Requires Python 3.8+ - -.. tip:: You can download docset for Dash_ (MacOS) or Zeal_ (Windows / Linux) documentation - readers from releases_ at github. - -.. toctree:: - :maxdepth: 1 - :includehidden: - -.. toctree:: - :maxdepth: 1 - :hidden: - - introduction - modules - changelog - license - -| -| - -.. _Firebird Project: http://www.firebirdsql.org -.. _releases: https://github.com/FirebirdSQL/python3-base/releases -.. _Dash: https://kapeli.com/dash -.. _Zeal: https://zealdocs.org/ diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/introduction.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/introduction.txt deleted file mode 100644 index 55c2c86..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/introduction.txt +++ /dev/null @@ -1,137 +0,0 @@ -############ -Introduction -############ - -The firebird-base package is a set of Python 3 modules commonly used by Firebird Project in -various development projects (for example the firebird-driver). However, these modules have -general applicability outside the scope of development for Firebird RDBMS. - -Common data types -================= - -The `.types` module provides collection of classes and other types that are often used by -other library modules or applications. - -* Exception `.Error` that is intended to be used as a base class of all application-related - errors. The important difference from `Exception` class is that `.Error` accepts keyword - arguments, that are stored into instance attributes with the same name. -* `.Singleton` base class for singletons. -* `.Sentinel` base class for named sentinel objects that provide meaningful `str` and `repr`, - along with collection of predefined sentinels. -* `.Distinct` abstract base class for classes (incl. dataclasses) with distinct instances. -* Collection of `Enums` and `custom string types`. - -Various collection types -======================== - -The `.collections` module provides data structures that behave much like builtin `list` and -`dict` types, but with direct support of operations that can use structured data stored in -container, and which would normally require utilization of `operator`, `functools` or other -means. - -All containers provide next operations: - -* `filter` and `filterfalse` that return generator that yields items for which expr is - evaluated as True (or False). -* `find` that returns first item for which expr is evaluated as True, or default. -* `contains` that returns True if there is any item for which expr is evaluated as True. -* `occurrence` that returns number of items for which expr is evaluated as True. -* `all` and `any` that return True if expr is evaluated as True for all or any list element(s). -* `report` that returns generator that yields data produced by expression(s) evaluated on list items. - -Individual collection types provide additional operations like splitting and extracting -based on expression etc. - -Expressions used by these methods could be strings that contain Python expression referencing -the collection item(s), or lambda functions. - -Data conversion from/to string -============================== - -While Python types typically support conversion to string via builtin `str()` function (and -custom `__str__` methods), there is no symetric operation that converts string created by -`str()` back to typed value. Module `.strconv` provides support for such symetric conversion -from/to string for any data type. - -Symetric string conversion is used by `~firebird.base.config` module, notably by -`~firebird.base.config.ListOption` and `~firebird.base.config.DataclassOption`. You can -extend the range of data types supported by these options by registering convertors for -required data types. - -Configuration definitions -========================= - -Complex applications (and some library modules like `logging`) could be often parametrized -via configuration. Module `~firebird.base.config` provides a framework for unified structured -configuration that supports: - -* configuration options of various data type, including lists and other complex types -* validation -* direct manipulation of configuration values -* reading from (and writing into) configuration in `configparser` format -* exchanging configuration (for example between processes) using Google protobuf messages - -Memory buffer manager -===================== - -Module `.buffer` provides a raw memory buffer manager with convenient methods to read/write -data of various data type. - -Hook manager -============ - -Module `.hooks` provides a general framework for callbacks and “hookable” events, that -supports multiple usage strategies. - -Context-based logging -===================== - -Module `.logging` provides context-based logging system built on top of standard `logging` -module. - -The context-based logging: - -* Adds context information (defined as combination of topic, agent and context string values) - into `~logging.LogRecord`, that could be used in logging message. -* Adds support for f-string message format. -* Allows assignment of loggers to specific contexts. The `.LoggingManager` class maintains - a set of bindings between `Logger` objects and combination of `agent`, `context` and `topic` - specifications. It’s possible to bind loggers to exact combination of values, or whole - sets of values using `.ANY` sentinel. It means that is possible to assign specific Logger - to log messages for particular agent in any context, or any agent operating in specific - context etc. - -Trace/audit for class instances -=============================== - -Module `.trace` provides trace/audit logging for functions or object methods through -context-based logging provided by `.logging` module. - -The trace logging is performed by `.traced` decorator. You can use this decorator directly, -or use `.TracedMixin` class to automatically decorate methods of class instances on creation. -Each decorated callable could log messages before execution, after successful execution or -on failed execution (when unhandled execption is raised by callable). The trace decorator -can automatically add `agent` and `context` information, and include parameters passed to -callable, execution time, return value, information about raised exception etc. to log messages. - -The trace logging is managed by `.TraceManager`, that allows dynamic configuration of traced -callables at runtime. - -Registry for Google Protocol Buffer messages and enums -====================================================== - -Module `.protobuf` provides central registry for Google Protocol Buffer messages and enums. -The generated `*_pb2.py protobuf` files could be registered using `.register_decriptor` or -`.load_registered` function. The registry could be then used to obtain information about -protobuf messages or enum types, or to create message instances or enum values. - -Callback systems -================ - -Module `~firebird.base..signal` provides two callback mechanisms: one based on signals and -slots similar to Qt signal/slot, and second based on optional method delegation similar to -events in Delphi. - -In both cases, the callback callables could be functions, instance or class methods, -partials and lambda functions. The `inspect` module is used to define the signature for -callbacks, and to validate that only compatible callables are assigned. diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/license.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/license.txt deleted file mode 100644 index 935e89d..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/license.txt +++ /dev/null @@ -1,6 +0,0 @@ -####### -License -####### - -.. include:: ../LICENSE - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/logging.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/logging.txt deleted file mode 100644 index c869a27..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/logging.txt +++ /dev/null @@ -1,310 +0,0 @@ -.. module:: firebird.base.logging - :synopsis: Context-based logging - -############################### -logging - Context-based logging -############################### - -Overview -======== - -This module provides context-based logging system built on top of standard `logging` module. - -The context-based logging: - -1. Adds context information into `~logging.LogRecord`, that could be used in logging message. -2. Adds support for f-string message format. -3. Allows assignment of loggers to specific contexts. - -The logging context -------------------- -The logging context is defined as combination of `topic`, `agent` and `context` string values. - -The `agent` is typically an unit of code that works in specific execution contexts. For -example a code that process client request in web application (where request is the context), -or executes SQL command (the context could be a database connection, or transaction). -The `topic` is optional. It could be any string value that can be used as secondary context. - -Agent and Context identification --------------------------------- -Agents and contexts could be identified by string value, or by any object (i.e. you can use -the object that implement the agent or context). If object is used, the ID could be -provided as `logging_id` attribute, `__name__` attribute or by `__str__()` return value. - -A `LoggingIdMixin` class could be used to add `logging_id` support to any class. - -The LoggingManager ------------------- -The `LoggingManager` class maintains a set of bindings between `~logging.Logger` objects and -combination of `agent`, `context` and `topic` specifications. It's possible to bind loggers -to exact combination of values, or whole sets of values using `.ANY` sentinel. It means that -is possible to assign specific `~logging.Logger` to log messages for particular agent in -any context, or any agent operating in specific context etc. - -To log `agent` activities, use a logger returned by `.get_logger()` function/method. - -Example -------- - -The following program is an example of small but complex enough code that you can use to experiment with contextual logging options. Parts relevant to logging are highlighted in the code by embedded comments. The program is very simple simulation of virtual "human" agents that can change their mood during mutual interaction. - -.. code-block:: python - - # test-logging.py - from __future__ import annotations - import logging - from time import monotonic - from decimal import Decimal - from enum import IntEnum, auto - from firebird.base.types import * - from firebird.base.logging import LogLevel, LoggingIdMixin, get_logger - - class Mood(IntEnum): - "Agent moods" - ANGRY = auto() - SAD = auto() - NEUTRAL = auto() - PLEASED = auto() - HAPPY = auto() - - class Person(LoggingIdMixin): # LOGGING - "Sample virtual human agent" - def __init__(self, name: str, mood: Mood=Mood.NEUTRAL): - self.name: str = name - self.mood: Mood = mood - self.partners: List[Person] = [] - # >>> LOGGING - @property - def _logging_id_(self) -> str: - return f"{self.mood.name} {self.name}" - # <<< LOGGING - def change_mood(self, offset: int) -> None: - result = self.mood + offset - if result < Mood.ANGRY: - self.mood = Mood.ANGRY - elif result > Mood.HAPPY: - self.mood = Mood.HAPPY - else: - self.mood = Mood(result) - def process(self, message: str) -> None: - msg = message.lower() - if msg == "what you are doing here": - self.change_mood(-1) - if 'awful' in msg: - self.change_mood(-1) - if ('nice' in msg) or ('wonderful' in msg) or ('pleased' in msg): - if self.mood != Mood.ANGRY: - self.change_mood(1) - if 'happy' in msg: - if self.mood != Mood.ANGRY: - self.change_mood(2) - if 'very nice' in msg: - if self.mood != Mood.ANGRY: - self.change_mood(1) - if 'get lost' in msg: - self.change_mood(-2) - if self.name.lower() in msg: - if self.mood == Mood.SAD: - self.change_mood(1) - if self.name.lower() not in msg: - if self.mood == Mood.NEUTRAL: - self.change_mood(-1) - def process_response(self, to: str, mood: Mood) -> None: - if to == 'greeting': - if self.mood == Mood.NEUTRAL: - if mood > Mood.NEUTRAL: - self.mood = Mood.PLEASED - elif mood == Mood.ANGRY: - self.mood = Mood.SAD - elif self.mood == Mood.SAD: - if mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif mood == Mood.HAPPY: - self.mood = Mood.ANGRY - elif self.mood == Mood.ANGRY and mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif to == 'chat': - if self.mood == Mood.SAD and mood > Mood.NEUTRAL: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.ANGRY and mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.PLEASED and mood == Mood.ANGRY: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.HAPPY and mood == Mood.ANGRY: - self.mood = Mood.SAD - elif to == 'bye': - if self.mood == Mood.NEUTRAL: - if mood == Mood.ANGRY: - self.mood = Mood.ANGRY - elif mood > Mood.NEUTRAL: - self.mood = Mood.PLEASED - elif self.mood == Mood.HAPPY and mood == Mood.ANGRY: - self.mood = Mood.NEUTRAL - def meet(self, other: Person) -> None: - self.partners.append(other) - self.greeting(other) - def interact(self, other: Person, message: str) -> Mood: - print(f"[{other.name}] {message}") - # >>> LOGGING - get_logger(self, topic='Person').debug(f'Processing "{message}" from [{other.name}]') - # <<< LOGGING - self.process(message) - return self.mood - def greeting(self, other: Person) -> None: - if self.mood == Mood.NEUTRAL: - msg = f"Hi {other.name}, I'm {self.name}" - elif self.mood == Mood.ANGRY: - msg = "Hi" - elif self.mood == Mood.SAD: - msg = f"Hi {other.name}" - else: - msg = f"Hi {other.name}, I'm {self.name}. I'm {self.mood.name} to meet you." - self.process_response('greeting', other.interact(self, msg)) - def chat(self) -> None: - for other in self.partners: - if self.mood == Mood.ANGRY: - msg = "What you are doing here?" - elif self.mood == Mood.SAD: - msg = "The weather is awful today, don't you think?" - elif self.mood == Mood.NEUTRAL: - msg = "It's a fine day, don't you think?" - elif self.mood == Mood.PLEASED: - msg = "It's a very nice day, don't you think?" - else: - msg = "Today is a wonderful day!" - self.process_response('chat', other.interact(self, msg)) - def bye(self) -> str: - while self.partners: - other = self.partners.pop() - if self.mood == Mood.ANGRY: - msg = "Get lost!" - elif self.mood == Mood.SAD: - msg = "Bye" - elif self.mood == Mood.NEUTRAL: - msg = f"Bye, {other.name}." - elif self.mood == Mood.PLEASED: - msg = f"See you, {other.name}!" - else: - msg = f"Bye, {other.name}. Have a nice day!" - self.process_response('bye', other.interact(self, msg)) - if self.mood == Mood.ANGRY: - result = "I hate this meeting!" - elif self.mood == Mood.SAD: - result = "It was a waste of time!" - elif self.mood == Mood.NEUTRAL: - result = "It was OK." - elif self.mood == Mood.PLEASED: - result = "Nice meeting, I think." - else: - result = "What a wonderful meeting!" - return result - def __repr__(self) -> str: - return f"{self.name} [{self.mood.name}]" - - def meeting(name: str, persons: List[Person]): - "Simulation of virtual agents meeting" - - for person in persons: - person.log_context = name - - start = monotonic() - print("Meeting started...") - print(f"Attendees: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}") - - for person in persons: - for other in persons: - if other is not person: - person.meet(other) - - for person in persons: - person.chat() - - for person in persons: - person.bye() - - e = str(Decimal(monotonic() - start)) - print(f"Meeting closed in {e[:e.find('.')+6]} sec.") - print(f"Outcome: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}") - - def test_loggig(name: str, first: Mood, second: Mood) -> None: - meeting(name, [Person('Alex', first), Person('David', second)]) - - if __name__ == '__main__': - # >>> LOGGING - logger = logging.getLogger() - logger.setLevel(LogLevel.NOTSET) - sh = logging.StreamHandler() - sh.setFormatter(logging.Formatter('%(levelname)-10s: [%(topic)s][%(agent)s][%(context)s] %(message)s')) - logger.addHandler(sh) - # <<< LOGGING - test_loggig('TEST-1', Mood.SAD, Mood.PLEASED) - print('-'*20) - test_loggig('TEST-2', Mood.HAPPY, Mood.ANGRY) - -| - -**Output from sample code**:: - - > python test-logging.py - Meeting started... - Attendees: Alex [SAD], David [PLEASED] - [Alex] Hi David - DEBUG : [Person][PLEASED David][TEST-1] Processing "Hi David" from [Alex] - [David] Hi Alex, I'm David. I'm PLEASED to meet you. - DEBUG : [Person][SAD Alex][TEST-1] Processing "Hi Alex, I'm David. I'm PLEASED to meet you." from [David] - [Alex] It's a fine day, don't you think? - DEBUG : [Person][PLEASED David][TEST-1] Processing "It's a fine day, don't you think?" from [Alex] - [David] It's a very nice day, don't you think? - DEBUG : [Person][NEUTRAL Alex][TEST-1] Processing "It's a very nice day, don't you think?" from [David] - [Alex] Bye, David. Have a nice day! - DEBUG : [Person][PLEASED David][TEST-1] Processing "Bye, David. Have a nice day!" from [Alex] - [David] Bye, Alex. Have a nice day! - DEBUG : [Person][HAPPY Alex][TEST-1] Processing "Bye, Alex. Have a nice day!" from [David] - Meeting closed in 0.00132 sec. - Outcome: Alex [HAPPY], David [HAPPY] - -------------------- - Meeting started... - Attendees: Alex [HAPPY], David [ANGRY] - [Alex] Hi David, I'm Alex. I'm HAPPY to meet you. - DEBUG : [Person][ANGRY David][TEST-2] Processing "Hi David, I'm Alex. I'm HAPPY to meet you." from [Alex] - [David] Hi - DEBUG : [Person][HAPPY Alex][TEST-2] Processing "Hi" from [David] - [Alex] Today is a wonderful day! - DEBUG : [Person][ANGRY David][TEST-2] Processing "Today is a wonderful day!" from [Alex] - [David] What you are doing here? - DEBUG : [Person][SAD Alex][TEST-2] Processing "What you are doing here?" from [David] - [Alex] Bye - DEBUG : [Person][NEUTRAL David][TEST-2] Processing "Bye" from [Alex] - [David] Bye - DEBUG : [Person][SAD Alex][TEST-2] Processing "Bye" from [David] - Meeting closed in 0.00050 sec. - Outcome: Alex [SAD], David [SAD] - -Enums & Flags -============= -.. autoclass:: LogLevel -.. autoclass:: BindFlag - -Functions -========= -.. autofunction:: bind_logger -.. autofunction:: get_logger -.. autofunction:: get_logging_id -.. autofunction:: install_null_logger - -Logger adapter -============== -.. autoclass:: FBLoggerAdapter - -Logging manager -=============== -.. autoclass:: LoggingManager - -Mixins -====== -.. autoclass:: LoggingIdMixin - -Globals -======= -.. autodata:: logging_manager - :no-value: diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/modules.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/modules.txt deleted file mode 100644 index d6e0484..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/modules.txt +++ /dev/null @@ -1,20 +0,0 @@ -####### -Modules -####### - -Package modules -=============== - -.. toctree:: - :maxdepth: 2 - - types - collections - strconv - config - buffer - hooks - logging - trace - protobuf - signal diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/protobuf.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/protobuf.txt deleted file mode 100644 index 9cd4ba4..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/protobuf.txt +++ /dev/null @@ -1,43 +0,0 @@ -.. module:: firebird.base.protobuf - :synopsis: Registry for Google Protocol Buffer messages and enums - -################################################################# -protobuf - Registry for Google Protocol Buffer messages and enums -################################################################# - -Overview -======== - -This module provides central registry for Google Protocol Buffer messages and enums. -The generated `*_pb2.py` protobuf files could be registered using `register_decriptor` -or `load_registered` function. The registry could be then used to obtain information -about protobuf messages or enum types, or to create message instances or enum values. - -Constants -========= -.. autodata:: PROTO_EMPTY -.. autodata:: PROTO_ANY -.. autodata:: PROTO_DURATION -.. autodata:: PROTO_TIMESTAMP -.. autodata:: PROTO_STRUCT -.. autodata:: PROTO_VALUE -.. autodata:: PROTO_LISTVALUE -.. autodata:: PROTO_FIELDMASK - -Functions -========= -.. autofunction:: register_decriptor -.. autofunction:: load_registered -.. autofunction:: is_msg_registered -.. autofunction:: is_enum_registered -.. autofunction:: get_enum_type -.. autofunction:: get_enum_value_name -.. autofunction:: create_message -.. autofunction:: get_enum_field_type -.. autofunction:: struct2dict -.. autofunction:: dict2struct - -Data classes -============ -.. autoclass:: ProtoMessageType -.. autoclass:: ProtoEnumType diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/signal.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/signal.txt deleted file mode 100644 index ecc3035..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/signal.txt +++ /dev/null @@ -1,190 +0,0 @@ -.. module:: firebird.base.signal - :synopsis: Callback system based on Signals and Slots, and "Delphi events" - -######################################################################## -signal - Callback system based on Signals and Slots, and "Delphi events" -######################################################################## - -Overview -======== - -This module provides two callback mechanisms: one based on signals and slots similar to Qt -signal/slot, and second based on optional method delegation similar to events in Delphi. - -In both cases, the callback callables could be functions, instance or class methods, -partials and lambda functions. The `inspect` module is used to define the signature for -callbacks, and to validate that only compatible callables are assigned. - -.. important:: - - All type annotations in signatures are significant, so callbacks must have exactly the - same annotations as signatures used by signals or events. The sole exception are excess - keyword arguments with default values defined on connected callable. - -.. tip:: - - You may use `functools.partial` to adapt callable with different signatures. However, - you can "mask" only keyword arguments (without default) and leading positional arguments - (as any positional argument binded by name will not mask-out parameter from signature - introspection). - -Signals and Slots ------------------ - -Signals and slots are suitable for 1:N notification schemes. The `Signal` works as a point -to which one or more Slots could be connected. When `Signal` is "emitted", all connected -slots are called (executed). It's possible to pass parameters to slot callables, but any -value returned by slot callable is ignored. The Signal contructor takes `inspect.Signature` -argument that defines the required signature that callables (slots) must have to connect -to this signal. - -This mechanism is provided in two forms: - -- The `Signal` class to create signal instances for direct use. -- The `signal` decorator to define signals on classes. This decorator works like builtin - `property` (without setter and deleter), where the 'getter' method is used only to define - the signature required for slots. - -**Example:** - -.. code-block:: - - class Emitor: - def __init__(self, name: str): - self.name = name - def showtime(self): - self.signal_a(self, 'They Live!', 42) - @signal - def signal_a(self, source: Emitor, msg: str, value: int) -> None: - "Documentation for signal" - - class Receptor: - def __init__(self, name: str): - self.name = name - def on_signal_a(self, source: Emitor, msg: str, value: int) -> None: - print(f"{self.name} received signal from {source.name} ({msg=}, {value=})") - @classmethod - def cls_on_signal_a(cls, source: Emitor, msg: str, value: int) -> None: - print(f"{cls.__name__} received signal from {source.name} ({msg=}, {value=})") - - def on_signal_a(source: Emitor, msg: str, value: int): - print(f"Function 'on_signal_a' received signal from {source.name} ({msg=}, {value=})") - - e1 = Emitor('e1') - e2 = Emitor('e2') - r1 = Receptor('r1') - r2 = Receptor('r2') - # - e1.signal_a.connect(r1.on_signal_a) - e1.signal_a.connect(r2.on_signal_a) - e1.signal_a.connect(r1.cls_on_signal_a) - e2.signal_a.connect(on_signal_a) - e2.signal_a.connect(r2.on_signal_a) - # - e1.showtime() - e2.showtime() - -| - -**Output from sample code**:: - - r1 received signal from e1 (msg='They Live!', value=42) - r2 received signal from e1 (msg='They Live!', value=42) - Receptor received signal from e1 (msg='They Live!', value=42) - Function 'on_signal_a' received signal from e2 (msg='They Live!', value=42) - r2 received signal from e2 (msg='They Live!', value=42) - - -Events ------- - -Events are suitable for optional callbacks that delegate some functionality to other class -or function. - -The 'event' works as a point to which one 'slot' could be connected. The event itself -acts as callable, that executes the connected slot (if assigned). Events may have parameters -and return values. Events could be defined only on classes using `eventsocket` decorator, -that works like builtin `property` (without deleter), where the 'getter' method is used only -to define the signature required for slot, and 'setter' is used to assign the callable. -To disconnect the callable from event, simply assign None to the event. - -**Example:** - -.. code-block:: - - class Component: - def __init__(self, name: str): - self.name = name - @eventsocket - def on_init(self, source: Component, arg: str) -> bool: - "Documentation for event" - @eventsocket - def on_exit(self, source: Component) -> None: - "Documentation for event" - def showtime(self) -> None: - print(f"{self.name}.on_init handler is {'SET' if self.on_init.is_set() else 'NOT SET'}") - print(f"{self.name}.on_exit handler is {'SET' if self.on_exit.is_set() else 'NOT SET'}") - print("Event handler returned", self.on_init(self, 'argument')) - print(f"{self.name} does something...") - self.on_exit(self) - - class Container: - def __init__(self): - self.c1 = Component('C1') - self.c1.on_init = self.event_init - self.c2 = Component('C2') - self.c2.on_init = self.event_init - self.c2.on_exit = self.event_exit - self.c3 = Component('C3') - self.c3.on_exit = self.event_exit - def event_init(self, source: Component, arg: str) -> bool: - print(f"Handlig {source.name}.on_init({arg=})") - return source is self.c2 - def event_exit(self, source: Component) -> None: - print(f"Handlig {source.name}.on_exit()") - def showtime(self) -> None: - self.c1.showtime() - self.c2.showtime() - self.c3.showtime() - - cn = Container() - cn.showtime() - -| - -**Output from sample code**:: - - C1.on_init handler is SET - C1.on_exit handler is NOT SET - Handlig C1.on_init(arg='argument') - Event handler returned False - C1 does something... - C2.on_init handler is SET - C2.on_exit handler is SET - Handlig C2.on_init(arg='argument') - Event handler returned True - C2 does something... - Handlig C2.on_exit() - C3.on_init handler is NOT SET - C3.on_exit handler is SET - Event handler returned None - C3 does something... - Handlig C3.on_exit() - -Classes -======= - -.. autoclass:: Signal - ------------- - -.. autoclass:: _EventSocket - -Decorators -========== - -.. autoclass:: signal - ------------ - -.. autoclass:: eventsocket diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/strconv.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/strconv.txt deleted file mode 100644 index 1eb7308..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/strconv.txt +++ /dev/null @@ -1,150 +0,0 @@ -.. module:: firebird.base.strconv - :synopsis: Data conversion from/to string - -######################################## -strconv - Data conversion from/to string -######################################## - -Overview -======== - -While Python types typically support conversion to string via builtin `str()` function -(and custom `__str__` methods), there is no symetric operation that converts string created -by `str()` back to typed value. This module provides support for such symetric conversion -from/to string for any data type. - -.. note:: - - Symetric string conversion is used by `~firebird.base.config` module, notably by - `~firebird.base.config.ListOption` and `~firebird.base.config.DataclassOption`. You can - extend the range of data types supported by these options by registering convertors - for required data types. - -Architecture ------------- - -Module maintains a global registry of convertors associated with a data type. These -convertor functions may support conversion for multiple data types, and must have signatures: - -.. code-block:: - - # Conversion to string - - def value2str(value: Any) -> str: - ... - - # Conversion from string - - def str2value(cls: Type, value: str) -> Any: - ... - -Convertors should raise `ValueError` when conversion fails. - -Convertors must be registered using `register_convertor()` function, or reassigned using -`update_convertor()`. - -There are two methods for use of registered convertors: - -1. By using functions `convert_to_str()` and `convert_from_str()`. These functions use - convertor that is registered for particular data type. If there is no such convertor, - they use first convertor registered for any base class. The lookup is performed in Method - Resolution Order. - - This method is preferred when you will work with various data types. -2. Using `get_convertor()` function to obtain registry entry with convertors. - - This method is preferred when you will work with single data type repeatedly. - -.. important:: - - The convertor registry lookup could be done either for a class, or class name. - - Lookup for a class is first performed for specified class. If there is no such entry, - all bases classes in Method Resolution Order are used for lookup, and the first entry - found is returned. - - Lookup for a class name could be performed only for a specified class. Because some types - could be converted using convertors registered for their base class, such lookup will - not find the required convertor entry. To circumvent this issue, it's necessary to - register a class for name lookup using `register_class()` function. The registry lookup - uses this class registry to use the actual type instead type name. - -Registered data types ---------------------- - -Module registers convertor functions for next data types: - -* `str` -* `int` -* `float` -* `complex` -* `bool`. Uses `TRUE_STR` and `FALSE_STR` list for conversion from string (the case is NOT - significant). Conversion to string always uses first item in these lists. -* `~decimal.Decimal` -* `~uuid.UUID` -* `.MIME` -* `.ZMQAddress` -* `~enum.Enum` and `~enum.Flag`. Supports conversion for all descendants of `Enum`, - `IntEnum`, `Flag` and `IntFlag`. - -.. tip:: - - Functions `any2str()` and `str2any()` could be used to register conversion for data - types that support symetric conversion via `__str__()` method and class constructor - (`__init__()` must accept one positional argument that could be a string and all other - arguments must be keyword arguments with default values). - - -Types for annotations -===================== - -.. autodata:: TConvertToStr -.. autodata:: TConvertFromStr - -Globals -======= - -.. autodata:: TRUE_STR -.. autodata:: FALSE_STR - -Functions -========= - -.. autofunction:: convert_to_str - ----------------- - -.. autofunction:: convert_from_str - ------------------- - -.. autofunction:: register_convertor - ----------------- - -.. autofunction:: update_convertor - --------------- - -.. autofunction:: register_class - -------------- - -.. autofunction:: has_convertor - -------------- - -.. autofunction:: get_convertor - -------- - -.. autofunction:: any2str - -------- - -.. autofunction:: str2any - -Dataclasses -=========== - -.. autoclass:: Convertor diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/trace.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/trace.txt deleted file mode 100644 index 4835f5c..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/trace.txt +++ /dev/null @@ -1,433 +0,0 @@ -.. module:: firebird.base.trace - :synopsis: Trace/audit for class instances - -####################################### -trace - Trace/audit for class instances -####################################### - -Overview -======== - -This module provides trace/audit logging for functions or object methods through context-based -logging provided by `.logging` module. - -The trace logging is performed by `traced` decorator. You can use this decorator directly, -or use `TracedMixin` class to automatically decorate methods of class instances on creation. -Each decorated callable could log messages before execution, after successful execution or -on failed execution (when unhandled execption is raised by callable). The trace decorator -can automatically add `agent` and `context` information, and include parameters passed to -callable, execution time, return value, information about raised exception etc. to log messages. - -The trace logging is managed by `TraceManager`, that allows dynamic configuration of traced -callables at runtime. - -Example -======= - -The following program is an example of small but complex enough code that you can use to experiment with code tracing options. The parts relevant to tracing are highlighted in the code by embedded comments. - -.. code-block:: python - - # test-trace.py - from __future__ import annotations - import logging - from time import monotonic - from decimal import Decimal - from enum import IntEnum, auto - from firebird.base.types import * - from firebird.base.logging import LogLevel, LoggingIdMixin, get_logger - from firebird.base.trace import TracedMixin, add_trace, trace_manager, TraceFlag, traced - - class Mood(IntEnum): - "Agent moods" - ANGRY = auto() - SAD = auto() - NEUTRAL = auto() - PLEASED = auto() - HAPPY = auto() - - class Person(LoggingIdMixin, TracedMixin): # LOGGING & TRACE - "Sample virtual human agent" - def __init__(self, name: str, mood: Mood=Mood.NEUTRAL): - self.name: str = name - self.mood: Mood = mood - self.partners: List[Person] = [] - # >>> LOGGING & TRACE - @property - def _logging_id_(self) -> str: - return f"{self.mood.name} {self.name}" - # <<< LOGGING & TRACE - def change_mood(self, offset: int) -> None: - result = self.mood + offset - if result < Mood.ANGRY: - self.mood = Mood.ANGRY - elif result > Mood.HAPPY: - self.mood = Mood.HAPPY - else: - self.mood = Mood(result) - def process(self, message: str) -> None: - msg = message.lower() - if msg == "what you are doing here": - self.change_mood(-1) - if 'awful' in msg: - self.change_mood(-1) - if ('nice' in msg) or ('wonderful' in msg) or ('pleased' in msg): - if self.mood != Mood.ANGRY: - self.change_mood(1) - if 'happy' in msg: - if self.mood != Mood.ANGRY: - self.change_mood(2) - if 'very nice' in msg: - if self.mood != Mood.ANGRY: - self.change_mood(1) - if 'get lost' in msg: - self.change_mood(-2) - if self.name.lower() in msg: - if self.mood == Mood.SAD: - self.change_mood(1) - if self.name.lower() not in msg: - if self.mood == Mood.NEUTRAL: - self.change_mood(-1) - def process_response(self, to: str, mood: Mood) -> None: - if to == 'greeting': - if self.mood == Mood.NEUTRAL: - if mood > Mood.NEUTRAL: - self.mood = Mood.PLEASED - elif mood == Mood.ANGRY: - self.mood = Mood.SAD - elif self.mood == Mood.SAD: - if mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif mood == Mood.HAPPY: - self.mood = Mood.ANGRY - elif self.mood == Mood.ANGRY and mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif to == 'chat': - if self.mood == Mood.SAD and mood > Mood.NEUTRAL: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.ANGRY and mood == Mood.SAD: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.PLEASED and mood == Mood.ANGRY: - self.mood = Mood.NEUTRAL - elif self.mood == Mood.HAPPY and mood == Mood.ANGRY: - self.mood = Mood.SAD - elif to == 'bye': - if self.mood == Mood.NEUTRAL: - if mood == Mood.ANGRY: - self.mood = Mood.ANGRY - elif mood > Mood.NEUTRAL: - self.mood = Mood.PLEASED - elif self.mood == Mood.HAPPY and mood == Mood.ANGRY: - self.mood = Mood.NEUTRAL - def meet(self, other: Person) -> None: - self.partners.append(other) - self.greeting(other) - def interact(self, other: Person, message: str) -> Mood: - print(f"[{other.name}] {message}") - # >>> LOGGING - get_logger(self, topic='Person').debug(f'Processing "{message}" from [{other.name}]') - # <<< LOGGING - self.process(message) - return self.mood - def greeting(self, other: Person) -> None: - if self.mood == Mood.NEUTRAL: - msg = f"Hi {other.name}, I'm {self.name}" - elif self.mood == Mood.ANGRY: - msg = "Hi" - elif self.mood == Mood.SAD: - msg = f"Hi {other.name}" - else: - msg = f"Hi {other.name}, I'm {self.name}. I'm {self.mood.name} to meet you." - self.process_response('greeting', other.interact(self, msg)) - def chat(self) -> None: - for other in self.partners: - if self.mood == Mood.ANGRY: - msg = "What you are doing here?" - elif self.mood == Mood.SAD: - msg = "The weather is awful today, don't you think?" - elif self.mood == Mood.NEUTRAL: - msg = "It's a fine day, don't you think?" - elif self.mood == Mood.PLEASED: - msg = "It's a very nice day, don't you think?" - else: - msg = "Today is a wonderful day!" - self.process_response('chat', other.interact(self, msg)) - def bye(self) -> str: - while self.partners: - other = self.partners.pop() - if self.mood == Mood.ANGRY: - msg = "Get lost!" - elif self.mood == Mood.SAD: - msg = "Bye" - elif self.mood == Mood.NEUTRAL: - msg = f"Bye, {other.name}." - elif self.mood == Mood.PLEASED: - msg = f"See you, {other.name}!" - else: - msg = f"Bye, {other.name}. Have a nice day!" - self.process_response('bye', other.interact(self, msg)) - if self.mood == Mood.ANGRY: - result = "I hate this meeting!" - elif self.mood == Mood.SAD: - result = "It was a waste of time!" - elif self.mood == Mood.NEUTRAL: - result = "It was OK." - elif self.mood == Mood.PLEASED: - result = "Nice meeting, I think." - else: - result = "What a wonderful meeting!" - return result - def __repr__(self) -> str: - return f"{self.name} [{self.mood.name}]" - - def meeting(name: str, persons: List[Person]): - "Simulation of virtual agents meeting" - - for person in persons: - person.log_context = name - - start = monotonic() - print("Meeting started...") - print(f"Attendees: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}") - - for person in persons: - for other in persons: - if other is not person: - person.meet(other) - - for person in persons: - person.chat() - - for person in persons: - person.bye() - - e = str(Decimal(monotonic() - start)) - print(f"Meeting closed in {e[:e.find('.')+6]} sec.") - print(f"Outcome: {', '.join(f'{x.name} [{x.mood.name}]' for x in persons)}") - - - def test_trace(name: str, first: Mood, second: Mood) -> None: - print(f"- without trace ----------") - meeting(name, [Person('Alex', first), Person('David', second)]) - - print(f"- trace ------------------") - # >>> TRACE - add_trace(Person, 'greeting', traced) - add_trace(Person, 'bye', traced) - add_trace(Person, 'chat', traced) - add_trace(Person, 'change_mood', traced) - add_trace(Person, 'process', traced, with_args=False) - add_trace(Person, 'process_response', traced) - # <<< TRACE - meeting(name, [Person('Alex', first), Person('David', second)]) - - if __name__ == '__main__': - # >>> LOGGING - logger = logging.getLogger() - logger.setLevel(LogLevel.NOTSET) - sh = logging.StreamHandler() - sh.setFormatter(logging.Formatter('%(levelname)-10s: [%(topic)s][%(agent)s][%(context)s] %(message)s')) - logger.addHandler(sh) - # <<< LOGGING - # >>> TRACE - trace_manager.trace |= (TraceFlag.FAIL | TraceFlag.BEFORE | TraceFlag.AFTER) - trace_manager.trace_active = True - # <<< TRACE - test_trace('TEST-1', Mood.SAD, Mood.PLEASED) - -| - -**Output from sample code**:: - - > python test-trace.py - - without trace ---------- - Meeting started... - Attendees: Alex [SAD], David [PLEASED] - [Alex] Hi David - DEBUG : [Person][PLEASED David][TEST-1] Processing "Hi David" from [Alex] - [David] Hi Alex, I'm David. I'm PLEASED to meet you. - DEBUG : [Person][SAD Alex][TEST-1] Processing "Hi Alex, I'm David. I'm PLEASED to meet you." from [David] - [Alex] It's a fine day, don't you think? - DEBUG : [Person][PLEASED David][TEST-1] Processing "It's a fine day, don't you think?" from [Alex] - [David] It's a very nice day, don't you think? - DEBUG : [Person][NEUTRAL Alex][TEST-1] Processing "It's a very nice day, don't you think?" from [David] - [Alex] Bye, David. Have a nice day! - DEBUG : [Person][PLEASED David][TEST-1] Processing "Bye, David. Have a nice day!" from [Alex] - [David] Bye, Alex. Have a nice day! - DEBUG : [Person][HAPPY Alex][TEST-1] Processing "Bye, Alex. Have a nice day!" from [David] - Meeting closed in 0.00071 sec. - Outcome: Alex [HAPPY], David [HAPPY] - - trace ------------------ - Meeting started... - Attendees: Alex [SAD], David [PLEASED] - DEBUG : [trace][SAD Alex][TEST-1] >>> greeting(other=David [PLEASED]) - [Alex] Hi David - DEBUG : [Person][PLEASED David][TEST-1] Processing "Hi David" from [Alex] - DEBUG : [trace][PLEASED David][TEST-1] >>> process - DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00002] - DEBUG : [trace][SAD Alex][TEST-1] >>> process_response(to='greeting', mood=) - DEBUG : [trace][SAD Alex][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][SAD Alex][TEST-1] <<< greeting[0.00050] - DEBUG : [trace][PLEASED David][TEST-1] >>> greeting(other=Alex [SAD]) - [David] Hi Alex, I'm David. I'm PLEASED to meet you. - DEBUG : [Person][SAD Alex][TEST-1] Processing "Hi Alex, I'm David. I'm PLEASED to meet you." from [David] - DEBUG : [trace][SAD Alex][TEST-1] >>> process - DEBUG : [trace][SAD Alex][TEST-1] >>> change_mood(offset=1) - DEBUG : [trace][SAD Alex][TEST-1] <<< change_mood[0.00000] - DEBUG : [trace][SAD Alex][TEST-1] <<< process[0.00018] - DEBUG : [trace][PLEASED David][TEST-1] >>> process_response(to='greeting', mood=) - DEBUG : [trace][PLEASED David][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][PLEASED David][TEST-1] <<< greeting[0.00061] - DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> chat() - [Alex] It's a fine day, don't you think? - DEBUG : [Person][PLEASED David][TEST-1] Processing "It's a fine day, don't you think?" from [Alex] - DEBUG : [trace][PLEASED David][TEST-1] >>> process - DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00000] - DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> process_response(to='chat', mood=) - DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< chat[0.00045] - DEBUG : [trace][PLEASED David][TEST-1] >>> chat() - [David] It's a very nice day, don't you think? - DEBUG : [Person][NEUTRAL Alex][TEST-1] Processing "It's a very nice day, don't you think?" from [David] - DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> process - DEBUG : [trace][NEUTRAL Alex][TEST-1] >>> change_mood(offset=1) - DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< change_mood[0.00000] - DEBUG : [trace][PLEASED Alex][TEST-1] >>> change_mood(offset=1) - DEBUG : [trace][PLEASED Alex][TEST-1] <<< change_mood[0.00000] - DEBUG : [trace][NEUTRAL Alex][TEST-1] <<< process[0.00035] - DEBUG : [trace][PLEASED David][TEST-1] >>> process_response(to='chat', mood=) - DEBUG : [trace][PLEASED David][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][PLEASED David][TEST-1] <<< chat[0.00077] - DEBUG : [trace][HAPPY Alex][TEST-1] >>> bye() - [Alex] Bye, David. Have a nice day! - DEBUG : [Person][PLEASED David][TEST-1] Processing "Bye, David. Have a nice day!" from [Alex] - DEBUG : [trace][PLEASED David][TEST-1] >>> process - DEBUG : [trace][PLEASED David][TEST-1] >>> change_mood(offset=1) - DEBUG : [trace][PLEASED David][TEST-1] <<< change_mood[0.00000] - DEBUG : [trace][PLEASED David][TEST-1] <<< process[0.00017] - DEBUG : [trace][HAPPY Alex][TEST-1] >>> process_response(to='bye', mood=) - DEBUG : [trace][HAPPY Alex][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][HAPPY Alex][TEST-1] <<< bye[0.00060] Result: What a wonderful meeting! - DEBUG : [trace][HAPPY David][TEST-1] >>> bye() - [David] Bye, Alex. Have a nice day! - DEBUG : [Person][HAPPY Alex][TEST-1] Processing "Bye, Alex. Have a nice day!" from [David] - DEBUG : [trace][HAPPY Alex][TEST-1] >>> process - DEBUG : [trace][HAPPY Alex][TEST-1] >>> change_mood(offset=1) - DEBUG : [trace][HAPPY Alex][TEST-1] <<< change_mood[0.00000] - DEBUG : [trace][HAPPY Alex][TEST-1] <<< process[0.00018] - DEBUG : [trace][HAPPY David][TEST-1] >>> process_response(to='bye', mood=) - DEBUG : [trace][HAPPY David][TEST-1] <<< process_response[0.00000] - DEBUG : [trace][HAPPY David][TEST-1] <<< bye[0.00059] Result: What a wonderful meeting! - Meeting closed in 0.00466 sec. - Outcome: Alex [HAPPY], David [HAPPY] - -Trace configuration -=================== - -.. versionadded:: 1.1.0 - -Trace supports configuration based on `~firebird.base.config`. - -**Sample configuration file**:: - - [trace] - flags = ACTIVE | FAIL - ;flags = ACTIVE | BEFORE | AFTER | FAIL - classes = trace_ChannelManager, trace_Channel, trace_TextIOServiceImpl, trace_PipeServerHandler - - [trace_PipeServerHandler] - source = saturnin.core.protocol.fbdp.PipeServerHandler - methods = close, send_ready, send_close - - [trace_ChannelManager] - source = saturnin.core.base.ChannelManager - special = trace_defer - - [trace_Channel] - source = saturnin.core.base.Channel - methods = send, receive, close, bind, unbind, connect, disconnect - - [trace_DealerChannel] - source = saturnin.core.base.DealerChannel - methods = send, receive, close, bind, unbind, connect, disconnect - - [trace_SimpleService] - source = saturnin.core.classic.SimpleService - methods = validate, run, initialize, start - with_args = no - - [trace_TextIOServiceImpl] - source = saturnin.sdk.micro.textio.service.TextIOServiceImpl - methods = initialize, configure, validate, finalize - with_args = no - - [trace_defer] - method = defer - max_param_length = 50 - - -.. seealso:: - - `~TraceManager.load_config()`, `~firebird.base.trace.BaseTraceConfig`, - `~firebird.base.trace.TracedMethodConfig`, `~firebird.base.trace.TracedClassConfig` and - `~firebird.base.trace.TraceConfig`. - -Enums & Flags -============= - -.. autoclass:: TraceFlag - -Functions -========= - -.. autofunction:: add_trace - ------------- - -.. autofunction:: remove_trace - ------------- - -.. autofunction:: trace_object - -Trace manager -============= - -.. autoclass:: TraceManager - -Trace/audit decorator -===================== - -.. autoclass:: traced - -Mixins -====== - -.. autoclass:: TracedMixin - -Globals -======= - -.. autodata:: trace_manager - :no-value: - -Trace configuration classes -=========================== - -.. autoclass:: BaseTraceConfig - ------------------- - -.. autoclass:: TracedMethodConfig - :no-inherited-members: - ------------------ - -.. autoclass:: TracedClassConfig - :no-inherited-members: - ------------ - -.. autoclass:: TraceConfig - :no-inherited-members: - diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/types.txt b/docs/firebird-base.docset/Contents/Resources/Documents/_sources/types.txt deleted file mode 100644 index dbf65ed..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_sources/types.txt +++ /dev/null @@ -1,177 +0,0 @@ -.. module:: firebird.base.types - :synopsis: Common data types - -######################### -types - Common data types -######################### - -Overview -======== - -This module provides collection of classes that are often used by other library modules or -applications. - -Exceptions -========== - -.. autoexception:: Error - :show-inheritance: - :no-inherited-members: - -Singletons -========== - -Singleton is a pattern that restricts the instantiation of a class to one "single" instance. -This is useful when exactly one object is needed to coordinate actions across the system. - -Common uses: - -- The abstract factory, factory method, builder, and prototype patterns can use singletons - in their implementation. -- Facade objects are often singletons because only one facade object is required. -- State objects are often singletons. -- Singletons are often preferred to global variables because: - - - They do not pollute the global namespace with unnecessary variables. - - They permit lazy allocation and initialization. - -To create your own singletons, use `Singleton` as the base class. - -.. admonition:: example - - >>> class MySingleton(Singleton): - ... "Description" - ... ... - ... - >>> obj1 = MySingleton() - >>> obj1 = MySingleton() - >>> obj1 is obj2 - True - -.. autoclass:: Singleton - -Sentinels -========= - -The Sentinel Object pattern is a standard Pythonic approach that’s used both in the -Standard Library and beyond. The pattern most often uses Python’s built-in `None` object, -but in situations where None might be a useful value, a unique sentinel `object()` can be -used instead to indicate missing or unspecified data, or other specific condition. - -However, the plain `object()` sentinel has not very useful `str` and `repr` values. -The `Sentinel` class provides named sentinels, with meaningful `str` and `repr`. - --------- - -.. autoclass:: Sentinel - -Predefined sentinels --------------------- - -.. autodata:: DEFAULT -.. autodata:: INFINITY -.. autodata:: UNLIMITED -.. autodata:: UNKNOWN -.. autodata:: NOT_FOUND -.. autodata:: UNDEFINED -.. autodata:: ANY -.. autodata:: ALL -.. autodata:: SUSPEND -.. autodata:: RESUME -.. autodata:: STOP - -Distinct objects -================ - -Some complex data structures or data processing algorithms require unique object -identification (ie object identity). In Python, an object identity is defined internally -as unique instance identity that is not suitable for complex objects whose identity is -derived from content. - -The `Distinct` abstract base class is intended as a unified solution to these needs. - -.. seealso:: module `firebird.base.collections` - - --------- - -.. autoclass:: Distinct - --------------- - -.. autoclass:: CachedDistinct - -Enums -===== - -.. autoclass:: ByteOrder - ------------- - -.. autoclass:: ZMQTransport - ---------- - -.. autoclass:: ZMQDomain - -Custom string types -=================== - -Some string values have unified structure and carry specific information (like network -address or database connection string). Typical repeating operation with these values -are validation and parsing. It makes sense to put these operations under one roof. -One such approach uses custom descendants of builtin `str` type. - -.. caution:: - - Custom string types have an inherent weakness. They support all inherited string methods, - but any method that returns string value return a base `str` type, not the decendant class - type. That same apply when you assign strings to variables that should be of custom - string type. - - .. tip:: - - Module `~firebird.base.strconv` could help you to safely translate strings stored - externally to typed strings. - --------------- - -.. autoclass:: ZMQAddress - ------- - -.. autoclass:: MIME - ------- - -.. autoclass:: PyExpr - ------- - -.. autoclass:: PyCode - ----------- - -.. autoclass:: PyCallable - -Meta classes -============ - -.. autoclass:: SingletonMeta - ------------- - -.. autoclass:: SentinelMeta - ------------------- - -.. autoclass:: CachedDistinctMeta - ------------ - -.. autofunction:: Conjunctive - -Functions -========= - -.. autofunction:: load diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/_sphinx_javascript_frameworks_compat.js b/docs/firebird-base.docset/Contents/Resources/Documents/_static/_sphinx_javascript_frameworks_compat.js deleted file mode 100644 index 8549469..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/_sphinx_javascript_frameworks_compat.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - * _sphinx_javascript_frameworks_compat.js - * ~~~~~~~~~~ - * - * Compatability shim for jQuery and underscores.js. - * - * WILL BE REMOVED IN Sphinx 6.0 - * xref RemovedInSphinx60Warning - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - - -/** - * small helper function to urldecode strings - * - * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL - */ -jQuery.urldecode = function(x) { - if (!x) { - return x - } - return decodeURIComponent(x.replace(/\+/g, ' ')); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && - !jQuery(node.parentNode).hasClass(className) && - !jQuery(node.parentNode).hasClass("nohighlight")) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - var bbox = node.parentElement.getBBox(); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this, addItems); - }); - } - } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); - }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/basic.css b/docs/firebird-base.docset/Contents/Resources/Documents/_static/basic.css deleted file mode 100644 index 20b93ce..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/basic.css +++ /dev/null @@ -1,703 +0,0 @@ -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: 450px; - max-width: 1920px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -div.code-block-caption { - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; - border-style: none; - padding: 0; -} - -code.descclassname { - background-color: transparent; - border-style: none; - padding: 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; - border-style: none; - padding: 0; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: relative; - left: 0px; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} - -/* -- My additions ---------------------------------------------------------- */ - -div.note { - color: black; - border: 2px solid #7a9eec; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 0px 60px; - background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px; -} - -div.danger { - color: black; - border: 2px solid #fbc2c4; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 0px 60px; - background: #fbe3e4 url(dialog-note.png) no-repeat 10px 8px; -} - -div.attention { - color: black; - border: 2px solid #ffd324; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 0px 60px; - background: #fff6bf url(dialog-note.png) no-repeat 10px 8px; -} - -div.caution { - color: black; - border: 2px solid #ffd324; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 0px 60px; - background: #fff6bf url(dialog-warning.png) no-repeat 10px 8px; -} - -div.important { - color: black; - background: #fbe3e4 url(dialog-seealso.png) no-repeat 10px 8px; - border: 2px solid #fbc2c4; - border-left-style: none; - border-right-style: none; - padding: 10px 20px 0px 60px; -} - -div.seealso { - color: black; - background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px; - border: 2px solid #ffd324; - border-left-style: none; - border-right-style: none; - padding: 10px 20px 0px 60px; -} - -div.hint, div.tip { - color: black; - background: #eeffcc url(dialog-topic.png) no-repeat 10px 8px; - border: 2px solid #aacc99; - border-left-style: none; - border-right-style: none; - padding: 10px 20px 0px 60px; -} - -div.admonition-example { - color: black; - background: white url(dialog-topic.png) no-repeat 10px 8px; - border: 2px solid #aacc99; - border-left-style: none; - border-right-style: none; - padding: 10px 0px 20px 60px; -} -div.warning, div.error { - color: black; - background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px; - border: 2px solid #fbc2c4; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 0px 60px; -} - -p { - text-align: justify; - padding-bottom: 5px; -} - -h1 { - background: #fff6bf; - border: 2px solid #ffd324; - border-left-style: none; - border-right-style: none; - padding: 10px 10px 10px 10px; - text-align: center; -} - -h2 { - /* background: #eeffcc; */ - border: 2px solid #aacc99; - border-left-style: none; - border-right-style: none; - border-top-style: none; - padding: 10px 0px 0px 0px; - /* text-align: center; */ -} - -h3 { - /* background: #eeffcc; */ - border: 1px solid #7a9eec; - border-left-style: none; - border-right-style: none; - border-top-style: none; - padding: 0; - /* text-align: center; */ -} - -h4 { - background: #eeffcc; - /* border: 1px solid #aacc99; */ - border-left-style: none; - border-right-style: none; - border-top-style: none; - padding: 5px 5px 5px 5px; - /* text-align: center; */ -} - -cite { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - border: 1px solid #e1e1e8; - background: #f7f7f9; - margin: 0 0 10px; - padding: 0 5px 0 5px; - font-size: 13px; - font-style: italic; -} - -.program { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - border: 1px solid #e1e1e8; - background: #f7f7f9; - margin: 0 0 10px; - padding: 0 5px 0 5px; - font-size: 13px; -} - -/* dt/dd on single line */ - -dl.field-list { - display: grid; - grid-template-columns: max-content auto; -} - -dt.field-list { - grid-column-start: 1; -} - -dt.field-odd:after { - content: ':'; -} - -dt.field-even:after { - content: ':'; -} - -dd.field-list { - grid-column-start: 2; -} - -hr.docutils { - font-weight: bold; -/* border: 2px solid #7a9eec; */ - border: 2px solid grey; - border-left-style: none; - border-right-style: none; - border-top-style: none; -} - -div.versionadded { - color: black; -/* padding: 10px 0 0 10px; */ - font-weight: bold; - margin: 5px 0; -} - -div.versionchanged { - color: black; -/* padding: 0 10px 0 0; */ - font-weight: bold; - margin: 5px 0; -} - -span.added { - background: #eeffcc ; - border: 2px solid #aacc99; - border-left-style: none; - border-right-style: none; - padding: 5px; -} - -span.changed { - background: #fbe3e4 ; - border: 2px solid #fbc2c4; - border-left-style: none; - border-right-style: none; - padding: 5px; -} - -dl.class, dl.exception, dl.data, dl.function { -/* background: #fbe3e4 ;*/ - border: 1px solid grey; - border-top-style: none; - border-left-style: none; - border-right-style: none; -/* padding: 3px;*/ -} - -dt.py { - background: #f8f8f8; -/* border: 2px solid #aacc99;*/ -/* border: 2px solid #ffcccc; /*#ffd324;*/ -/* border: 2px solid #fbc2c4;*/ - border: 1px solid #e1e1e8; - border-top-style: none; - border-left-style: none; -/* border-right-style: none; */ - padding: 2px 5px; -} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.css b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.css deleted file mode 100644 index 09e88ce..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.css +++ /dev/null @@ -1,1109 +0,0 @@ -/*! - * Bootstrap Responsive v2.3.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -.clearfix { - *zoom: 1; -} - -.clearfix:before, -.clearfix:after { - display: table; - line-height: 0; - content: ""; -} - -.clearfix:after { - clear: both; -} - -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.input-block-level { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -@-ms-viewport { - width: device-width; -} - -.hidden { - display: none; - visibility: hidden; -} - -.visible-phone { - display: none !important; -} - -.visible-tablet { - display: none !important; -} - -.hidden-desktop { - display: none !important; -} - -.visible-desktop { - display: inherit !important; -} - -@media (min-width: 768px) and (max-width: 979px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important ; - } - .visible-tablet { - display: inherit !important; - } - .hidden-tablet { - display: none !important; - } -} - -@media (max-width: 767px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-phone { - display: inherit !important; - } - .hidden-phone { - display: none !important; - } -} - -.visible-print { - display: none !important; -} - -@media print { - .visible-print { - display: inherit !important; - } - .hidden-print { - display: none !important; - } -} - -@media (min-width: 1200px) { - .row { - margin-left: -30px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - line-height: 0; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 30px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 1170px; - } - .span12 { - width: 1170px; - } - .span11 { - width: 1070px; - } - .span10 { - width: 970px; - } - .span9 { - width: 870px; - } - .span8 { - width: 770px; - } - .span7 { - width: 670px; - } - .span6 { - width: 570px; - } - .span5 { - width: 470px; - } - .span4 { - width: 370px; - } - .span3 { - width: 270px; - } - .span2 { - width: 170px; - } - .span1 { - width: 70px; - } - .offset12 { - margin-left: 1230px; - } - .offset11 { - margin-left: 1130px; - } - .offset10 { - margin-left: 1030px; - } - .offset9 { - margin-left: 930px; - } - .offset8 { - margin-left: 830px; - } - .offset7 { - margin-left: 730px; - } - .offset6 { - margin-left: 630px; - } - .offset5 { - margin-left: 530px; - } - .offset4 { - margin-left: 430px; - } - .offset3 { - margin-left: 330px; - } - .offset2 { - margin-left: 230px; - } - .offset1 { - margin-left: 130px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - line-height: 0; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 30px; - margin-left: 2.564102564102564%; - *margin-left: 2.5109110747408616%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.564102564102564%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; - } - .row-fluid .span11 { - width: 91.45299145299145%; - *width: 91.39979996362975%; - } - .row-fluid .span10 { - width: 82.90598290598291%; - *width: 82.8527914166212%; - } - .row-fluid .span9 { - width: 74.35897435897436%; - *width: 74.30578286961266%; - } - .row-fluid .span8 { - width: 65.81196581196582%; - *width: 65.75877432260411%; - } - .row-fluid .span7 { - width: 57.26495726495726%; - *width: 57.21176577559556%; - } - .row-fluid .span6 { - width: 48.717948717948715%; - *width: 48.664757228587014%; - } - .row-fluid .span5 { - width: 40.17094017094017%; - *width: 40.11774868157847%; - } - .row-fluid .span4 { - width: 31.623931623931625%; - *width: 31.570740134569924%; - } - .row-fluid .span3 { - width: 23.076923076923077%; - *width: 23.023731587561375%; - } - .row-fluid .span2 { - width: 14.52991452991453%; - *width: 14.476723040552828%; - } - .row-fluid .span1 { - width: 5.982905982905983%; - *width: 5.929714493544281%; - } - .row-fluid .offset12 { - margin-left: 105.12820512820512%; - *margin-left: 105.02182214948171%; - } - .row-fluid .offset12:first-child { - margin-left: 102.56410256410257%; - *margin-left: 102.45771958537915%; - } - .row-fluid .offset11 { - margin-left: 96.58119658119658%; - *margin-left: 96.47481360247316%; - } - .row-fluid .offset11:first-child { - margin-left: 94.01709401709402%; - *margin-left: 93.91071103837061%; - } - .row-fluid .offset10 { - margin-left: 88.03418803418803%; - *margin-left: 87.92780505546462%; - } - .row-fluid .offset10:first-child { - margin-left: 85.47008547008548%; - *margin-left: 85.36370249136206%; - } - .row-fluid .offset9 { - margin-left: 79.48717948717949%; - *margin-left: 79.38079650845607%; - } - .row-fluid .offset9:first-child { - margin-left: 76.92307692307693%; - *margin-left: 76.81669394435352%; - } - .row-fluid .offset8 { - margin-left: 70.94017094017094%; - *margin-left: 70.83378796144753%; - } - .row-fluid .offset8:first-child { - margin-left: 68.37606837606839%; - *margin-left: 68.26968539734497%; - } - .row-fluid .offset7 { - margin-left: 62.393162393162385%; - *margin-left: 62.28677941443899%; - } - .row-fluid .offset7:first-child { - margin-left: 59.82905982905982%; - *margin-left: 59.72267685033642%; - } - .row-fluid .offset6 { - margin-left: 53.84615384615384%; - *margin-left: 53.739770867430444%; - } - .row-fluid .offset6:first-child { - margin-left: 51.28205128205128%; - *margin-left: 51.175668303327875%; - } - .row-fluid .offset5 { - margin-left: 45.299145299145295%; - *margin-left: 45.1927623204219%; - } - .row-fluid .offset5:first-child { - margin-left: 42.73504273504273%; - *margin-left: 42.62865975631933%; - } - .row-fluid .offset4 { - margin-left: 36.75213675213675%; - *margin-left: 36.645753773413354%; - } - .row-fluid .offset4:first-child { - margin-left: 34.18803418803419%; - *margin-left: 34.081651209310785%; - } - .row-fluid .offset3 { - margin-left: 28.205128205128204%; - *margin-left: 28.0987452264048%; - } - .row-fluid .offset3:first-child { - margin-left: 25.641025641025642%; - *margin-left: 25.53464266230224%; - } - .row-fluid .offset2 { - margin-left: 19.65811965811966%; - *margin-left: 19.551736679396257%; - } - .row-fluid .offset2:first-child { - margin-left: 17.094017094017094%; - *margin-left: 16.98763411529369%; - } - .row-fluid .offset1 { - margin-left: 11.11111111111111%; - *margin-left: 11.004728132387708%; - } - .row-fluid .offset1:first-child { - margin-left: 8.547008547008547%; - *margin-left: 8.440625568285142%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 30px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 1156px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 1056px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 956px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 856px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 756px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 656px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 556px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 456px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 356px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 256px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 156px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 56px; - } - .thumbnails { - margin-left: -30px; - } - .thumbnails > li { - margin-left: 30px; - } - .row-fluid .thumbnails { - margin-left: 0; - } -} - -@media (min-width: 768px) and (max-width: 979px) { - .row { - margin-left: -20px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - line-height: 0; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 724px; - } - .span12 { - width: 724px; - } - .span11 { - width: 662px; - } - .span10 { - width: 600px; - } - .span9 { - width: 538px; - } - .span8 { - width: 476px; - } - .span7 { - width: 414px; - } - .span6 { - width: 352px; - } - .span5 { - width: 290px; - } - .span4 { - width: 228px; - } - .span3 { - width: 166px; - } - .span2 { - width: 104px; - } - .span1 { - width: 42px; - } - .offset12 { - margin-left: 764px; - } - .offset11 { - margin-left: 702px; - } - .offset10 { - margin-left: 640px; - } - .offset9 { - margin-left: 578px; - } - .offset8 { - margin-left: 516px; - } - .offset7 { - margin-left: 454px; - } - .offset6 { - margin-left: 392px; - } - .offset5 { - margin-left: 330px; - } - .offset4 { - margin-left: 268px; - } - .offset3 { - margin-left: 206px; - } - .offset2 { - margin-left: 144px; - } - .offset1 { - margin-left: 82px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - line-height: 0; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 30px; - margin-left: 2.7624309392265194%; - *margin-left: 2.709239449864817%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.7624309392265194%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; - } - .row-fluid .span11 { - width: 91.43646408839778%; - *width: 91.38327259903608%; - } - .row-fluid .span10 { - width: 82.87292817679558%; - *width: 82.81973668743387%; - } - .row-fluid .span9 { - width: 74.30939226519337%; - *width: 74.25620077583166%; - } - .row-fluid .span8 { - width: 65.74585635359117%; - *width: 65.69266486422946%; - } - .row-fluid .span7 { - width: 57.18232044198895%; - *width: 57.12912895262725%; - } - .row-fluid .span6 { - width: 48.61878453038674%; - *width: 48.56559304102504%; - } - .row-fluid .span5 { - width: 40.05524861878453%; - *width: 40.00205712942283%; - } - .row-fluid .span4 { - width: 31.491712707182323%; - *width: 31.43852121782062%; - } - .row-fluid .span3 { - width: 22.92817679558011%; - *width: 22.87498530621841%; - } - .row-fluid .span2 { - width: 14.3646408839779%; - *width: 14.311449394616199%; - } - .row-fluid .span1 { - width: 5.801104972375691%; - *width: 5.747913483013988%; - } - .row-fluid .offset12 { - margin-left: 105.52486187845304%; - *margin-left: 105.41847889972962%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243093922652%; - *margin-left: 102.6560479605031%; - } - .row-fluid .offset11 { - margin-left: 96.96132596685082%; - *margin-left: 96.8549429881274%; - } - .row-fluid .offset11:first-child { - margin-left: 94.1988950276243%; - *margin-left: 94.09251204890089%; - } - .row-fluid .offset10 { - margin-left: 88.39779005524862%; - *margin-left: 88.2914070765252%; - } - .row-fluid .offset10:first-child { - margin-left: 85.6353591160221%; - *margin-left: 85.52897613729868%; - } - .row-fluid .offset9 { - margin-left: 79.8342541436464%; - *margin-left: 79.72787116492299%; - } - .row-fluid .offset9:first-child { - margin-left: 77.07182320441989%; - *margin-left: 76.96544022569647%; - } - .row-fluid .offset8 { - margin-left: 71.2707182320442%; - *margin-left: 71.16433525332079%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729281768%; - *margin-left: 68.40190431409427%; - } - .row-fluid .offset7 { - margin-left: 62.70718232044199%; - *margin-left: 62.600799341718584%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138121547%; - *margin-left: 59.838368402492065%; - } - .row-fluid .offset6 { - margin-left: 54.14364640883978%; - *margin-left: 54.037263430116376%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121546961326%; - *margin-left: 51.27483249088986%; - } - .row-fluid .offset5 { - margin-left: 45.58011049723757%; - *margin-left: 45.47372751851417%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767955801105%; - *margin-left: 42.71129657928765%; - } - .row-fluid .offset4 { - margin-left: 37.01657458563536%; - *margin-left: 36.91019160691196%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414364640884%; - *margin-left: 34.14776066768544%; - } - .row-fluid .offset3 { - margin-left: 28.45303867403315%; - *margin-left: 28.346655695309746%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773480663%; - *margin-left: 25.584224756083227%; - } - .row-fluid .offset2 { - margin-left: 19.88950276243094%; - *margin-left: 19.783119783707537%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182320442%; - *margin-left: 17.02068884448102%; - } - .row-fluid .offset1 { - margin-left: 11.32596685082873%; - *margin-left: 11.219583872105325%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591160221%; - *margin-left: 8.457152932878806%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 710px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 648px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 586px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 524px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 462px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 400px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 338px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 276px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 214px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 152px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 90px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 28px; - } -} - -@media (max-width: 767px) { - body { - padding-right: 20px; - padding-left: 20px; - } - .navbar-fixed-top, - .navbar-fixed-bottom, - .navbar-static-top { - margin-right: -20px; - margin-left: -20px; - } - .container-fluid { - padding: 0; - } - .dl-horizontal dt { - float: none; - width: auto; - clear: none; - text-align: left; - } - .dl-horizontal dd { - margin-left: 0; - } - .container { - width: auto; - } - .row-fluid { - width: 100%; - } - .row, - .thumbnails { - margin-left: 0; - } - .thumbnails > li { - float: none; - margin-left: 0; - } - [class*="span"], - .uneditable-input[class*="span"], - .row-fluid [class*="span"] { - display: block; - float: none; - width: 100%; - margin-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .span12, - .row-fluid .span12 { - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="offset"]:first-child { - margin-left: 0; - } - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; - width: auto; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 0; - } - .modal { - position: fixed; - top: 20px; - right: 20px; - left: 20px; - width: auto; - margin: 0; - } - .modal.fade { - top: -100px; - } - .modal.fade.in { - top: 20px; - } -} - -@media (max-width: 480px) { - .nav-collapse { - -webkit-transform: translate3d(0, 0, 0); - } - .page-header h1 small { - display: block; - line-height: 20px; - } - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - .form-horizontal .control-label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - .form-horizontal .controls { - margin-left: 0; - } - .form-horizontal .control-list { - padding-top: 0; - } - .form-horizontal .form-actions { - padding-right: 10px; - padding-left: 10px; - } - .media .pull-left, - .media .pull-right { - display: block; - float: none; - margin-bottom: 10px; - } - .media-object { - margin-right: 0; - margin-left: 0; - } - .modal { - top: 10px; - right: 10px; - left: 10px; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - .carousel-caption { - position: static; - } -} - -@media (max-width: 979px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 20px; - } - .navbar-fixed-bottom { - margin-top: 20px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-right: 10px; - padding-left: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 10px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #777777; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: #777777; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - background-color: #f2f2f2; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: #999999; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - background-color: #111111; - } - .nav-collapse.in .btn-group { - padding: 0; - margin-top: 5px; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - display: none; - float: none; - max-width: none; - padding: 0; - margin: 0 15px; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu:before, - .nav-collapse .nav > li > .dropdown-menu:after { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 10px 15px; - margin: 10px 0; - border-top: 1px solid #f2f2f2; - border-bottom: 1px solid #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: #111111; - border-bottom-color: #111111; - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - height: 0; - overflow: hidden; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-right: 10px; - padding-left: 10px; - } -} - -@media (min-width: 980px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css deleted file mode 100644 index f4ede63..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap-responsive.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap Responsive v2.3.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.css b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.css deleted file mode 100644 index b725064..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.css +++ /dev/null @@ -1,6167 +0,0 @@ -/*! - * Bootstrap v2.3.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -.clearfix { - *zoom: 1; -} - -.clearfix:before, -.clearfix:after { - display: table; - line-height: 0; - content: ""; -} - -.clearfix:after { - clear: both; -} - -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.input-block-level { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} - -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} - -audio:not([controls]) { - display: none; -} - -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -a:hover, -a:active { - outline: 0; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - width: auto\9; - height: auto; - max-width: 100%; - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} - -#map_canvas img, -.google-maps img { - max-width: none; -} - -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; -} - -button, -input { - *overflow: visible; - line-height: normal; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; -} - -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} - -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -@media print { - * { - color: #000 !important; - text-shadow: none !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 0.5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } -} - -body { - margin: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 20px; - color: #333333; - background-color: #ffffff; -} - -a { - color: #0088cc; - text-decoration: none; -} - -a:hover, -a:focus { - color: #005580; - text-decoration: underline; -} - -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.img-polaroid { - padding: 4px; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -.img-circle { - -webkit-border-radius: 500px; - -moz-border-radius: 500px; - border-radius: 500px; -} - -.row { - margin-left: -20px; - *zoom: 1; -} - -.row:before, -.row:after { - display: table; - line-height: 0; - content: ""; -} - -.row:after { - clear: both; -} - -[class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; -} - -.container, -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} - -.span12 { - width: 940px; -} - -.span11 { - width: 860px; -} - -.span10 { - width: 780px; -} - -.span9 { - width: 700px; -} - -.span8 { - width: 620px; -} - -.span7 { - width: 540px; -} - -.span6 { - width: 460px; -} - -.span5 { - width: 380px; -} - -.span4 { - width: 300px; -} - -.span3 { - width: 220px; -} - -.span2 { - width: 140px; -} - -.span1 { - width: 60px; -} - -.offset12 { - margin-left: 980px; -} - -.offset11 { - margin-left: 900px; -} - -.offset10 { - margin-left: 820px; -} - -.offset9 { - margin-left: 740px; -} - -.offset8 { - margin-left: 660px; -} - -.offset7 { - margin-left: 580px; -} - -.offset6 { - margin-left: 500px; -} - -.offset5 { - margin-left: 420px; -} - -.offset4 { - margin-left: 340px; -} - -.offset3 { - margin-left: 260px; -} - -.offset2 { - margin-left: 180px; -} - -.offset1 { - margin-left: 100px; -} - -.row-fluid { - width: 100%; - *zoom: 1; -} - -.row-fluid:before, -.row-fluid:after { - display: table; - line-height: 0; - content: ""; -} - -.row-fluid:after { - clear: both; -} - -.row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 30px; - margin-left: 2.127659574468085%; - *margin-left: 2.074468085106383%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.row-fluid [class*="span"]:first-child { - margin-left: 0; -} - -.row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.127659574468085%; -} - -.row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; -} - -.row-fluid .span11 { - width: 91.48936170212765%; - *width: 91.43617021276594%; -} - -.row-fluid .span10 { - width: 82.97872340425532%; - *width: 82.92553191489361%; -} - -.row-fluid .span9 { - width: 74.46808510638297%; - *width: 74.41489361702126%; -} - -.row-fluid .span8 { - width: 65.95744680851064%; - *width: 65.90425531914893%; -} - -.row-fluid .span7 { - width: 57.44680851063829%; - *width: 57.39361702127659%; -} - -.row-fluid .span6 { - width: 48.93617021276595%; - *width: 48.88297872340425%; -} - -.row-fluid .span5 { - width: 40.42553191489362%; - *width: 40.37234042553192%; -} - -.row-fluid .span4 { - width: 31.914893617021278%; - *width: 31.861702127659576%; -} - -.row-fluid .span3 { - width: 23.404255319148934%; - *width: 23.351063829787233%; -} - -.row-fluid .span2 { - width: 14.893617021276595%; - *width: 14.840425531914894%; -} - -.row-fluid .span1 { - width: 6.382978723404255%; - *width: 6.329787234042553%; -} - -.row-fluid .offset12 { - margin-left: 104.25531914893617%; - *margin-left: 104.14893617021275%; -} - -.row-fluid .offset12:first-child { - margin-left: 102.12765957446808%; - *margin-left: 102.02127659574467%; -} - -.row-fluid .offset11 { - margin-left: 95.74468085106382%; - *margin-left: 95.6382978723404%; -} - -.row-fluid .offset11:first-child { - margin-left: 93.61702127659574%; - *margin-left: 93.51063829787232%; -} - -.row-fluid .offset10 { - margin-left: 87.23404255319149%; - *margin-left: 87.12765957446807%; -} - -.row-fluid .offset10:first-child { - margin-left: 85.1063829787234%; - *margin-left: 84.99999999999999%; -} - -.row-fluid .offset9 { - margin-left: 78.72340425531914%; - *margin-left: 78.61702127659572%; -} - -.row-fluid .offset9:first-child { - margin-left: 76.59574468085106%; - *margin-left: 76.48936170212764%; -} - -.row-fluid .offset8 { - margin-left: 70.2127659574468%; - *margin-left: 70.10638297872339%; -} - -.row-fluid .offset8:first-child { - margin-left: 68.08510638297872%; - *margin-left: 67.9787234042553%; -} - -.row-fluid .offset7 { - margin-left: 61.70212765957446%; - *margin-left: 61.59574468085106%; -} - -.row-fluid .offset7:first-child { - margin-left: 59.574468085106375%; - *margin-left: 59.46808510638297%; -} - -.row-fluid .offset6 { - margin-left: 53.191489361702125%; - *margin-left: 53.085106382978715%; -} - -.row-fluid .offset6:first-child { - margin-left: 51.063829787234035%; - *margin-left: 50.95744680851063%; -} - -.row-fluid .offset5 { - margin-left: 44.68085106382979%; - *margin-left: 44.57446808510638%; -} - -.row-fluid .offset5:first-child { - margin-left: 42.5531914893617%; - *margin-left: 42.4468085106383%; -} - -.row-fluid .offset4 { - margin-left: 36.170212765957444%; - *margin-left: 36.06382978723405%; -} - -.row-fluid .offset4:first-child { - margin-left: 34.04255319148936%; - *margin-left: 33.93617021276596%; -} - -.row-fluid .offset3 { - margin-left: 27.659574468085104%; - *margin-left: 27.5531914893617%; -} - -.row-fluid .offset3:first-child { - margin-left: 25.53191489361702%; - *margin-left: 25.425531914893618%; -} - -.row-fluid .offset2 { - margin-left: 19.148936170212764%; - *margin-left: 19.04255319148936%; -} - -.row-fluid .offset2:first-child { - margin-left: 17.02127659574468%; - *margin-left: 16.914893617021278%; -} - -.row-fluid .offset1 { - margin-left: 10.638297872340425%; - *margin-left: 10.53191489361702%; -} - -.row-fluid .offset1:first-child { - margin-left: 8.51063829787234%; - *margin-left: 8.404255319148938%; -} - -[class*="span"].hide, -.row-fluid [class*="span"].hide { - display: none; -} - -[class*="span"].pull-right, -.row-fluid [class*="span"].pull-right { - float: right; -} - -.container { - margin-right: auto; - margin-left: auto; - *zoom: 1; -} - -.container:before, -.container:after { - display: table; - line-height: 0; - content: ""; -} - -.container:after { - clear: both; -} - -.container-fluid { - padding-right: 20px; - padding-left: 20px; - *zoom: 1; -} - -.container-fluid:before, -.container-fluid:after { - display: table; - line-height: 0; - content: ""; -} - -.container-fluid:after { - clear: both; -} - -p { - margin: 0 0 10px; -} - -.lead { - margin-bottom: 20px; - font-size: 21px; - font-weight: 200; - line-height: 30px; -} - -small { - font-size: 85%; -} - -strong { - font-weight: bold; -} - -em { - font-style: italic; -} - -cite { - font-style: normal; -} - -.muted { - color: #999999; -} - -a.muted:hover, -a.muted:focus { - color: #808080; -} - -.text-warning { - color: #c09853; -} - -a.text-warning:hover, -a.text-warning:focus { - color: #a47e3c; -} - -.text-error { - color: #b94a48; -} - -a.text-error:hover, -a.text-error:focus { - color: #953b39; -} - -.text-info { - color: #3a87ad; -} - -a.text-info:hover, -a.text-info:focus { - color: #2d6987; -} - -.text-success { - color: #468847; -} - -a.text-success:hover, -a.text-success:focus { - color: #356635; -} - -.text-left { - text-align: left; -} - -.text-right { - text-align: right; -} - -.text-center { - text-align: center; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 10px 0; - font-family: inherit; - font-weight: bold; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} - -h1, -h2, -h3 { - line-height: 40px; -} - -h1 { - font-size: 38.5px; -} - -h2 { - font-size: 31.5px; -} - -h3 { - font-size: 24.5px; -} - -h4 { - font-size: 17.5px; -} - -h5 { - font-size: 14px; -} - -h6 { - font-size: 11.9px; -} - -h1 small { - font-size: 24.5px; -} - -h2 small { - font-size: 17.5px; -} - -h3 small { - font-size: 14px; -} - -h4 small { - font-size: 14px; -} - -.page-header { - padding-bottom: 9px; - margin: 20px 0 30px; - border-bottom: 1px solid #eeeeee; -} - -ul, -ol { - padding: 0; - margin: 0 0 10px 25px; -} - -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} - -li { - line-height: 20px; -} - -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} - -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; -} - -ul.inline > li, -ol.inline > li { - display: inline-block; - *display: inline; - padding-right: 5px; - padding-left: 5px; - *zoom: 1; -} - -dl { - margin-bottom: 20px; -} - -dt, -dd { - line-height: 20px; -} - -dt { - font-weight: bold; -} - -dd { - margin-left: 10px; -} - -.dl-horizontal { - *zoom: 1; -} - -.dl-horizontal:before, -.dl-horizontal:after { - display: table; - line-height: 0; - content: ""; -} - -.dl-horizontal:after { - clear: both; -} - -.dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap; -} - -.dl-horizontal dd { - margin-left: 180px; -} - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; -} - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} - -blockquote p { - margin-bottom: 0; - font-size: 17.5px; - font-weight: 300; - line-height: 1.25; -} - -blockquote small { - display: block; - line-height: 20px; - color: #999999; -} - -blockquote small:before { - content: '\2014 \00A0'; -} - -blockquote.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} - -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} - -blockquote.pull-right small:before { - content: ''; -} - -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; -} - -code, -pre { - padding: 0 3px 2px; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - font-size: 12px; - color: #333333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -code { - padding: 2px 4px; - color: #d14; - white-space: nowrap; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 20px; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -pre.prettyprint { - margin-bottom: 20px; -} - -pre code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -form { - margin: 0 0 20px; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: 40px; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} - -legend small { - font-size: 15px; - color: #999999; -} - -label, -input, -button, -select, -textarea { - font-size: 14px; - font-weight: normal; - line-height: 20px; -} - -input, -button, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} - -label { - display: block; - margin-bottom: 5px; -} - -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 20px; - padding: 4px 6px; - margin-bottom: 10px; - font-size: 14px; - line-height: 20px; - color: #555555; - vertical-align: middle; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -input, -textarea, -.uneditable-input { - width: 206px; -} - -textarea { - height: auto; -} - -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: #ffffff; - border: 1px solid #cccccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; - -moz-transition: border linear 0.2s, box-shadow linear 0.2s; - -o-transition: border linear 0.2s, box-shadow linear 0.2s; - transition: border linear 0.2s, box-shadow linear 0.2s; -} - -textarea:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="datetime"]:focus, -input[type="datetime-local"]:focus, -input[type="date"]:focus, -input[type="month"]:focus, -input[type="time"]:focus, -input[type="week"]:focus, -input[type="number"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="search"]:focus, -input[type="tel"]:focus, -input[type="color"]:focus, -.uneditable-input:focus { - border-color: rgba(82, 168, 236, 0.8); - outline: 0; - outline: thin dotted \9; - /* IE6-9 */ - - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); -} - -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - *margin-top: 0; - line-height: normal; -} - -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; -} - -select, -input[type="file"] { - height: 30px; - /* In IE7, the height of the select element cannot be changed by height, only font-size */ - - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ - - line-height: 30px; -} - -select { - width: 220px; - background-color: #ffffff; - border: 1px solid #cccccc; -} - -select[multiple], -select[size] { - height: auto; -} - -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.uneditable-input, -.uneditable-textarea { - color: #999999; - cursor: not-allowed; - background-color: #fcfcfc; - border-color: #cccccc; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); -} - -.uneditable-input { - overflow: hidden; - white-space: nowrap; -} - -.uneditable-textarea { - width: auto; - height: auto; -} - -input:-moz-placeholder, -textarea:-moz-placeholder { - color: #999999; -} - -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #999999; -} - -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #999999; -} - -.radio, -.checkbox { - min-height: 20px; - padding-left: 20px; -} - -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} - -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; -} - -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} - -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; -} - -.input-mini { - width: 60px; -} - -.input-small { - width: 90px; -} - -.input-medium { - width: 150px; -} - -.input-large { - width: 210px; -} - -.input-xlarge { - width: 270px; -} - -.input-xxlarge { - width: 530px; -} - -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} - -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - -input, -textarea, -.uneditable-input { - margin-left: 0; -} - -.controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; -} - -input.span12, -textarea.span12, -.uneditable-input.span12 { - width: 926px; -} - -input.span11, -textarea.span11, -.uneditable-input.span11 { - width: 846px; -} - -input.span10, -textarea.span10, -.uneditable-input.span10 { - width: 766px; -} - -input.span9, -textarea.span9, -.uneditable-input.span9 { - width: 686px; -} - -input.span8, -textarea.span8, -.uneditable-input.span8 { - width: 606px; -} - -input.span7, -textarea.span7, -.uneditable-input.span7 { - width: 526px; -} - -input.span6, -textarea.span6, -.uneditable-input.span6 { - width: 446px; -} - -input.span5, -textarea.span5, -.uneditable-input.span5 { - width: 366px; -} - -input.span4, -textarea.span4, -.uneditable-input.span4 { - width: 286px; -} - -input.span3, -textarea.span3, -.uneditable-input.span3 { - width: 206px; -} - -input.span2, -textarea.span2, -.uneditable-input.span2 { - width: 126px; -} - -input.span1, -textarea.span1, -.uneditable-input.span1 { - width: 46px; -} - -.controls-row { - *zoom: 1; -} - -.controls-row:before, -.controls-row:after { - display: table; - line-height: 0; - content: ""; -} - -.controls-row:after { - clear: both; -} - -.controls-row [class*="span"], -.row-fluid .controls-row [class*="span"] { - float: left; -} - -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: #eeeeee; -} - -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - -.control-group.warning .control-label, -.control-group.warning .help-block, -.control-group.warning .help-inline { - color: #c09853; -} - -.control-group.warning .checkbox, -.control-group.warning .radio, -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - color: #c09853; -} - -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - border-color: #c09853; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.warning input:focus, -.control-group.warning select:focus, -.control-group.warning textarea:focus { - border-color: #a47e3c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -} - -.control-group.warning .input-prepend .add-on, -.control-group.warning .input-append .add-on { - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.control-group.error .control-label, -.control-group.error .help-block, -.control-group.error .help-inline { - color: #b94a48; -} - -.control-group.error .checkbox, -.control-group.error .radio, -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - color: #b94a48; -} - -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - border-color: #b94a48; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.error input:focus, -.control-group.error select:focus, -.control-group.error textarea:focus { - border-color: #953b39; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -} - -.control-group.error .input-prepend .add-on, -.control-group.error .input-append .add-on { - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.control-group.success .control-label, -.control-group.success .help-block, -.control-group.success .help-inline { - color: #468847; -} - -.control-group.success .checkbox, -.control-group.success .radio, -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - color: #468847; -} - -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - border-color: #468847; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.success input:focus, -.control-group.success select:focus, -.control-group.success textarea:focus { - border-color: #356635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -} - -.control-group.success .input-prepend .add-on, -.control-group.success .input-append .add-on { - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -.control-group.info .control-label, -.control-group.info .help-block, -.control-group.info .help-inline { - color: #3a87ad; -} - -.control-group.info .checkbox, -.control-group.info .radio, -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - color: #3a87ad; -} - -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - border-color: #3a87ad; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.info input:focus, -.control-group.info select:focus, -.control-group.info textarea:focus { - border-color: #2d6987; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; -} - -.control-group.info .input-prepend .add-on, -.control-group.info .input-append .add-on { - color: #3a87ad; - background-color: #d9edf7; - border-color: #3a87ad; -} - -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; -} - -input:focus:invalid:focus, -textarea:focus:invalid:focus, -select:focus:invalid:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} - -.form-actions { - padding: 19px 20px 20px; - margin-top: 20px; - margin-bottom: 20px; - background-color: #f5f5f5; - border-top: 1px solid #e5e5e5; - *zoom: 1; -} - -.form-actions:before, -.form-actions:after { - display: table; - line-height: 0; - content: ""; -} - -.form-actions:after { - clear: both; -} - -.help-block, -.help-inline { - color: #595959; -} - -.help-block { - display: block; - margin-bottom: 10px; -} - -.help-inline { - display: inline-block; - *display: inline; - padding-left: 5px; - vertical-align: middle; - *zoom: 1; -} - -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: 10px; - font-size: 0; - white-space: nowrap; - vertical-align: middle; -} - -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input, -.input-append .dropdown-menu, -.input-prepend .dropdown-menu, -.input-append .popover, -.input-prepend .popover { - font-size: 14px; -} - -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input { - position: relative; - margin-bottom: 0; - *margin-left: 0; - vertical-align: top; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-append input:focus, -.input-prepend input:focus, -.input-append select:focus, -.input-prepend select:focus, -.input-append .uneditable-input:focus, -.input-prepend .uneditable-input:focus { - z-index: 2; -} - -.input-append .add-on, -.input-prepend .add-on { - display: inline-block; - width: auto; - height: 20px; - min-width: 16px; - padding: 4px 5px; - font-size: 14px; - font-weight: normal; - line-height: 20px; - text-align: center; - text-shadow: 0 1px 0 #ffffff; - background-color: #eeeeee; - border: 1px solid #ccc; -} - -.input-append .add-on, -.input-prepend .add-on, -.input-append .btn, -.input-prepend .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .btn-group > .dropdown-toggle { - vertical-align: top; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.input-append .active, -.input-prepend .active { - background-color: #a9dba9; - border-color: #46a546; -} - -.input-prepend .add-on, -.input-prepend .btn { - margin-right: -1px; -} - -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-append input + .btn-group .btn:last-child, -.input-append select + .btn-group .btn:last-child, -.input-append .uneditable-input + .btn-group .btn:last-child { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-append .add-on, -.input-append .btn, -.input-append .btn-group { - margin-left: -1px; -} - -.input-append .add-on:last-child, -.input-append .btn:last-child, -.input-append .btn-group:last-child > .dropdown-toggle { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.input-prepend.input-append input + .btn-group .btn, -.input-prepend.input-append select + .btn-group .btn, -.input-prepend.input-append .uneditable-input + .btn-group .btn { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append .btn-group:first-child { - margin-left: 0; -} - -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; - /* IE7-8 doesn't have border-radius, so don't indent the padding */ - - margin-bottom: 0; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -/* Allow for input prepend/append in search forms */ - -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.form-search .input-append .search-query { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} - -.form-search .input-append .btn { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} - -.form-search .input-prepend .search-query { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} - -.form-search .input-prepend .btn { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} - -.form-search input, -.form-inline input, -.form-horizontal input, -.form-search textarea, -.form-inline textarea, -.form-horizontal textarea, -.form-search select, -.form-inline select, -.form-horizontal select, -.form-search .help-inline, -.form-inline .help-inline, -.form-horizontal .help-inline, -.form-search .uneditable-input, -.form-inline .uneditable-input, -.form-horizontal .uneditable-input, -.form-search .input-prepend, -.form-inline .input-prepend, -.form-horizontal .input-prepend, -.form-search .input-append, -.form-inline .input-append, -.form-horizontal .input-append { - display: inline-block; - *display: inline; - margin-bottom: 0; - vertical-align: middle; - *zoom: 1; -} - -.form-search .hide, -.form-inline .hide, -.form-horizontal .hide { - display: none; -} - -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} - -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} - -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} - -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - -.control-group { - margin-bottom: 10px; -} - -legend + .control-group { - margin-top: 20px; - -webkit-margin-top-collapse: separate; -} - -.form-horizontal .control-group { - margin-bottom: 20px; - *zoom: 1; -} - -.form-horizontal .control-group:before, -.form-horizontal .control-group:after { - display: table; - line-height: 0; - content: ""; -} - -.form-horizontal .control-group:after { - clear: both; -} - -.form-horizontal .control-label { - float: left; - width: 160px; - padding-top: 5px; - text-align: right; -} - -.form-horizontal .controls { - *display: inline-block; - *padding-left: 20px; - margin-left: 180px; - *margin-left: 0; -} - -.form-horizontal .controls:first-child { - *padding-left: 180px; -} - -.form-horizontal .help-block { - margin-bottom: 0; -} - -.form-horizontal input + .help-block, -.form-horizontal select + .help-block, -.form-horizontal textarea + .help-block, -.form-horizontal .uneditable-input + .help-block, -.form-horizontal .input-prepend + .help-block, -.form-horizontal .input-append + .help-block { - margin-top: 10px; -} - -.form-horizontal .form-actions { - padding-left: 180px; -} - -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} - -.table { - width: 100%; - margin-bottom: 20px; -} - -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #dddddd; -} - -.table th { - font-weight: bold; -} - -.table thead th { - vertical-align: bottom; -} - -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; -} - -.table tbody + tbody { - border-top: 2px solid #dddddd; -} - -.table .table { - background-color: #ffffff; -} - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; -} - -.table-bordered { - border: 1px solid #dddddd; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #dddddd; -} - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; -} - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; -} - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; -} - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; -} - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; -} - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; -} - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; -} - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; -} - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; -} - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: #f5f5f5; -} - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; -} - -.table td.span1, -.table th.span1 { - float: none; - width: 44px; - margin-left: 0; -} - -.table td.span2, -.table th.span2 { - float: none; - width: 124px; - margin-left: 0; -} - -.table td.span3, -.table th.span3 { - float: none; - width: 204px; - margin-left: 0; -} - -.table td.span4, -.table th.span4 { - float: none; - width: 284px; - margin-left: 0; -} - -.table td.span5, -.table th.span5 { - float: none; - width: 364px; - margin-left: 0; -} - -.table td.span6, -.table th.span6 { - float: none; - width: 444px; - margin-left: 0; -} - -.table td.span7, -.table th.span7 { - float: none; - width: 524px; - margin-left: 0; -} - -.table td.span8, -.table th.span8 { - float: none; - width: 604px; - margin-left: 0; -} - -.table td.span9, -.table th.span9 { - float: none; - width: 684px; - margin-left: 0; -} - -.table td.span10, -.table th.span10 { - float: none; - width: 764px; - margin-left: 0; -} - -.table td.span11, -.table th.span11 { - float: none; - width: 844px; - margin-left: 0; -} - -.table td.span12, -.table th.span12 { - float: none; - width: 924px; - margin-left: 0; -} - -.table tbody tr.success > td { - background-color: #dff0d8; -} - -.table tbody tr.error > td { - background-color: #f2dede; -} - -.table tbody tr.warning > td { - background-color: #fcf8e3; -} - -.table tbody tr.info > td { - background-color: #d9edf7; -} - -.table-hover tbody tr.success:hover > td { - background-color: #d0e9c6; -} - -.table-hover tbody tr.error:hover > td { - background-color: #ebcccc; -} - -.table-hover tbody tr.warning:hover > td { - background-color: #faf2cc; -} - -.table-hover tbody tr.info:hover > td { - background-color: #c4e3f3; -} - -[class^="icon-"], -[class*=" icon-"] { - display: inline-block; - width: 14px; - height: 14px; - margin-top: 1px; - *margin-right: .3em; - line-height: 14px; - vertical-align: text-top; - background-image: url("../img/glyphicons-halflings.png"); - background-position: 14px 14px; - background-repeat: no-repeat; -} - -/* White icons with optional class, or on hover/focus/active states of certain elements */ - -.icon-white, -.nav-pills > .active > a > [class^="icon-"], -.nav-pills > .active > a > [class*=" icon-"], -.nav-list > .active > a > [class^="icon-"], -.nav-list > .active > a > [class*=" icon-"], -.navbar-inverse .nav > .active > a > [class^="icon-"], -.navbar-inverse .nav > .active > a > [class*=" icon-"], -.dropdown-menu > li > a:hover > [class^="icon-"], -.dropdown-menu > li > a:focus > [class^="icon-"], -.dropdown-menu > li > a:hover > [class*=" icon-"], -.dropdown-menu > li > a:focus > [class*=" icon-"], -.dropdown-menu > .active > a > [class^="icon-"], -.dropdown-menu > .active > a > [class*=" icon-"], -.dropdown-submenu:hover > a > [class^="icon-"], -.dropdown-submenu:focus > a > [class^="icon-"], -.dropdown-submenu:hover > a > [class*=" icon-"], -.dropdown-submenu:focus > a > [class*=" icon-"] { - background-image: url("../img/glyphicons-halflings-white.png"); -} - -.icon-glass { - background-position: 0 0; -} - -.icon-music { - background-position: -24px 0; -} - -.icon-search { - background-position: -48px 0; -} - -.icon-envelope { - background-position: -72px 0; -} - -.icon-heart { - background-position: -96px 0; -} - -.icon-star { - background-position: -120px 0; -} - -.icon-star-empty { - background-position: -144px 0; -} - -.icon-user { - background-position: -168px 0; -} - -.icon-film { - background-position: -192px 0; -} - -.icon-th-large { - background-position: -216px 0; -} - -.icon-th { - background-position: -240px 0; -} - -.icon-th-list { - background-position: -264px 0; -} - -.icon-ok { - background-position: -288px 0; -} - -.icon-remove { - background-position: -312px 0; -} - -.icon-zoom-in { - background-position: -336px 0; -} - -.icon-zoom-out { - background-position: -360px 0; -} - -.icon-off { - background-position: -384px 0; -} - -.icon-signal { - background-position: -408px 0; -} - -.icon-cog { - background-position: -432px 0; -} - -.icon-trash { - background-position: -456px 0; -} - -.icon-home { - background-position: 0 -24px; -} - -.icon-file { - background-position: -24px -24px; -} - -.icon-time { - background-position: -48px -24px; -} - -.icon-road { - background-position: -72px -24px; -} - -.icon-download-alt { - background-position: -96px -24px; -} - -.icon-download { - background-position: -120px -24px; -} - -.icon-upload { - background-position: -144px -24px; -} - -.icon-inbox { - background-position: -168px -24px; -} - -.icon-play-circle { - background-position: -192px -24px; -} - -.icon-repeat { - background-position: -216px -24px; -} - -.icon-refresh { - background-position: -240px -24px; -} - -.icon-list-alt { - background-position: -264px -24px; -} - -.icon-lock { - background-position: -287px -24px; -} - -.icon-flag { - background-position: -312px -24px; -} - -.icon-headphones { - background-position: -336px -24px; -} - -.icon-volume-off { - background-position: -360px -24px; -} - -.icon-volume-down { - background-position: -384px -24px; -} - -.icon-volume-up { - background-position: -408px -24px; -} - -.icon-qrcode { - background-position: -432px -24px; -} - -.icon-barcode { - background-position: -456px -24px; -} - -.icon-tag { - background-position: 0 -48px; -} - -.icon-tags { - background-position: -25px -48px; -} - -.icon-book { - background-position: -48px -48px; -} - -.icon-bookmark { - background-position: -72px -48px; -} - -.icon-print { - background-position: -96px -48px; -} - -.icon-camera { - background-position: -120px -48px; -} - -.icon-font { - background-position: -144px -48px; -} - -.icon-bold { - background-position: -167px -48px; -} - -.icon-italic { - background-position: -192px -48px; -} - -.icon-text-height { - background-position: -216px -48px; -} - -.icon-text-width { - background-position: -240px -48px; -} - -.icon-align-left { - background-position: -264px -48px; -} - -.icon-align-center { - background-position: -288px -48px; -} - -.icon-align-right { - background-position: -312px -48px; -} - -.icon-align-justify { - background-position: -336px -48px; -} - -.icon-list { - background-position: -360px -48px; -} - -.icon-indent-left { - background-position: -384px -48px; -} - -.icon-indent-right { - background-position: -408px -48px; -} - -.icon-facetime-video { - background-position: -432px -48px; -} - -.icon-picture { - background-position: -456px -48px; -} - -.icon-pencil { - background-position: 0 -72px; -} - -.icon-map-marker { - background-position: -24px -72px; -} - -.icon-adjust { - background-position: -48px -72px; -} - -.icon-tint { - background-position: -72px -72px; -} - -.icon-edit { - background-position: -96px -72px; -} - -.icon-share { - background-position: -120px -72px; -} - -.icon-check { - background-position: -144px -72px; -} - -.icon-move { - background-position: -168px -72px; -} - -.icon-step-backward { - background-position: -192px -72px; -} - -.icon-fast-backward { - background-position: -216px -72px; -} - -.icon-backward { - background-position: -240px -72px; -} - -.icon-play { - background-position: -264px -72px; -} - -.icon-pause { - background-position: -288px -72px; -} - -.icon-stop { - background-position: -312px -72px; -} - -.icon-forward { - background-position: -336px -72px; -} - -.icon-fast-forward { - background-position: -360px -72px; -} - -.icon-step-forward { - background-position: -384px -72px; -} - -.icon-eject { - background-position: -408px -72px; -} - -.icon-chevron-left { - background-position: -432px -72px; -} - -.icon-chevron-right { - background-position: -456px -72px; -} - -.icon-plus-sign { - background-position: 0 -96px; -} - -.icon-minus-sign { - background-position: -24px -96px; -} - -.icon-remove-sign { - background-position: -48px -96px; -} - -.icon-ok-sign { - background-position: -72px -96px; -} - -.icon-question-sign { - background-position: -96px -96px; -} - -.icon-info-sign { - background-position: -120px -96px; -} - -.icon-screenshot { - background-position: -144px -96px; -} - -.icon-remove-circle { - background-position: -168px -96px; -} - -.icon-ok-circle { - background-position: -192px -96px; -} - -.icon-ban-circle { - background-position: -216px -96px; -} - -.icon-arrow-left { - background-position: -240px -96px; -} - -.icon-arrow-right { - background-position: -264px -96px; -} - -.icon-arrow-up { - background-position: -289px -96px; -} - -.icon-arrow-down { - background-position: -312px -96px; -} - -.icon-share-alt { - background-position: -336px -96px; -} - -.icon-resize-full { - background-position: -360px -96px; -} - -.icon-resize-small { - background-position: -384px -96px; -} - -.icon-plus { - background-position: -408px -96px; -} - -.icon-minus { - background-position: -433px -96px; -} - -.icon-asterisk { - background-position: -456px -96px; -} - -.icon-exclamation-sign { - background-position: 0 -120px; -} - -.icon-gift { - background-position: -24px -120px; -} - -.icon-leaf { - background-position: -48px -120px; -} - -.icon-fire { - background-position: -72px -120px; -} - -.icon-eye-open { - background-position: -96px -120px; -} - -.icon-eye-close { - background-position: -120px -120px; -} - -.icon-warning-sign { - background-position: -144px -120px; -} - -.icon-plane { - background-position: -168px -120px; -} - -.icon-calendar { - background-position: -192px -120px; -} - -.icon-random { - width: 16px; - background-position: -216px -120px; -} - -.icon-comment { - background-position: -240px -120px; -} - -.icon-magnet { - background-position: -264px -120px; -} - -.icon-chevron-up { - background-position: -288px -120px; -} - -.icon-chevron-down { - background-position: -313px -119px; -} - -.icon-retweet { - background-position: -336px -120px; -} - -.icon-shopping-cart { - background-position: -360px -120px; -} - -.icon-folder-close { - width: 16px; - background-position: -384px -120px; -} - -.icon-folder-open { - width: 16px; - background-position: -408px -120px; -} - -.icon-resize-vertical { - background-position: -432px -119px; -} - -.icon-resize-horizontal { - background-position: -456px -118px; -} - -.icon-hdd { - background-position: 0 -144px; -} - -.icon-bullhorn { - background-position: -24px -144px; -} - -.icon-bell { - background-position: -48px -144px; -} - -.icon-certificate { - background-position: -72px -144px; -} - -.icon-thumbs-up { - background-position: -96px -144px; -} - -.icon-thumbs-down { - background-position: -120px -144px; -} - -.icon-hand-right { - background-position: -144px -144px; -} - -.icon-hand-left { - background-position: -168px -144px; -} - -.icon-hand-up { - background-position: -192px -144px; -} - -.icon-hand-down { - background-position: -216px -144px; -} - -.icon-circle-arrow-right { - background-position: -240px -144px; -} - -.icon-circle-arrow-left { - background-position: -264px -144px; -} - -.icon-circle-arrow-up { - background-position: -288px -144px; -} - -.icon-circle-arrow-down { - background-position: -312px -144px; -} - -.icon-globe { - background-position: -336px -144px; -} - -.icon-wrench { - background-position: -360px -144px; -} - -.icon-tasks { - background-position: -384px -144px; -} - -.icon-filter { - background-position: -408px -144px; -} - -.icon-briefcase { - background-position: -432px -144px; -} - -.icon-fullscreen { - background-position: -456px -144px; -} - -.dropup, -.dropdown { - position: relative; -} - -.dropdown-toggle { - *margin-bottom: -3px; -} - -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} - -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - background-color: #ffffff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; -} - -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 20px; - color: #333333; - white-space: nowrap; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - color: #ffffff; - text-decoration: none; - background-color: #0081c2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); -} - -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - background-color: #0081c2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - outline: 0; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); -} - -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999999; -} - -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - cursor: default; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.open { - *z-index: 1000; -} - -.open > .dropdown-menu { - display: block; -} - -.dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990; -} - -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid #000000; - content: ""; -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} - -.dropdown-submenu { - position: relative; -} - -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - -webkit-border-radius: 0 6px 6px 6px; - -moz-border-radius: 0 6px 6px 6px; - border-radius: 0 6px 6px 6px; -} - -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} - -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - -webkit-border-radius: 5px 5px 5px 0; - -moz-border-radius: 5px 5px 5px 0; - border-radius: 5px 5px 5px 0; -} - -.dropdown-submenu > a:after { - display: block; - float: right; - width: 0; - height: 0; - margin-top: 5px; - margin-right: -10px; - border-color: transparent; - border-left-color: #cccccc; - border-style: solid; - border-width: 5px 0 5px 5px; - content: " "; -} - -.dropdown-submenu:hover > a:after { - border-left-color: #ffffff; -} - -.dropdown-submenu.pull-left { - float: none; -} - -.dropdown-submenu.pull-left > .dropdown-menu { - left: -100%; - margin-left: 10px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} - -.dropdown .dropdown-menu .nav-header { - padding-right: 20px; - padding-left: 20px; -} - -.typeahead { - z-index: 1051; - margin-top: 2px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #e3e3e3; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-large { - padding: 24px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.well-small { - padding: 9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -moz-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} - -.fade.in { - opacity: 1; -} - -.collapse { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - -moz-transition: height 0.35s ease; - -o-transition: height 0.35s ease; - transition: height 0.35s ease; -} - -.collapse.in { - height: auto; -} - -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: 20px; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} - -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} - -.btn { - display: inline-block; - *display: inline; - padding: 4px 12px; - margin-bottom: 0; - *margin-left: .3em; - font-size: 14px; - line-height: 20px; - color: #333333; - text-align: center; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - vertical-align: middle; - cursor: pointer; - background-color: #f5f5f5; - *background-color: #e6e6e6; - background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); - background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); - background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); - background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); - background-repeat: repeat-x; - border: 1px solid #cccccc; - *border: 0; - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - border-bottom-color: #b3b3b3; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn:hover, -.btn:focus, -.btn:active, -.btn.active, -.btn.disabled, -.btn[disabled] { - color: #333333; - background-color: #e6e6e6; - *background-color: #d9d9d9; -} - -.btn:active, -.btn.active { - background-color: #cccccc \9; -} - -.btn:first-child { - *margin-left: 0; -} - -.btn:hover, -.btn:focus { - color: #333333; - text-decoration: none; - background-position: 0 -15px; - -webkit-transition: background-position 0.1s linear; - -moz-transition: background-position 0.1s linear; - -o-transition: background-position 0.1s linear; - transition: background-position 0.1s linear; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn.active, -.btn:active { - background-image: none; - outline: 0; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn.disabled, -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -.btn-large { - padding: 11px 19px; - font-size: 17.5px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} - -.btn-small { - padding: 2px 10px; - font-size: 11.9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} - -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} - -.btn-mini { - padding: 0 6px; - font-size: 10.5px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.btn-block + .btn-block { - margin-top: 5px; -} - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} - -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - color: rgba(255, 255, 255, 0.75); -} - -.btn-primary { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #006dcc; - *background-color: #0044cc; - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(to bottom, #0088cc, #0044cc); - background-repeat: repeat-x; - border-color: #0044cc #0044cc #002a80; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.btn-primary.disabled, -.btn-primary[disabled] { - color: #ffffff; - background-color: #0044cc; - *background-color: #003bb3; -} - -.btn-primary:active, -.btn-primary.active { - background-color: #003399 \9; -} - -.btn-warning { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #faa732; - *background-color: #f89406; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - border-color: #f89406 #f89406 #ad6704; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.btn-warning.disabled, -.btn-warning[disabled] { - color: #ffffff; - background-color: #f89406; - *background-color: #df8505; -} - -.btn-warning:active, -.btn-warning.active { - background-color: #c67605 \9; -} - -.btn-danger { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #da4f49; - *background-color: #bd362f; - background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); - background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); - background-repeat: repeat-x; - border-color: #bd362f #bd362f #802420; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.btn-danger.disabled, -.btn-danger[disabled] { - color: #ffffff; - background-color: #bd362f; - *background-color: #a9302a; -} - -.btn-danger:active, -.btn-danger.active { - background-color: #942a25 \9; -} - -.btn-success { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #5bb75b; - *background-color: #51a351; - background-image: -moz-linear-gradient(top, #62c462, #51a351); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); - background-image: -webkit-linear-gradient(top, #62c462, #51a351); - background-image: -o-linear-gradient(top, #62c462, #51a351); - background-image: linear-gradient(to bottom, #62c462, #51a351); - background-repeat: repeat-x; - border-color: #51a351 #51a351 #387038; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.btn-success.disabled, -.btn-success[disabled] { - color: #ffffff; - background-color: #51a351; - *background-color: #499249; -} - -.btn-success:active, -.btn-success.active { - background-color: #408140 \9; -} - -.btn-info { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #49afcd; - *background-color: #2f96b4; - background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); - background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); - background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); - background-repeat: repeat-x; - border-color: #2f96b4 #2f96b4 #1f6377; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.btn-info.disabled, -.btn-info[disabled] { - color: #ffffff; - background-color: #2f96b4; - *background-color: #2a85a0; -} - -.btn-info:active, -.btn-info.active { - background-color: #24748c \9; -} - -.btn-inverse { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #363636; - *background-color: #222222; - background-image: -moz-linear-gradient(top, #444444, #222222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); - background-image: -webkit-linear-gradient(top, #444444, #222222); - background-image: -o-linear-gradient(top, #444444, #222222); - background-image: linear-gradient(to bottom, #444444, #222222); - background-repeat: repeat-x; - border-color: #222222 #222222 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-inverse:hover, -.btn-inverse:focus, -.btn-inverse:active, -.btn-inverse.active, -.btn-inverse.disabled, -.btn-inverse[disabled] { - color: #ffffff; - background-color: #222222; - *background-color: #151515; -} - -.btn-inverse:active, -.btn-inverse.active { - background-color: #080808 \9; -} - -button.btn, -input[type="submit"].btn { - *padding-top: 3px; - *padding-bottom: 3px; -} - -button.btn::-moz-focus-inner, -input[type="submit"].btn::-moz-focus-inner { - padding: 0; - border: 0; -} - -button.btn.btn-large, -input[type="submit"].btn.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; -} - -button.btn.btn-small, -input[type="submit"].btn.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; -} - -button.btn.btn-mini, -input[type="submit"].btn.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; -} - -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -.btn-link { - color: #0088cc; - cursor: pointer; - border-color: transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-link:hover, -.btn-link:focus { - color: #005580; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: #333333; - text-decoration: none; -} - -.btn-group { - position: relative; - display: inline-block; - *display: inline; - *margin-left: .3em; - font-size: 0; - white-space: nowrap; - vertical-align: middle; - *zoom: 1; -} - -.btn-group:first-child { - *margin-left: 0; -} - -.btn-group + .btn-group { - margin-left: 5px; -} - -.btn-toolbar { - margin-top: 10px; - margin-bottom: 10px; - font-size: 0; -} - -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn { - position: relative; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-group > .btn + .btn { - margin-left: -1px; -} - -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: 14px; -} - -.btn-group > .btn-mini { - font-size: 10.5px; -} - -.btn-group > .btn-small { - font-size: 11.9px; -} - -.btn-group > .btn-large { - font-size: 17.5px; -} - -.btn-group > .btn:first-child { - margin-left: 0; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} - -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; -} - -.btn-group > .btn.large:first-child { - margin-left: 0; - -webkit-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -webkit-border-top-left-radius: 6px; - border-top-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - -moz-border-radius-topleft: 6px; -} - -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - -moz-border-radius-topright: 6px; - -moz-border-radius-bottomright: 6px; -} - -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - -.btn-group > .btn + .dropdown-toggle { - *padding-top: 5px; - padding-right: 8px; - *padding-bottom: 5px; - padding-left: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn-group > .btn-mini + .dropdown-toggle { - *padding-top: 2px; - padding-right: 5px; - *padding-bottom: 2px; - padding-left: 5px; -} - -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} - -.btn-group > .btn-large + .dropdown-toggle { - *padding-top: 7px; - padding-right: 12px; - *padding-bottom: 7px; - padding-left: 12px; -} - -.btn-group.open .dropdown-toggle { - background-image: none; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn-group.open .btn.dropdown-toggle { - background-color: #e6e6e6; -} - -.btn-group.open .btn-primary.dropdown-toggle { - background-color: #0044cc; -} - -.btn-group.open .btn-warning.dropdown-toggle { - background-color: #f89406; -} - -.btn-group.open .btn-danger.dropdown-toggle { - background-color: #bd362f; -} - -.btn-group.open .btn-success.dropdown-toggle { - background-color: #51a351; -} - -.btn-group.open .btn-info.dropdown-toggle { - background-color: #2f96b4; -} - -.btn-group.open .btn-inverse.dropdown-toggle { - background-color: #222222; -} - -.btn .caret { - margin-top: 8px; - margin-left: 0; -} - -.btn-large .caret { - margin-top: 6px; -} - -.btn-large .caret { - border-top-width: 5px; - border-right-width: 5px; - border-left-width: 5px; -} - -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} - -.dropup .btn-large .caret { - border-bottom-width: 5px; -} - -.btn-primary .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret, -.btn-success .caret, -.btn-inverse .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.btn-group-vertical { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - - *zoom: 1; -} - -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-group-vertical > .btn + .btn { - margin-top: -1px; - margin-left: 0; -} - -.btn-group-vertical > .btn:first-child { - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -.btn-group-vertical > .btn:last-child { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.btn-group-vertical > .btn-large:first-child { - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} - -.btn-group-vertical > .btn-large:last-child { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} - -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 20px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #fbeed5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.alert, -.alert h4 { - color: #c09853; -} - -.alert h4 { - margin: 0; -} - -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 20px; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success h4 { - color: #468847; -} - -.alert-danger, -.alert-error { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger h4, -.alert-error h4 { - color: #b94a48; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info h4 { - color: #3a87ad; -} - -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} - -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} - -.alert-block p + p { - margin-top: 5px; -} - -.nav { - margin-bottom: 20px; - margin-left: 0; - list-style: none; -} - -.nav > li > a { - display: block; -} - -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; -} - -.nav > li > a > img { - max-width: none; -} - -.nav > .pull-right { - float: right; -} - -.nav-header { - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: 20px; - color: #999999; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-transform: uppercase; -} - -.nav li + .nav-header { - margin-top: 9px; -} - -.nav-list { - padding-right: 15px; - padding-left: 15px; - margin-bottom: 0; -} - -.nav-list > li > a, -.nav-list .nav-header { - margin-right: -15px; - margin-left: -15px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} - -.nav-list > li > a { - padding: 3px 15px; -} - -.nav-list > .active > a, -.nav-list > .active > a:hover, -.nav-list > .active > a:focus { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); - background-color: #0088cc; -} - -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} - -.nav-list .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; -} - -.nav-tabs, -.nav-pills { - *zoom: 1; -} - -.nav-tabs:before, -.nav-pills:before, -.nav-tabs:after, -.nav-pills:after { - display: table; - line-height: 0; - content: ""; -} - -.nav-tabs:after, -.nav-pills:after { - clear: both; -} - -.nav-tabs > li, -.nav-pills > li { - float: left; -} - -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; -} - -.nav-tabs { - border-bottom: 1px solid #ddd; -} - -.nav-tabs > li { - margin-bottom: -1px; -} - -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 20px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #dddddd; -} - -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - color: #555555; - cursor: default; - background-color: #ffffff; - border: 1px solid #ddd; - border-bottom-color: transparent; -} - -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.nav-pills > .active > a, -.nav-pills > .active > a:hover, -.nav-pills > .active > a:focus { - color: #ffffff; - background-color: #0088cc; -} - -.nav-stacked > li { - float: none; -} - -.nav-stacked > li > a { - margin-right: 0; -} - -.nav-tabs.nav-stacked { - border-bottom: 0; -} - -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.nav-tabs.nav-stacked > li:first-child > a { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-topleft: 4px; -} - -.nav-tabs.nav-stacked > li:last-child > a { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-bottomleft: 4px; -} - -.nav-tabs.nav-stacked > li > a:hover, -.nav-tabs.nav-stacked > li > a:focus { - z-index: 2; - border-color: #ddd; -} - -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} - -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; -} - -.nav-tabs .dropdown-menu { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} - -.nav-pills .dropdown-menu { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.nav .dropdown-toggle .caret { - margin-top: 6px; - border-top-color: #0088cc; - border-bottom-color: #0088cc; -} - -.nav .dropdown-toggle:hover .caret, -.nav .dropdown-toggle:focus .caret { - border-top-color: #005580; - border-bottom-color: #005580; -} - -/* move down carets for tabs */ - -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} - -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} - -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.nav > .dropdown.active > a:hover, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} - -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - color: #ffffff; - background-color: #999999; - border-color: #999999; -} - -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret, -.nav li.dropdown.open a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; - opacity: 1; - filter: alpha(opacity=100); -} - -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - border-color: #999999; -} - -.tabbable { - *zoom: 1; -} - -.tabbable:before, -.tabbable:after { - display: table; - line-height: 0; - content: ""; -} - -.tabbable:after { - clear: both; -} - -.tab-content { - overflow: auto; -} - -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} - -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} - -.tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.tabs-below > .nav-tabs > li > a:hover, -.tabs-below > .nav-tabs > li > a:focus { - border-top-color: #ddd; - border-bottom-color: transparent; -} - -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - border-color: transparent #ddd #ddd #ddd; -} - -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} - -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} - -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} - -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.tabs-left > .nav-tabs > li > a:hover, -.tabs-left > .nav-tabs > li > a:focus { - border-color: #eeeeee #dddddd #eeeeee #eeeeee; -} - -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #ffffff; -} - -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} - -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.tabs-right > .nav-tabs > li > a:hover, -.tabs-right > .nav-tabs > li > a:focus { - border-color: #eeeeee #eeeeee #eeeeee #dddddd; -} - -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #ffffff; -} - -.nav > .disabled > a { - color: #999999; -} - -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - text-decoration: none; - cursor: default; - background-color: transparent; -} - -.navbar { - *position: relative; - *z-index: 2; - margin-bottom: 20px; - overflow: visible; -} - -.navbar-inner { - min-height: 40px; - padding-right: 20px; - padding-left: 20px; - background-color: #fafafa; - background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); - background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); - background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); - background-repeat: repeat-x; - border: 1px solid #d4d4d4; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); - *zoom: 1; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); -} - -.navbar-inner:before, -.navbar-inner:after { - display: table; - line-height: 0; - content: ""; -} - -.navbar-inner:after { - clear: both; -} - -.navbar .container { - width: auto; -} - -.nav-collapse.collapse { - height: auto; - overflow: visible; -} - -.navbar .brand { - display: block; - float: left; - padding: 10px 20px 10px; - margin-left: -20px; - font-size: 20px; - font-weight: 200; - color: #777777; - text-shadow: 0 1px 0 #ffffff; -} - -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} - -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #777777; -} - -.navbar-link { - color: #777777; -} - -.navbar-link:hover, -.navbar-link:focus { - color: #333333; -} - -.navbar .divider-vertical { - height: 40px; - margin: 0 9px; - border-right: 1px solid #ffffff; - border-left: 1px solid #f2f2f2; -} - -.navbar .btn, -.navbar .btn-group { - margin-top: 5px; -} - -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - margin-top: 0; -} - -.navbar-form { - margin-bottom: 0; - *zoom: 1; -} - -.navbar-form:before, -.navbar-form:after { - display: table; - line-height: 0; - content: ""; -} - -.navbar-form:after { - clear: both; -} - -.navbar-form input, -.navbar-form select, -.navbar-form .radio, -.navbar-form .checkbox { - margin-top: 5px; -} - -.navbar-form input, -.navbar-form select, -.navbar-form .btn { - display: inline-block; - margin-bottom: 0; -} - -.navbar-form input[type="image"], -.navbar-form input[type="checkbox"], -.navbar-form input[type="radio"] { - margin-top: 3px; -} - -.navbar-form .input-append, -.navbar-form .input-prepend { - margin-top: 5px; - white-space: nowrap; -} - -.navbar-form .input-append input, -.navbar-form .input-prepend input { - margin-top: 0; -} - -.navbar-search { - position: relative; - float: left; - margin-top: 5px; - margin-bottom: 0; -} - -.navbar-search .search-query { - padding: 4px 14px; - margin-bottom: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -.navbar-static-top { - position: static; - margin-bottom: 0; -} - -.navbar-static-top .navbar-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; - margin-bottom: 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} - -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-right: 0; - padding-left: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} - -.navbar-fixed-top { - top: 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); -} - -.navbar-fixed-bottom { - bottom: 0; -} - -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); - box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); -} - -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} - -.navbar .nav.pull-right { - float: right; - margin-right: 0; -} - -.navbar .nav > li { - float: left; -} - -.navbar .nav > li > a { - float: none; - padding: 10px 15px 10px; - color: #777777; - text-decoration: none; - text-shadow: 0 1px 0 #ffffff; -} - -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} - -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - color: #333333; - text-decoration: none; - background-color: transparent; -} - -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: #555555; - text-decoration: none; - background-color: #e5e5e5; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); -} - -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-right: 5px; - margin-left: 5px; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #ededed; - *background-color: #e5e5e5; - background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); - background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); - background-repeat: repeat-x; - border-color: #e5e5e5 #e5e5e5 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); -} - -.navbar .btn-navbar:hover, -.navbar .btn-navbar:focus, -.navbar .btn-navbar:active, -.navbar .btn-navbar.active, -.navbar .btn-navbar.disabled, -.navbar .btn-navbar[disabled] { - color: #ffffff; - background-color: #e5e5e5; - *background-color: #d9d9d9; -} - -.navbar .btn-navbar:active, -.navbar .btn-navbar.active { - background-color: #cccccc \9; -} - -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); -} - -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} - -.navbar .nav > li > .dropdown-menu:before { - position: absolute; - top: -7px; - left: 9px; - display: inline-block; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-left: 7px solid transparent; - border-bottom-color: rgba(0, 0, 0, 0.2); - content: ''; -} - -.navbar .nav > li > .dropdown-menu:after { - position: absolute; - top: -6px; - left: 10px; - display: inline-block; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - border-left: 6px solid transparent; - content: ''; -} - -.navbar-fixed-bottom .nav > li > .dropdown-menu:before { - top: auto; - bottom: -7px; - border-top: 7px solid #ccc; - border-bottom: 0; - border-top-color: rgba(0, 0, 0, 0.2); -} - -.navbar-fixed-bottom .nav > li > .dropdown-menu:after { - top: auto; - bottom: -6px; - border-top: 6px solid #ffffff; - border-bottom: 0; -} - -.navbar .nav li.dropdown > a:hover .caret, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: #333333; - border-bottom-color: #333333; -} - -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - color: #555555; - background-color: #e5e5e5; -} - -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} - -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu:before, -.navbar .nav > li > .dropdown-menu.pull-right:before { - right: 12px; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu:after, -.navbar .nav > li > .dropdown-menu.pull-right:after { - right: 13px; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { - right: 100%; - left: auto; - margin-right: -1px; - margin-left: 0; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} - -.navbar-inverse .navbar-inner { - background-color: #1b1b1b; - background-image: -moz-linear-gradient(top, #222222, #111111); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); - background-image: -webkit-linear-gradient(top, #222222, #111111); - background-image: -o-linear-gradient(top, #222222, #111111); - background-image: linear-gradient(to bottom, #222222, #111111); - background-repeat: repeat-x; - border-color: #252525; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); -} - -.navbar-inverse .brand, -.navbar-inverse .nav > li > a { - color: #999999; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} - -.navbar-inverse .brand:hover, -.navbar-inverse .nav > li > a:hover, -.navbar-inverse .brand:focus, -.navbar-inverse .nav > li > a:focus { - color: #ffffff; -} - -.navbar-inverse .brand { - color: #999999; -} - -.navbar-inverse .navbar-text { - color: #999999; -} - -.navbar-inverse .nav > li > a:focus, -.navbar-inverse .nav > li > a:hover { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .nav .active > a, -.navbar-inverse .nav .active > a:hover, -.navbar-inverse .nav .active > a:focus { - color: #ffffff; - background-color: #111111; -} - -.navbar-inverse .navbar-link { - color: #999999; -} - -.navbar-inverse .navbar-link:hover, -.navbar-inverse .navbar-link:focus { - color: #ffffff; -} - -.navbar-inverse .divider-vertical { - border-right-color: #222222; - border-left-color: #111111; -} - -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { - color: #ffffff; - background-color: #111111; -} - -.navbar-inverse .nav li.dropdown > a:hover .caret, -.navbar-inverse .nav li.dropdown > a:focus .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} - -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .navbar-search .search-query { - color: #ffffff; - background-color: #515151; - border-color: #111111; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} - -.navbar-inverse .navbar-search .search-query:-moz-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query:focus, -.navbar-inverse .navbar-search .search-query.focused { - padding: 5px 15px; - color: #333333; - text-shadow: 0 1px 0 #ffffff; - background-color: #ffffff; - border: 0; - outline: 0; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -} - -.navbar-inverse .btn-navbar { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e0e0e; - *background-color: #040404; - background-image: -moz-linear-gradient(top, #151515, #040404); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); - background-image: -webkit-linear-gradient(top, #151515, #040404); - background-image: -o-linear-gradient(top, #151515, #040404); - background-image: linear-gradient(to bottom, #151515, #040404); - background-repeat: repeat-x; - border-color: #040404 #040404 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.navbar-inverse .btn-navbar:hover, -.navbar-inverse .btn-navbar:focus, -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active, -.navbar-inverse .btn-navbar.disabled, -.navbar-inverse .btn-navbar[disabled] { - color: #ffffff; - background-color: #040404; - *background-color: #000000; -} - -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active { - background-color: #000000 \9; -} - -.breadcrumb { - padding: 8px 15px; - margin: 0 0 20px; - list-style: none; - background-color: #f5f5f5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.breadcrumb > li { - display: inline-block; - *display: inline; - text-shadow: 0 1px 0 #ffffff; - *zoom: 1; -} - -.breadcrumb > li > .divider { - padding: 0 5px; - color: #ccc; -} - -.breadcrumb > .active { - color: #999999; -} - -.pagination { - margin: 20px 0; -} - -.pagination ul { - display: inline-block; - *display: inline; - margin-bottom: 0; - margin-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - *zoom: 1; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.pagination ul > li { - display: inline; -} - -.pagination ul > li > a, -.pagination ul > li > span { - float: left; - padding: 4px 12px; - line-height: 20px; - text-decoration: none; - background-color: #ffffff; - border: 1px solid #dddddd; - border-left-width: 0; -} - -.pagination ul > li > a:hover, -.pagination ul > li > a:focus, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: #f5f5f5; -} - -.pagination ul > .active > a, -.pagination ul > .active > span { - color: #999999; - cursor: default; -} - -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover, -.pagination ul > .disabled > a:focus { - color: #999999; - cursor: default; - background-color: transparent; -} - -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} - -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; -} - -.pagination-centered { - text-align: center; -} - -.pagination-right { - text-align: right; -} - -.pagination-large ul > li > a, -.pagination-large ul > li > span { - padding: 11px 19px; - font-size: 17.5px; -} - -.pagination-large ul > li:first-child > a, -.pagination-large ul > li:first-child > span { - -webkit-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -webkit-border-top-left-radius: 6px; - border-top-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - -moz-border-radius-topleft: 6px; -} - -.pagination-large ul > li:last-child > a, -.pagination-large ul > li:last-child > span { - -webkit-border-top-right-radius: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - -moz-border-radius-topright: 6px; - -moz-border-radius-bottomright: 6px; -} - -.pagination-mini ul > li:first-child > a, -.pagination-small ul > li:first-child > a, -.pagination-mini ul > li:first-child > span, -.pagination-small ul > li:first-child > span { - -webkit-border-bottom-left-radius: 3px; - border-bottom-left-radius: 3px; - -webkit-border-top-left-radius: 3px; - border-top-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - -moz-border-radius-topleft: 3px; -} - -.pagination-mini ul > li:last-child > a, -.pagination-small ul > li:last-child > a, -.pagination-mini ul > li:last-child > span, -.pagination-small ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - border-bottom-right-radius: 3px; - -moz-border-radius-topright: 3px; - -moz-border-radius-bottomright: 3px; -} - -.pagination-small ul > li > a, -.pagination-small ul > li > span { - padding: 2px 10px; - font-size: 11.9px; -} - -.pagination-mini ul > li > a, -.pagination-mini ul > li > span { - padding: 0 6px; - font-size: 10.5px; -} - -.pager { - margin: 20px 0; - text-align: center; - list-style: none; - *zoom: 1; -} - -.pager:before, -.pager:after { - display: table; - line-height: 0; - content: ""; -} - -.pager:after { - clear: both; -} - -.pager li { - display: inline; -} - -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #f5f5f5; -} - -.pager .next > a, -.pager .next > span { - float: right; -} - -.pager .previous > a, -.pager .previous > span { - float: left; -} - -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999999; - cursor: default; - background-color: #fff; -} - -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; -} - -.modal-backdrop.fade { - opacity: 0; -} - -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.8; - filter: alpha(opacity=80); -} - -.modal { - position: fixed; - top: 10%; - left: 50%; - z-index: 1050; - width: 560px; - margin-left: -280px; - background-color: #ffffff; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -.modal.fade { - top: -25%; - -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; - -moz-transition: opacity 0.3s linear, top 0.3s ease-out; - -o-transition: opacity 0.3s linear, top 0.3s ease-out; - transition: opacity 0.3s linear, top 0.3s ease-out; -} - -.modal.fade.in { - top: 10%; -} - -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; -} - -.modal-header .close { - margin-top: 2px; -} - -.modal-header h3 { - margin: 0; - line-height: 30px; -} - -.modal-body { - position: relative; - max-height: 400px; - padding: 15px; - overflow-y: auto; -} - -.modal-form { - margin-bottom: 0; -} - -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 #ffffff; - -moz-box-shadow: inset 0 1px 0 #ffffff; - box-shadow: inset 0 1px 0 #ffffff; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - line-height: 0; - content: ""; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} - -.tooltip { - position: absolute; - z-index: 1030; - display: block; - font-size: 11px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} - -.tooltip.top { - padding: 5px 0; - margin-top: -3px; -} - -.tooltip.right { - padding: 0 5px; - margin-left: 3px; -} - -.tooltip.bottom { - padding: 5px 0; - margin-top: 3px; -} - -.tooltip.left { - padding: 0 5px; - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-right-color: #000000; - border-width: 5px 5px 5px 0; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-left-color: #000000; - border-width: 5px 0 5px 5px; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - white-space: normal; - background-color: #ffffff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -.popover.top { - margin-top: -10px; -} - -.popover.right { - margin-left: 10px; -} - -.popover.bottom { - margin-top: 10px; -} - -.popover.left { - margin-left: -10px; -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} - -.popover-title:empty { - display: none; -} - -.popover-content { - padding: 9px 14px; -} - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.popover .arrow { - border-width: 11px; -} - -.popover .arrow:after { - border-width: 10px; - content: ""; -} - -.popover.top .arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999; - border-top-color: rgba(0, 0, 0, 0.25); - border-bottom-width: 0; -} - -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-top-color: #ffffff; - border-bottom-width: 0; -} - -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999; - border-right-color: rgba(0, 0, 0, 0.25); - border-left-width: 0; -} - -.popover.right .arrow:after { - bottom: -10px; - left: 1px; - border-right-color: #ffffff; - border-left-width: 0; -} - -.popover.bottom .arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-bottom-color: #999; - border-bottom-color: rgba(0, 0, 0, 0.25); - border-top-width: 0; -} - -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-bottom-color: #ffffff; - border-top-width: 0; -} - -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-left-color: #999; - border-left-color: rgba(0, 0, 0, 0.25); - border-right-width: 0; -} - -.popover.left .arrow:after { - right: 1px; - bottom: -10px; - border-left-color: #ffffff; - border-right-width: 0; -} - -.thumbnails { - margin-left: -20px; - list-style: none; - *zoom: 1; -} - -.thumbnails:before, -.thumbnails:after { - display: table; - line-height: 0; - content: ""; -} - -.thumbnails:after { - clear: both; -} - -.row-fluid .thumbnails { - margin-left: 0; -} - -.thumbnails > li { - float: left; - margin-bottom: 20px; - margin-left: 20px; -} - -.thumbnail { - display: block; - padding: 4px; - line-height: 20px; - border: 1px solid #ddd; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #0088cc; - -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -} - -.thumbnail > img { - display: block; - max-width: 100%; - margin-right: auto; - margin-left: auto; -} - -.thumbnail .caption { - padding: 9px; - color: #555555; -} - -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} - -.media, -.media .media { - margin-top: 15px; -} - -.media:first-child { - margin-top: 0; -} - -.media-object { - display: block; -} - -.media-heading { - margin: 0 0 5px; -} - -.media > .pull-left { - margin-right: 10px; -} - -.media > .pull-right { - margin-left: 10px; -} - -.media-list { - margin-left: 0; - list-style: none; -} - -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: 11.844px; - font-weight: bold; - line-height: 14px; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - white-space: nowrap; - vertical-align: baseline; - background-color: #999999; -} - -.label { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.badge { - padding-right: 9px; - padding-left: 9px; - -webkit-border-radius: 9px; - -moz-border-radius: 9px; - border-radius: 9px; -} - -.label:empty, -.badge:empty { - display: none; -} - -a.label:hover, -a.label:focus, -a.badge:hover, -a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.label-important, -.badge-important { - background-color: #b94a48; -} - -.label-important[href], -.badge-important[href] { - background-color: #953b39; -} - -.label-warning, -.badge-warning { - background-color: #f89406; -} - -.label-warning[href], -.badge-warning[href] { - background-color: #c67605; -} - -.label-success, -.badge-success { - background-color: #468847; -} - -.label-success[href], -.badge-success[href] { - background-color: #356635; -} - -.label-info, -.badge-info { - background-color: #3a87ad; -} - -.label-info[href], -.badge-info[href] { - background-color: #2d6987; -} - -.label-inverse, -.badge-inverse { - background-color: #333333; -} - -.label-inverse[href], -.badge-inverse[href] { - background-color: #1a1a1a; -} - -.btn .label, -.btn .badge { - position: relative; - top: -1px; -} - -.btn-mini .label, -.btn-mini .badge { - top: 0; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-ms-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -.progress { - height: 20px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); - background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); - background-repeat: repeat-x; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.progress .bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - color: #ffffff; - text-align: center; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top, #149bdf, #0480be); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); - background-image: -webkit-linear-gradient(top, #149bdf, #0480be); - background-image: -o-linear-gradient(top, #149bdf, #0480be); - background-image: linear-gradient(to bottom, #149bdf, #0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width 0.6s ease; - -moz-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress .bar + .bar { - -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); -} - -.progress-striped .bar { - background-color: #149bdf; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} - -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-danger .bar, -.progress .bar-danger { - background-color: #dd514c; - background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); - background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); -} - -.progress-danger.progress-striped .bar, -.progress-striped .bar-danger { - background-color: #ee5f5b; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-success .bar, -.progress .bar-success { - background-color: #5eb95e; - background-image: -moz-linear-gradient(top, #62c462, #57a957); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); - background-image: -webkit-linear-gradient(top, #62c462, #57a957); - background-image: -o-linear-gradient(top, #62c462, #57a957); - background-image: linear-gradient(to bottom, #62c462, #57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); -} - -.progress-success.progress-striped .bar, -.progress-striped .bar-success { - background-color: #62c462; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-info .bar, -.progress .bar-info { - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); - background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); - background-image: -o-linear-gradient(top, #5bc0de, #339bb9); - background-image: linear-gradient(to bottom, #5bc0de, #339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); -} - -.progress-info.progress-striped .bar, -.progress-striped .bar-info { - background-color: #5bc0de; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-warning .bar, -.progress .bar-warning { - background-color: #faa732; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); -} - -.progress-warning.progress-striped .bar, -.progress-striped .bar-warning { - background-color: #fbb450; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.accordion { - margin-bottom: 20px; -} - -.accordion-group { - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.accordion-heading { - border-bottom: 0; -} - -.accordion-heading .accordion-toggle { - display: block; - padding: 8px 15px; -} - -.accordion-toggle { - cursor: pointer; -} - -.accordion-inner { - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} - -.carousel { - position: relative; - margin-bottom: 20px; - line-height: 1; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #ffffff; - text-align: center; - background: #222222; - border: 3px solid #ffffff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.right { - right: 15px; - left: auto; -} - -.carousel-control:hover, -.carousel-control:focus { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; -} - -.carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255, 255, 255, 0.25); - border-radius: 5px; -} - -.carousel-indicators .active { - background-color: #fff; -} - -.carousel-caption { - position: absolute; - right: 0; - bottom: 0; - left: 0; - padding: 15px; - background: #333333; - background: rgba(0, 0, 0, 0.75); -} - -.carousel-caption h4, -.carousel-caption p { - line-height: 20px; - color: #ffffff; -} - -.carousel-caption h4 { - margin: 0 0 5px; -} - -.carousel-caption p { - margin-bottom: 0; -} - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: #eeeeee; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; -} - -.hero-unit li { - line-height: 30px; -} - -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -.hide { - display: none; -} - -.show { - display: block; -} - -.invisible { - visibility: hidden; -} - -.affix { - position: fixed; -} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.min.css b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.min.css deleted file mode 100644 index b6428e6..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/css/bootstrap.min.css +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Bootstrap v2.3.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484..0000000 Binary files a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings-white.png and /dev/null differ diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings.png b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings.png deleted file mode 100644 index a996999..0000000 Binary files a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/img/glyphicons-halflings.png and /dev/null differ diff --git a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/js/bootstrap.js b/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/js/bootstrap.js deleted file mode 100644 index 638bb18..0000000 --- a/docs/firebird-base.docset/Contents/Resources/Documents/_static/bootstrap-2.3.2/js/bootstrap.js +++ /dev/null @@ -1,2287 +0,0 @@ -/* =================================================== - * bootstrap-transition.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#transitions - * =================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) - * ======================================================= */ - - $(function () { - - $.support.transition = (function () { - - var transitionEnd = (function () { - - var el = document.createElement('bootstrap') - , transEndEventNames = { - 'WebkitTransition' : 'webkitTransitionEnd' - , 'MozTransition' : 'transitionend' - , 'OTransition' : 'oTransitionEnd otransitionend' - , 'transition' : 'transitionend' - } - , name - - for (name in transEndEventNames){ - if (el.style[name] !== undefined) { - return transEndEventNames[name] - } - } - - }()) - - return transitionEnd && { - end: transitionEnd - } - - })() - - }) - -}(window.$jqTheme || window.jQuery); -/* ========================================================== - * bootstrap-alert.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#alerts - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* ALERT CLASS DEFINITION - * ====================== */ - - var dismiss = '[data-dismiss="alert"]' - , Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - - e && e.preventDefault() - - $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) - - $parent.trigger(e = $.Event('close')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent - .trigger('closed') - .remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent.on($.support.transition.end, removeElement) : - removeElement() - } - - - /* ALERT PLUGIN DEFINITION - * ======================= */ - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('alert') - if (!data) $this.data('alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - /* ALERT NO CONFLICT - * ================= */ - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - /* ALERT DATA-API - * ============== */ - - $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) - -}(window.$jqTheme || window.jQuery); -/* ============================================================ - * bootstrap-button.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#buttons - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* BUTTON PUBLIC CLASS DEFINITION - * ============================== */ - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.button.defaults, options) - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - , $el = this.$element - , data = $el.data() - , val = $el.is('input') ? 'val' : 'html' - - state = state + 'Text' - data.resetText || $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d) - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons-radio"]') - - $parent && $parent - .find('.active') - .removeClass('active') - - this.$element.toggleClass('active') - } - - - /* BUTTON PLUGIN DEFINITION - * ======================== */ - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('button') - , options = typeof option == 'object' && option - if (!data) $this.data('button', (data = new Button(this, options))) - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.defaults = { - loadingText: 'loading...' - } - - $.fn.button.Constructor = Button - - - /* BUTTON NO CONFLICT - * ================== */ - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - /* BUTTON DATA-API - * =============== */ - - $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - }) - -}(window.$jqTheme || window.jQuery); -/* ========================================================== - * bootstrap-carousel.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#carousel - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* CAROUSEL CLASS DEFINITION - * ========================= */ - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.prototype = { - - cycle: function (e) { - if (!e) this.paused = false - if (this.interval) clearInterval(this.interval); - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - return this - } - - , getActiveIndex: function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - return this.$items.index(this.$active) - } - - , to: function (pos) { - var activeIndex = this.getActiveIndex() - , that = this - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) { - return this.$element.one('slid', function () { - that.to(pos) - }) - } - - if (activeIndex == pos) { - return this.pause().cycle() - } - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - , pause: function (e) { - if (!e) this.paused = true - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - clearInterval(this.interval) - this.interval = null - return this - } - - , next: function () { - if (this.sliding) return - return this.slide('next') - } - - , prev: function () { - if (this.sliding) return - return this.slide('prev') - } - - , slide: function (type, next) { - var $active = this.$element.find('.item.active') - , $next = next || $active[type]() - , isCycling = this.interval - , direction = type == 'next' ? 'left' : 'right' - , fallback = type == 'next' ? 'first' : 'last' - , that = this - , e - - this.sliding = true - - isCycling && this.pause() - - $next = $next.length ? $next : this.$element.find('.item')[fallback]() - - e = $.Event('slide', { - relatedTarget: $next[0] - , direction: direction - }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - this.$element.one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - } - - - /* CAROUSEL PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('carousel') - , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) - , action = typeof option == 'string' ? option : options.slide - if (!data) $this.data('carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - $.fn.carousel.defaults = { - interval: 5000 - , pause: 'hover' - } - - $.fn.carousel.Constructor = Carousel - - - /* CAROUSEL NO CONFLICT - * ==================== */ - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - /* CAROUSEL DATA-API - * ================= */ - - $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - , options = $.extend({}, $target.data(), $this.data()) - , slideIndex - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('carousel').pause().to(slideIndex).cycle() - } - - e.preventDefault() - }) - -}(window.$jqTheme || window.jQuery); -/* ============================================================= - * bootstrap-collapse.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#collapse - * ============================================================= - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* COLLAPSE PUBLIC CLASS DEFINITION - * ================================ */ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) - - if (this.options.parent) { - this.$parent = $(this.options.parent) - } - - this.options.toggle && this.toggle() - } - - Collapse.prototype = { - - constructor: Collapse - - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - , show: function () { - var dimension - , scroll - , actives - , hasData - - if (this.transitioning || this.$element.hasClass('in')) return - - dimension = this.dimension() - scroll = $.camelCase(['scroll', dimension].join('-')) - actives = this.$parent && this.$parent.find('> .accordion-group > .in') - - if (actives && actives.length) { - hasData = actives.data('collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('collapse', null) - } - - this.$element[dimension](0) - this.transition('addClass', $.Event('show'), 'shown') - $.support.transition && this.$element[dimension](this.$element[0][scroll]) - } - - , hide: function () { - var dimension - if (this.transitioning || !this.$element.hasClass('in')) return - dimension = this.dimension() - this.reset(this.$element[dimension]()) - this.transition('removeClass', $.Event('hide'), 'hidden') - this.$element[dimension](0) - } - - , reset: function (size) { - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth - - this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') - - return this - } - - , transition: function (method, startEvent, completeEvent) { - var that = this - , complete = function () { - if (startEvent.type == 'show') that.reset() - that.transitioning = 0 - that.$element.trigger(completeEvent) - } - - this.$element.trigger(startEvent) - - if (startEvent.isDefaultPrevented()) return - - this.transitioning = 1 - - this.$element[method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , toggle: function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - } - - - /* COLLAPSE PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('collapse') - , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.defaults = { - toggle: true - } - - $.fn.collapse.Constructor = Collapse - - - /* COLLAPSE NO CONFLICT - * ==================== */ - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - /* COLLAPSE DATA-API - * ================= */ - - $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - , target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() - $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - $(target).collapse(option) - }) - -}(window.$jqTheme || window.jQuery); -/* ============================================================ - * bootstrap-dropdown.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function (e) { - var $this = $(this) - , $parent - , isActive - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement) { - // if mobile we we use a backdrop because click events don't delegate - $('