diff --git a/README.md b/README.md index ebe7307..0a97b87 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,148 @@ -# ApiWrapper - -TODO: Delete this and the text below, and describe your gem - -Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/api_wrapper`. To experiment with that code, run `bin/console` for an interactive prompt. +`ApiWrapper` is a Ruby gem that offers an easy and flexible way to handle API interactions. + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) + - [Basic Usage](#basic-usage) + - [Custom Configuration](#custom-configuration) + - [Resetting the API Manager](#resetting-the-api-manager) +- [Configuration](#configuration) + - [API Configuration File](#api-configuration-file) +- [Key Methods](#key-methods) +- [Development](#development) + - [Running Tests](#running-tests) + - [Code Style and Linting](#code-style-and-linting) +- [Contributing](#contributing) +- [License](#license) +- [Code of Conduct](#code-of-conduct) ## Installation -TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org. +Add this to your Gemfile: -Install the gem and add to the application's Gemfile by executing: - $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG +```ruby +gem 'api_wrapper' +``` -If bundler is not being used to manage dependencies, install the gem by executing: +Then run - $ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG +```ruby +bundle install +``` ## Usage -TODO: Write usage instructions here +### Basic Usage +By default, ApiWrapper looks for an API configuration file at `config/api_endpoints.yml` (see [API Configuration File](#api-configuration-file)) in your root directory of your application and uses in-memory caching. You can fetch data from an API endpoint like this: + +```ruby +require 'api_wrapper' + +# Fetch data from an API endpoint using the default settings +response = ApiWrapper.fetch_data('endpoint_key') +puts response.body +``` + +### Custom Configuration +You can customize the API configuration path and cache store by configuring ApiWrapper: + +```ruby +require 'api_wrapper' + +# Configure ApiWrapper with custom settings +ApiWrapper.configure do |config| + config.api_configuration_path = 'custom/path/to/api_configuration.yml' + config.cache_store = CustomCacheStore.new # TODO: Update details on CustomCacheStore later +end + +# Fetch data with the custom configuration +response = ApiWrapper.fetch_data('endpoint_key') +puts response.body +``` + +### Resetting the API Manager +If you change the configuration and want to reset the API manager, call: +```ruby +ApiWrapper.reset_api_manager! +``` +This will create a new instance of ApiManager with the updated settings. + +## Configuration +You can adjust two main settings: + +1. **API Configuration Path**: This is the path to the YAML file that defines your API endpoints. By default, it’s set to config/api_endpoints.yml. You can also set it through the environment variable ENV['API_CONFIGURATION_PATH']. + +2. **Cache Store**: This is where API responses are stored. By default, ApiWrapper uses an in-memory cache. You can customize this to use a different cache store, such as Redis. You can also set the cache type through ENV['CACHE_STORE_TYPE']. + +### API Configuration File +Your configuration file (api_endpoints.yml) defines the base URL for the API and the available endpoints. Here’s an example: + +```yaml +base_url: https://api.example.com/ +apis: + endpoint1: + path: 'path/to/endpoint1' + description: 'Endpoint 1 description' + no_cache: true + endpoint2: + path: 'path/to/endpoint2' + description: 'Endpoint 2 description' + ttl: 600 +``` + +- base_url: The base URL for all API requests. +- apis: A list of API endpoints. + - path: The path to the API endpoint. + - description: (Optional) The description about the endpoint + - ttl: (Optional) The time (in seconds) that data should be cached. + - no_cache: (Optional) Whether to bypass caching for this endpoint. + +## Key Methods +- `ApiWrapper.fetch_data(endpoint_key, force_refresh: false)`: Fetches data from the specified API endpoint. +- `ApiWrapper.configure { |config| ... }`: Allows you to configure the gem with custom settings. +- `ApiWrapper.reset_api_manager!`: Resets the ApiManager instance, which will use any new settings. ## Development -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. +To get started with contributing to **ApiWrapper**, follow these steps: + +1. **Clone the repository**: + + First, clone the repository to your local machine and navigate to the project directory: + + ```bash + git clone https://github.com/ahasunos/api_wrapper.git + cd api_wrapper + +2. **Install dependencies**: + + After navigating to the project directory, install the required gems using Bundler: + + ```bash + bundle install + ``` + +### Running Tests +The project uses RSpec for testing. Before submitting any changes, make sure to run the test suite to ensure that everything works as expected: + +```bash +bundle exec rspec +``` + +### Code Style and Linting +To maintain consistent code quality and style, the project uses RuboCop for linting. Before submitting a pull request, ensure that your code adheres to the project's style guidelines by running RuboCop: + +```bash +bundle exec rubocop +``` -To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). +If RuboCop identifies any issues, it will provide suggestions for how to fix them. ## Contributing -Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/api_wrapper. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/api_wrapper/blob/master/CODE_OF_CONDUCT.md). +Bug reports and pull requests are welcome on GitHub at https://github.com/ahasunos/api_wrapper. For major changes, please open an issue first to discuss what you would like to change. ## License @@ -36,4 +150,4 @@ The gem is available as open source under the terms of the [MIT License](https:/ ## Code of Conduct -Everyone interacting in the ApiWrapper project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/api_wrapper/blob/master/CODE_OF_CONDUCT.md). +Everyone interacting in the NseData project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/ahasunos/api_wrapper/blob/master/CODE_OF_CONDUCT.md). diff --git a/api_wrapper.gemspec b/api_wrapper.gemspec index 4baa712..8f44780 100644 --- a/api_wrapper.gemspec +++ b/api_wrapper.gemspec @@ -12,9 +12,7 @@ Gem::Specification.new do |spec| spec.description = 'ApiWrapper provides an easy-to-use interface for interacting with APIs in a configurable way' spec.homepage = 'https://github.com/ahasunos/api_wrapper' spec.license = 'MIT' - spec.required_ruby_version = '>= 2.6.0' - - spec.metadata['allowed_push_host'] = "TODO: Set to your gem server 'https://example.com'" + spec.required_ruby_version = '>= 3.1.0' spec.metadata['homepage_uri'] = spec.homepage spec.metadata['source_code_uri'] = 'https://github.com/ahasunos/api_wrapper' diff --git a/doc/ApiWrapper.html b/doc/ApiWrapper.html new file mode 100644 index 0000000..a308d3d --- /dev/null +++ b/doc/ApiWrapper.html @@ -0,0 +1,543 @@ + + + + + + + Module: ApiWrapper + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: ApiWrapper + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper.rb,
+ lib/api_wrapper/version.rb,
lib/api_wrapper/api_manager.rb,
lib/api_wrapper/cache/cache_store.rb,
lib/api_wrapper/cache/cache_policy.rb,
lib/api_wrapper/http_client/base_client.rb,
lib/api_wrapper/http_client/faraday_client.rb
+
+
+ +
+ +

Overview

+
+ +

ApiWrapper provides a unified interface for managing API interactions and caching.

+ +

It simplifies API management and caching with sensible defaults and customization options.

+ +

Usage:

+ +
# Fetch data using default configuration
+response = ApiWrapper.fetch_data('endpoint_key')
+puts response.body
+
+# Configure with custom settings
+ApiWrapper.configure do |config|
+  config.api_configuration_path = 'custom/path/to/config.yml'
+  config.cache_store = CustomCacheStore.new
+end
+response = ApiWrapper.fetch_data('endpoint_key')
+puts response.body
+
+ + +
+
+
+ + +

Defined Under Namespace

+

+ + + Modules: Cache, HttpClient + + + + Classes: ApiManager, Configuration + + +

+ + +

+ Constant Summary + collapse +

+ +
+ +
VERSION = + +
+
'0.1.5'
+ +
+ + + + + + + + + +

+ Class Method Summary + collapse +

+ + + + + + +
+

Class Method Details

+ + +
+

+ + .api_managerObject + + + + + +

+
+ +

Returns the singleton ApiManager instance

+ + +
+
+
+ + +
+ + + + +
+
+
+
+66
+67
+68
+69
+70
+71
+
+
# File 'lib/api_wrapper.rb', line 66
+
+def api_manager
+  @api_manager ||= begin
+    config = configuration
+    ApiManager.new(config.api_configuration_path, cache_store: config.cache_store)
+  end
+end
+
+
+ +
+

+ + .configurationObject + + + + + +

+
+ +

Accesses the configuration instance, initializing if needed

+ + +
+
+
+ + +
+ + + + +
+
+
+
+53
+54
+55
+
+
# File 'lib/api_wrapper.rb', line 53
+
+def configuration
+  @configuration ||= Configuration.new
+end
+
+
+ +
+

+ + .configure {|configuration| ... } ⇒ Object + + + + + +

+
+ +

Configures ApiWrapper with a block

+ + +
+
+
+ +

Yields:

+ +

Raises:

+
    + +
  • + + + (ArgumentError) + + + +
  • + +
+ +
+ + + + +
+
+
+
+58
+59
+60
+61
+62
+63
+
+
# File 'lib/api_wrapper.rb', line 58
+
+def configure
+  raise ArgumentError, 'Configuration block required' unless block_given?
+
+  yield(configuration)
+  reset_api_manager!
+end
+
+
+ +
+

+ + .fetch_data(endpoint_key, force_refresh: false) ⇒ Object + + + + + +

+
+ +

Fetches data from the specified endpoint

+ + +
+
+
+ + +
+ + + + +
+
+
+
+74
+75
+76
+
+
# File 'lib/api_wrapper.rb', line 74
+
+def fetch_data(endpoint_key, force_refresh: false)
+  api_manager.fetch_data(endpoint_key, force_refresh:)
+end
+
+
+ +
+

+ + .reset_api_manager!Object + + + + + +

+
+ +

Resets the ApiManager instance

+ + +
+
+
+ + +
+ + + + +
+
+
+
+79
+80
+81
+
+
# File 'lib/api_wrapper.rb', line 79
+
+def reset_api_manager!
+  @api_manager = nil
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/ApiManager.html b/doc/ApiWrapper/ApiManager.html new file mode 100644 index 0000000..d365395 --- /dev/null +++ b/doc/ApiWrapper/ApiManager.html @@ -0,0 +1,807 @@ + + + + + + + Class: ApiWrapper::ApiManager + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::ApiManager + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/api_manager.rb
+
+ +
+ +

Overview

+
+ +

ApiManager is responsible for managing API interactions, including fetching data from endpoints and handling caching behavior.

+ +

It supports configuration of caching policies, including specifying endpoints that should bypass the cache and setting custom TTL (time-to-live) values for individual endpoints. The class uses a Faraday client for making HTTP requests and integrates with a cache store for storing and retrieving cached data.

+ +

Usage:

+ +
api_manager = ApiWrapper::ApiManager.new('path/to/api_configuration.yml')
+
+response = api_manager.fetch_data('endpoint_key')
+puts response.body
+
+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(api_configuration_path, cache_store: nil) ⇒ ApiManager + + + + + +

+
+ +

Initializes a new instance of the ApiManager class.

+ +

Defaults to in-memory cache if nil.

+ + +
+
+
+

Parameters:

+
    + +
  • + + api_configuration_path + + + (String) + + + + — +
    +

    Path to the API configuration file.

    +
    + +
  • + +
  • + + cache_store + + + (CacheStore, RedisCacheStore, nil) + + + (defaults to: nil) + + + — +
    +

    The cache store to use for caching.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+
+
# File 'lib/api_wrapper/api_manager.rb', line 33
+
+def initialize(api_configuration_path, cache_store: nil)
+  load_api_configuration(api_configuration_path)
+
+  # Initialize cache policy
+  @cache_policy = ApiWrapper::Cache::CachePolicy.new(cache_store || ApiWrapper::Cache::CacheStore.new)
+
+  # Configure cache policy
+  configure_cache_policy
+
+  # Initialize Faraday client
+  @client = ApiWrapper::HttpClient::FaradayClient.new(@base_url, @cache_policy)
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #base_urlString (readonly) + + + + + +

+
+ +

The base URL for API requests.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +
    +

    the current value of base_url

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/api_wrapper/api_manager.rb', line 27
+
+def base_url
+  @base_url
+end
+
+
+ + + +
+

+ + #cache_policyCachePolicy (readonly) + + + + + +

+
+ +

The cache policy used for caching data.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (CachePolicy) + + + + — +
    +

    the current value of cache_policy

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/api_wrapper/api_manager.rb', line 27
+
+def cache_policy
+  @cache_policy
+end
+
+
+ + + +
+

+ + #clientFaradayClient (readonly) + + + + + +

+
+ +

The Faraday client used for making HTTP requests.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (FaradayClient) + + + + — +
    +

    the current value of client

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/api_wrapper/api_manager.rb', line 27
+
+def client
+  @client
+end
+
+
+ + + +
+

+ + #endpointsHash (readonly) + + + + + +

+
+ +

The endpoints configuration loaded from the API configuration file.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (Hash) + + + + — +
    +

    the current value of endpoints

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+27
+28
+29
+
+
# File 'lib/api_wrapper/api_manager.rb', line 27
+
+def endpoints
+  @endpoints
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #fetch_data(endpoint_key, force_refresh: false) ⇒ Faraday::Response + + + + + +

+
+ +

Fetches data from the specified API endpoint.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint_key + + + (String) + + + + — +
    +

    The key of the API endpoint to fetch data from.

    +
    + +
  • + +
  • + + force_refresh + + + (Boolean) + + + (defaults to: false) + + + — +
    +

    Whether to force refresh the data, bypassing the cache.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Faraday::Response) + + + + — +
    +

    The response object containing the fetched data.

    +
    + +
  • + +
+

Raises:

+
    + +
  • + + + (ArgumentError) + + + + — +
    +

    If the provided endpoint key is invalid.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+52
+53
+54
+55
+56
+57
+58
+59
+
+
# File 'lib/api_wrapper/api_manager.rb', line 52
+
+def fetch_data(endpoint_key, force_refresh: false)
+  endpoint = @endpoints[endpoint_key]
+  raise ArgumentError, "Invalid endpoint key: #{endpoint_key}" unless endpoint
+
+  @cache_policy.fetch(endpoint['path'], force_refresh:) do
+    @client.get(endpoint['path'])
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/Cache.html b/doc/ApiWrapper/Cache.html new file mode 100644 index 0000000..c2783ba --- /dev/null +++ b/doc/ApiWrapper/Cache.html @@ -0,0 +1,117 @@ + + + + + + + Module: ApiWrapper::Cache + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: ApiWrapper::Cache + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/cache/cache_store.rb,
+ lib/api_wrapper/cache/cache_policy.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: CachePolicy, CacheStore + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/Cache/CachePolicy.html b/doc/ApiWrapper/Cache/CachePolicy.html new file mode 100644 index 0000000..2c0648a --- /dev/null +++ b/doc/ApiWrapper/Cache/CachePolicy.html @@ -0,0 +1,907 @@ + + + + + + + Class: ApiWrapper::Cache::CachePolicy + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::Cache::CachePolicy + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/cache/cache_policy.rb
+
+ +
+ +

Overview

+
+ +

CachePolicy manages caching behavior, including cache storage and time-to-live (TTL) settings.

+ +

It allows setting global TTLs, custom TTLs for specific endpoints, and controlling which endpoints should not use the cache.

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(cache_store, global_ttl = 300) ⇒ CachePolicy + + + + + +

+
+ +

Initializes the CachePolicy with a cache store and global TTL.

+ + +
+
+
+

Parameters:

+
    + +
  • + + cache_store + + + (CacheStore, RedisCacheStore) + + + + — +
    +

    The cache store to use for caching.

    +
    + +
  • + +
  • + + global_ttl + + + (Integer) + + + (defaults to: 300) + + + — +
    +

    The default TTL (in seconds) for caching.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+18
+19
+20
+21
+22
+23
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 18
+
+def initialize(cache_store, global_ttl = 300)
+  @cache_store = cache_store
+  @global_ttl = global_ttl
+  @custom_ttls = {}
+  @no_cache_endpoints = []
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #cache_storeCacheStore (readonly) + + + + + +

+
+ +

The cache store used for storing cached data.

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (CacheStore) + + + + — +
    +

    the current value of cache_store

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+11
+12
+13
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 11
+
+def cache_store
+  @cache_store
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #add_custom_ttl(endpoint, ttl = 300) ⇒ Object + + + + + +

+
+ +

Adds a custom TTL for a specific endpoint.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to apply a custom TTL to.

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + (defaults to: 300) + + + — +
    +

    The custom TTL value in seconds.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+36
+37
+38
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 36
+
+def add_custom_ttl(endpoint, ttl = 300)
+  @custom_ttls[endpoint] = ttl
+end
+
+
+ +
+

+ + #add_no_cache_endpoint(endpoint) ⇒ Object + + + + + +

+
+ +

Adds an endpoint that should bypass the cache.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to exclude from caching.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+28
+29
+30
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 28
+
+def add_no_cache_endpoint(endpoint)
+  @no_cache_endpoints << endpoint
+end
+
+
+ +
+

+ + #fetch(endpoint, force_refresh: false) { ... } ⇒ Object + + + + + +

+
+ +

Fetches the data for the given endpoint, using cache if applicable.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to fetch data for.

    +
    + +
  • + +
  • + + force_refresh + + + (Boolean) + + + (defaults to: false) + + + — +
    +

    Whether to force refresh the data, bypassing the cache.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +
    +

    The block that fetches fresh data if cache is not used or is stale.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +
    +

    The data fetched from cache or fresh data.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+62
+63
+64
+65
+66
+67
+68
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 62
+
+def fetch(endpoint, force_refresh: false, &block)
+  if force_refresh || !use_cache?(endpoint)
+    fetch_fresh_data(endpoint, &block)
+  else
+    fetch_cached_or_fresh_data(endpoint, &block)
+  end
+end
+
+
+ +
+

+ + #ttl_for(endpoint) ⇒ Integer + + + + + +

+
+ +

Returns the TTL for a specific endpoint. Defaults to the global TTL if no custom TTL is set.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to fetch the TTL for.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Integer) + + + + — +
    +

    The TTL in seconds.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+44
+45
+46
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 44
+
+def ttl_for(endpoint)
+  @custom_ttls.fetch(endpoint, @global_ttl)
+end
+
+
+ +
+

+ + #use_cache?(endpoint) ⇒ Boolean + + + + + +

+
+ +

Determines if caching should be used for the given endpoint.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to check.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Boolean) + + + + — +
    +

    True if caching is enabled for the endpoint, false otherwise.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+52
+53
+54
+
+
# File 'lib/api_wrapper/cache/cache_policy.rb', line 52
+
+def use_cache?(endpoint)
+  !@no_cache_endpoints.include?(endpoint)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/Cache/CacheStore.html b/doc/ApiWrapper/Cache/CacheStore.html new file mode 100644 index 0000000..7b8354b --- /dev/null +++ b/doc/ApiWrapper/Cache/CacheStore.html @@ -0,0 +1,674 @@ + + + + + + + Class: ApiWrapper::Cache::CacheStore + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::Cache::CacheStore + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/cache/cache_store.rb
+
+ +
+ +

Overview

+
+ +

CacheStore class provides an in-memory caching mechanism.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeCacheStore + + + + + +

+
+ +

Returns a new instance of CacheStore.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+7
+8
+9
+
+
# File 'lib/api_wrapper/cache/cache_store.rb', line 7
+
+def initialize
+  @store = {}
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #delete(key) ⇒ Object + + + + + +

+
+ +

Deletes data from the cache.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    The cache key.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+47
+48
+49
+
+
# File 'lib/api_wrapper/cache/cache_store.rb', line 47
+
+def delete(key)
+  @store.delete(key)
+end
+
+
+ +
+

+ + #fetch(key, ttl) { ... } ⇒ Object + + + + + +

+
+ +

Retrieves the cached data for the given key, or fetches fresh data if not cached or expired.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    The cache key.

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + + — +
    +

    The time-to-live in seconds.

    +
    + +
  • + +
+ +

Yields:

+
    + +
  • + + + + + + + +
    +

    Fetches fresh data if cache is expired or not present.

    +
    + +
  • + +
+

Returns:

+
    + +
  • + + + (Object) + + + + — +
    +

    The cached data or the result of the block if not cached or expired.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
+
# File 'lib/api_wrapper/cache/cache_store.rb', line 17
+
+def fetch(key, ttl)
+  if cached?(key, ttl)
+    @store[key][:data]
+  else
+    fresh_data = yield
+    store(key, fresh_data, ttl)
+    fresh_data
+  end
+end
+
+
+ +
+

+ + #read(key) ⇒ Object? + + + + + +

+
+ +

Reads data from the cache.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    The cache key.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Object, nil) + + + + — +
    +

    The cached data, or nil if not present.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+31
+32
+33
+
+
# File 'lib/api_wrapper/cache/cache_store.rb', line 31
+
+def read(key)
+  cached?(key) ? @store[key][:data] : nil
+end
+
+
+ +
+

+ + #write(key, data, ttl) ⇒ Object + + + + + +

+
+ +

Writes data to the cache with an expiration time.

+ + +
+
+
+

Parameters:

+
    + +
  • + + key + + + (String) + + + + — +
    +

    The cache key.

    +
    + +
  • + +
  • + + data + + + (Object) + + + + — +
    +

    The data to cache.

    +
    + +
  • + +
  • + + ttl + + + (Integer) + + + + — +
    +

    The time-to-live in seconds.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+40
+41
+42
+
+
# File 'lib/api_wrapper/cache/cache_store.rb', line 40
+
+def write(key, data, ttl)
+  store(key, data, ttl)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/Configuration.html b/doc/ApiWrapper/Configuration.html new file mode 100644 index 0000000..e042b3a --- /dev/null +++ b/doc/ApiWrapper/Configuration.html @@ -0,0 +1,366 @@ + + + + + + + Class: ApiWrapper::Configuration + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::Configuration + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper.rb
+
+ +
+ +

Overview

+
+ +

Configuration class for managing settings

+ + +
+
+
+ + +
+ + + +

Instance Attribute Summary collapse

+ + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initializeConfiguration + + + + + +

+
+ +

Returns a new instance of Configuration.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+27
+28
+29
+30
+
+
# File 'lib/api_wrapper.rb', line 27
+
+def initialize
+  @api_configuration_path = default_api_configuration_path
+  @cache_store = default_cache_store
+end
+
+
+ +
+ +
+

Instance Attribute Details

+ + + +
+

+ + #api_configuration_pathObject + + + + + +

+
+ +

Returns the value of attribute api_configuration_path.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/api_wrapper.rb', line 25
+
+def api_configuration_path
+  @api_configuration_path
+end
+
+
+ + + +
+

+ + #cache_storeObject + + + + + +

+
+ +

Returns the value of attribute cache_store.

+ + +
+
+
+ + +
+ + + + +
+
+
+
+25
+26
+27
+
+
# File 'lib/api_wrapper.rb', line 25
+
+def cache_store
+  @cache_store
+end
+
+
+ +
+ + +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/HttpClient.html b/doc/ApiWrapper/HttpClient.html new file mode 100644 index 0000000..6d0ca2c --- /dev/null +++ b/doc/ApiWrapper/HttpClient.html @@ -0,0 +1,117 @@ + + + + + + + Module: ApiWrapper::HttpClient + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: ApiWrapper::HttpClient + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/http_client/base_client.rb,
+ lib/api_wrapper/http_client/faraday_client.rb
+
+
+ +
+ +

Defined Under Namespace

+

+ + + + + Classes: BaseClient, FaradayClient + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/HttpClient/BaseClient.html b/doc/ApiWrapper/HttpClient/BaseClient.html new file mode 100644 index 0000000..cc34a65 --- /dev/null +++ b/doc/ApiWrapper/HttpClient/BaseClient.html @@ -0,0 +1,349 @@ + + + + + + + Class: ApiWrapper::HttpClient::BaseClient + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::HttpClient::BaseClient + + + +

+
+ +
+
Inherits:
+
+ Object + +
    +
  • Object
  • + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/http_client/base_client.rb
+
+ +
+ +

Overview

+
+ +

Base class for HTTP clients

+ + +
+
+
+ + +
+

Direct Known Subclasses

+

FaradayClient

+
+ + + + + + + + +

+ Instance Method Summary + collapse +

+ + + + +
+

Constructor Details

+ +
+

+ + #initialize(base_url, cache_policy) ⇒ BaseClient + + + + + +

+
+ +

Initializes a new instance of the BaseClient class.

+ + +
+
+
+

Parameters:

+
    + +
  • + + base_url + + + (String) + + + + — +
    +

    The base URL for the HTTP client.

    +
    + +
  • + +
+ + +
+ + + + +
+
+
+
+10
+11
+12
+13
+
+
# File 'lib/api_wrapper/http_client/base_client.rb', line 10
+
+def initialize(base_url, cache_policy)
+  @base_url = base_url
+  @cache_policy = cache_policy
+end
+
+
+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #get(endpoint) ⇒ Object + + + + + +

+
+ +

Sends a GET request to the specified endpoint.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to send the GET request to.

    +
    + +
  • + +
+ +

Raises:

+
    + +
  • + + + (NotImplementedError) + + + + — +
    +

    If the method is not implemented by subclasses.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+19
+20
+21
+
+
# File 'lib/api_wrapper/http_client/base_client.rb', line 19
+
+def get(endpoint)
+  raise NotImplementedError, 'Subclasses must implement the get method'
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/ApiWrapper/HttpClient/FaradayClient.html b/doc/ApiWrapper/HttpClient/FaradayClient.html new file mode 100644 index 0000000..017a9cb --- /dev/null +++ b/doc/ApiWrapper/HttpClient/FaradayClient.html @@ -0,0 +1,299 @@ + + + + + + + Class: ApiWrapper::HttpClient::FaradayClient + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Class: ApiWrapper::HttpClient::FaradayClient + + + +

+
+ +
+
Inherits:
+
+ BaseClient + +
    +
  • Object
  • + + + + + +
+ show all + +
+
+ + + + + + + + + + + +
+
Defined in:
+
lib/api_wrapper/http_client/faraday_client.rb
+
+ +
+ +

Overview

+
+ +

FaradayClient class is responsible for making HTTP requests using Faraday.

+ + +
+
+
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ + + + + + + + + + + + + +

Methods inherited from BaseClient

+

#initialize

+
+

Constructor Details

+ +

This class inherits a constructor from ApiWrapper::HttpClient::BaseClient

+ +
+ + +
+

Instance Method Details

+ + +
+

+ + #get(endpoint, force_refresh: false) ⇒ Faraday::Response + + + + + +

+
+ +

Sends a GET request to the specified endpoint.

+ + +
+
+
+

Parameters:

+
    + +
  • + + endpoint + + + (String) + + + + — +
    +

    The endpoint to send the request to.

    +
    + +
  • + +
  • + + force_refresh + + + (Boolean) + + + (defaults to: false) + + + — +
    +

    Whether to force a cache refresh.

    +
    + +
  • + +
+ +

Returns:

+
    + +
  • + + + (Faraday::Response) + + + + — +
    +

    The response object.

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+17
+18
+19
+20
+21
+22
+23
+24
+
+
# File 'lib/api_wrapper/http_client/faraday_client.rb', line 17
+
+def get(endpoint, force_refresh: false)
+  # Use the cache policy to determine whether to fetch from cache or refresh.
+  @cache_policy.fetch(endpoint, force_refresh:) do
+    handle_connection(endpoint) do |connection|
+      connection.get(endpoint)
+    end
+  end
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/_index.html b/doc/_index.html new file mode 100644 index 0000000..715d85e --- /dev/null +++ b/doc/_index.html @@ -0,0 +1,195 @@ + + + + + + + Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Documentation by YARD 0.9.37

+
+

Alphabetic Index

+ +

File Listing

+ + +
+

Namespace Listing A-Z

+ + + + + + + + +
+ + + + + +
    +
  • B
  • +
      + +
    • + BaseClient + + (ApiWrapper::HttpClient) + +
    • + +
    +
+ + + + + +
    +
  • F
  • + +
+ + +
    +
  • H
  • + +
+ +
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/class_list.html b/doc/class_list.html new file mode 100644 index 0000000..3eec3c4 --- /dev/null +++ b/doc/class_list.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + Class List + + + +
+
+

Class List

+ + + +
+ + +
+ + diff --git a/doc/css/common.css b/doc/css/common.css new file mode 100644 index 0000000..cf25c45 --- /dev/null +++ b/doc/css/common.css @@ -0,0 +1 @@ +/* Override this file with custom rules */ \ No newline at end of file diff --git a/doc/css/full_list.css b/doc/css/full_list.css new file mode 100644 index 0000000..6eef5e4 --- /dev/null +++ b/doc/css/full_list.css @@ -0,0 +1,58 @@ +body { + margin: 0; + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + height: 101%; + overflow-x: hidden; + background: #fafafa; +} + +h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; } +.clear { clear: both; } +.fixed_header { position: fixed; background: #fff; width: 100%; padding-bottom: 10px; margin-top: 0; top: 0; z-index: 9999; height: 70px; } +#search { position: absolute; right: 5px; top: 9px; padding-left: 24px; } +#content.insearch #search, #content.insearch #noresults { background: url(data:image/gif;base64,R0lGODlhEAAQAPYAAP///wAAAPr6+pKSkoiIiO7u7sjIyNjY2J6engAAAI6OjsbGxjIyMlJSUuzs7KamppSUlPLy8oKCghwcHLKysqSkpJqamvT09Pj4+KioqM7OzkRERAwMDGBgYN7e3ujo6Ly8vCoqKjY2NkZGRtTU1MTExDw8PE5OTj4+PkhISNDQ0MrKylpaWrS0tOrq6nBwcKysrLi4uLq6ul5eXlxcXGJiYoaGhuDg4H5+fvz8/KKiohgYGCwsLFZWVgQEBFBQUMzMzDg4OFhYWBoaGvDw8NbW1pycnOLi4ubm5kBAQKqqqiQkJCAgIK6urnJyckpKSjQ0NGpqatLS0sDAwCYmJnx8fEJCQlRUVAoKCggICLCwsOTk5ExMTPb29ra2tmZmZmhoaNzc3KCgoBISEiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCAAAACwAAAAAEAAQAAAHaIAAgoMgIiYlg4kACxIaACEJCSiKggYMCRselwkpghGJBJEcFgsjJyoAGBmfggcNEx0flBiKDhQFlIoCCA+5lAORFb4AJIihCRbDxQAFChAXw9HSqb60iREZ1omqrIPdJCTe0SWI09GBACH5BAkIAAAALAAAAAAQABAAAAdrgACCgwc0NTeDiYozCQkvOTo9GTmDKy8aFy+NOBA7CTswgywJDTIuEjYFIY0JNYMtKTEFiRU8Pjwygy4ws4owPyCKwsMAJSTEgiQlgsbIAMrO0dKDGMTViREZ14kYGRGK38nHguHEJcvTyIEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDAggPg4iJAAMJCRUAJRIqiRGCBI0WQEEJJkWDERkYAAUKEBc4Po1GiKKJHkJDNEeKig4URLS0ICImJZAkuQAhjSi/wQyNKcGDCyMnk8u5rYrTgqDVghgZlYjcACTA1sslvtHRgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCQARAtOUoQRGRiFD0kJUYWZhUhKT1OLhR8wBaaFBzQ1NwAlkIszCQkvsbOHL7Y4q4IuEjaqq0ZQD5+GEEsJTDCMmIUhtgk1lo6QFUwJVDKLiYJNUd6/hoEAIfkECQgAAAAsAAAAABAAEAAAB2iAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4uen4ICCA+IkIsDCQkVACWmhwSpFqAABQoQF6ALTkWFnYMrVlhWvIKTlSAiJiVVPqlGhJkhqShHV1lCW4cMqSkAR1ofiwsjJyqGgQAh+QQJCAAAACwAAAAAEAAQAAAHZ4AAgoOEhYaCJSWHgxGDJCSMhREZGIYYGY2ElYebi56fhyWQniSKAKKfpaCLFlAPhl0gXYNGEwkhGYREUywag1wJwSkHNDU3D0kJYIMZQwk8MjPBLx9eXwuETVEyAC/BOKsuEjYFhoEAIfkECQgAAAAsAAAAABAAEAAAB2eAAIKDhIWGgiUlh4MRgyQkjIURGRiGGBmNhJWHm4ueICImip6CIQkJKJ4kigynKaqKCyMnKqSEK05StgAGQRxPYZaENqccFgIID4KXmQBhXFkzDgOnFYLNgltaSAAEpxa7BQoQF4aBACH5BAkIAAAALAAAAAAQABAAAAdogACCg4SFggJiPUqCJSWGgkZjCUwZACQkgxGEXAmdT4UYGZqCGWQ+IjKGGIUwPzGPhAc0NTewhDOdL7Ykji+dOLuOLhI2BbaFETICx4MlQitdqoUsCQ2vhKGjglNfU0SWmILaj43M5oEAOwAAAAAAAAAAAA==) no-repeat center left; } +#full_list { padding: 0; list-style: none; margin-left: 0; margin-top: 80px; font-size: 1.1em; } +#full_list ul { padding: 0; } +#full_list li { padding: 0; margin: 0; list-style: none; } +#full_list li .item { padding: 5px 5px 5px 12px; } +#noresults { padding: 7px 12px; background: #fff; } +#content.insearch #noresults { margin-left: 7px; } +li.collapsed ul { display: none; } +li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; } +li.collapsed a.toggle { cursor: default; background-position: top left; } +li { color: #666; cursor: pointer; } +li.deprecated { text-decoration: line-through; font-style: italic; } +li.odd { background: #f0f0f0; } +li.even { background: #fafafa; } +.item:hover { background: #ddd; } +li small:before { content: "("; } +li small:after { content: ")"; } +li small.search_info { display: none; } +a, a:visited { text-decoration: none; color: #05a; } +li.clicked > .item { background: #05a; color: #ccc; } +li.clicked > .item a, li.clicked > .item a:visited { color: #eee; } +li.clicked > .item a.toggle { opacity: 0.5; background-position: bottom right; } +li.collapsed.clicked a.toggle { background-position: top right; } +#search input { border: 1px solid #bbb; border-radius: 3px; } +#full_list_nav { margin-left: 10px; font-size: 0.9em; display: block; color: #aaa; } +#full_list_nav a, #nav a:visited { color: #358; } +#full_list_nav a:hover { background: transparent; color: #5af; } +#full_list_nav span:after { content: ' | '; } +#full_list_nav span:last-child:after { content: ''; } + +#content h1 { margin-top: 0; } +li { white-space: nowrap; cursor: normal; } +li small { display: block; font-size: 0.8em; } +li small:before { content: ""; } +li small:after { content: ""; } +li small.search_info { display: none; } +#search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #666; padding-left: 0; padding-right: 24px; } +#content.insearch #search { background-position: center right; } +#search input { width: 110px; } + +#full_list.insearch ul { display: block; } +#full_list.insearch .item { display: none; } +#full_list.insearch .found { display: block; padding-left: 11px !important; } +#full_list.insearch li a.toggle { display: none; } +#full_list.insearch li small.search_info { display: block; } diff --git a/doc/css/style.css b/doc/css/style.css new file mode 100644 index 0000000..f169a65 --- /dev/null +++ b/doc/css/style.css @@ -0,0 +1,503 @@ +html { + width: 100%; + height: 100%; +} +body { + font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif; + font-size: 13px; + width: 100%; + margin: 0; + padding: 0; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; +} + +#nav { + position: relative; + width: 100%; + height: 100%; + border: 0; + border-right: 1px dotted #eee; + overflow: auto; +} +.nav_wrap { + margin: 0; + padding: 0; + width: 20%; + height: 100%; + position: relative; + display: flex; + display: -webkit-flex; + display: -ms-flexbox; + flex-shrink: 0; + -webkit-flex-shrink: 0; + -ms-flex: 1 0; +} +#resizer { + position: absolute; + right: -5px; + top: 0; + width: 10px; + height: 100%; + cursor: col-resize; + z-index: 9999; +} +#main { + flex: 5 1; + -webkit-flex: 5 1; + -ms-flex: 5 1; + outline: none; + position: relative; + background: #fff; + padding: 1.2em; + padding-top: 0.2em; + box-sizing: border-box; +} + +@media (max-width: 920px) { + .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; } + #resizer { display: none; } + #nav { + z-index: 9999; + background: #fff; + display: none; + position: absolute; + top: 40px; + right: 12px; + width: 500px; + max-width: 80%; + height: 80%; + overflow-y: scroll; + border: 1px solid #999; + border-collapse: collapse; + box-shadow: -7px 5px 25px #aaa; + border-radius: 2px; + } +} + +@media (min-width: 920px) { + body { height: 100%; overflow: hidden; } + #main { height: 100%; overflow: auto; } + #search { display: none; } +} + +@media (max-width: 320px) { + body { height: 100%; overflow: hidden; overflow-wrap: break-word; } + #main { height: 100%; overflow: auto; } +} + +#main img { max-width: 100%; } +h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; } +h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; } +h1.title { margin-bottom: 10px; } +h1.alphaindex { margin-top: 0; font-size: 22px; } +h2 { + padding: 0; + padding-bottom: 3px; + border-bottom: 1px #aaa solid; + font-size: 1.4em; + margin: 1.8em 0 0.5em; + position: relative; +} +h2 small { font-weight: normal; font-size: 0.7em; display: inline; position: absolute; right: 0; } +h2 small a { + display: block; + height: 20px; + border: 1px solid #aaa; + border-bottom: 0; + border-top-left-radius: 5px; + background: #f8f8f8; + position: relative; + padding: 2px 7px; +} +a { font-weight: 550; } +.clear { clear: both; } +.inline { display: inline; } +.inline p:first-child { display: inline; } +.docstring, .tags, #filecontents { font-size: 15px; line-height: 1.5145em; } +.docstring p > code, .docstring p > tt, .tags p > code, .tags p > tt { + color: #c7254e; background: #f9f2f4; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.docstring h1, .docstring h2, .docstring h3, .docstring h4 { padding: 0; border: 0; border-bottom: 1px dotted #bbb; } +.docstring h1 { font-size: 1.2em; } +.docstring h2 { font-size: 1.1em; } +.docstring h3, .docstring h4 { font-size: 1em; border-bottom: 0; padding-top: 10px; } +.summary_desc .object_link a, .docstring .object_link a { + font-family: monospace; font-size: 1.05em; + color: #05a; background: #EDF4FA; padding: 2px 4px; font-size: 1em; + border-radius: 4px; +} +.rdoc-term { padding-right: 25px; font-weight: bold; } +.rdoc-list p { margin: 0; padding: 0; margin-bottom: 4px; } +.summary_desc pre.code .object_link a, .docstring pre.code .object_link a { + padding: 0px; background: inherit; color: inherit; border-radius: inherit; +} + +/* style for */ +#filecontents table, .docstring table { border-collapse: collapse; } +#filecontents table th, #filecontents table td, +.docstring table th, .docstring table td { border: 1px solid #ccc; padding: 8px; padding-right: 17px; } +#filecontents table tr:nth-child(odd), +.docstring table tr:nth-child(odd) { background: #eee; } +#filecontents table tr:nth-child(even), +.docstring table tr:nth-child(even) { background: #fff; } +#filecontents table th, .docstring table th { background: #fff; } + +/* style for
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/doc/method_list.html b/doc/method_list.html new file mode 100644 index 0000000..95a5b21 --- /dev/null +++ b/doc/method_list.html @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + Method List + + + +
+
+

Method List

+ + + +
+ +
    + + +
  • +
    + #add_custom_ttl + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #add_no_cache_endpoint + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #api_configuration_path + ApiWrapper::Configuration +
    +
  • + + +
  • +
    + api_manager + ApiWrapper +
    +
  • + + +
  • +
    + #base_url + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + #cache_policy + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + #cache_store + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #cache_store + ApiWrapper::Configuration +
    +
  • + + +
  • +
    + #client + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + configuration + ApiWrapper +
    +
  • + + +
  • +
    + configure + ApiWrapper +
    +
  • + + +
  • +
    + #delete + ApiWrapper::Cache::CacheStore +
    +
  • + + +
  • +
    + #endpoints + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + #fetch + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #fetch + ApiWrapper::Cache::CacheStore +
    +
  • + + +
  • +
    + #fetch_data + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + fetch_data + ApiWrapper +
    +
  • + + +
  • +
    + #get + ApiWrapper::HttpClient::FaradayClient +
    +
  • + + +
  • +
    + #get + ApiWrapper::HttpClient::BaseClient +
    +
  • + + +
  • +
    + #initialize + ApiWrapper::HttpClient::BaseClient +
    +
  • + + +
  • +
    + #initialize + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #initialize + ApiWrapper::Cache::CacheStore +
    +
  • + + +
  • +
    + #initialize + ApiWrapper::ApiManager +
    +
  • + + +
  • +
    + #initialize + ApiWrapper::Configuration +
    +
  • + + +
  • +
    + #read + ApiWrapper::Cache::CacheStore +
    +
  • + + +
  • +
    + reset_api_manager! + ApiWrapper +
    +
  • + + +
  • +
    + #ttl_for + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #use_cache? + ApiWrapper::Cache::CachePolicy +
    +
  • + + +
  • +
    + #write + ApiWrapper::Cache::CacheStore +
    +
  • + + + +
+
+ + diff --git a/doc/top-level-namespace.html b/doc/top-level-namespace.html new file mode 100644 index 0000000..192f8c9 --- /dev/null +++ b/doc/top-level-namespace.html @@ -0,0 +1,110 @@ + + + + + + + Top Level Namespace + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Top Level Namespace + + + +

+
+ + + + + + + + + + + +
+ +

Defined Under Namespace

+

+ + + Modules: ApiWrapper + + + + +

+ + + + + + + + + +
+ + + +
+ + \ No newline at end of file diff --git a/lib/api_wrapper.rb b/lib/api_wrapper.rb index 48538b5..6320477 100644 --- a/lib/api_wrapper.rb +++ b/lib/api_wrapper.rb @@ -72,7 +72,7 @@ def api_manager # Fetches data from the specified endpoint def fetch_data(endpoint_key, force_refresh: false) - api_manager.fetch_data(endpoint_key, force_refresh: force_refresh) + api_manager.fetch_data(endpoint_key, force_refresh:) end # Resets the ApiManager instance diff --git a/lib/api_wrapper/api_manager.rb b/lib/api_wrapper/api_manager.rb index 51337fb..b83d3d1 100644 --- a/lib/api_wrapper/api_manager.rb +++ b/lib/api_wrapper/api_manager.rb @@ -53,7 +53,7 @@ def fetch_data(endpoint_key, force_refresh: false) endpoint = @endpoints[endpoint_key] raise ArgumentError, "Invalid endpoint key: #{endpoint_key}" unless endpoint - @cache_policy.fetch(endpoint['path'], force_refresh: force_refresh) do + @cache_policy.fetch(endpoint['path'], force_refresh:) do @client.get(endpoint['path']) end end diff --git a/lib/api_wrapper/cache/cache_store.rb b/lib/api_wrapper/cache/cache_store.rb index a681199..6b9aec9 100644 --- a/lib/api_wrapper/cache/cache_store.rb +++ b/lib/api_wrapper/cache/cache_store.rb @@ -77,7 +77,7 @@ def expired?(key, ttl) # @param data [Object] The data to cache. # @param ttl [Integer] The time-to-live in seconds. def store(key, data, ttl) - @store[key] = { data: data, timestamp: Time.now, ttl: ttl } + @store[key] = { data:, timestamp: Time.now, ttl: } end end end diff --git a/lib/api_wrapper/http_client/faraday_client.rb b/lib/api_wrapper/http_client/faraday_client.rb index d452f4c..5aae1d1 100644 --- a/lib/api_wrapper/http_client/faraday_client.rb +++ b/lib/api_wrapper/http_client/faraday_client.rb @@ -16,7 +16,7 @@ class FaradayClient < BaseClient # @return [Faraday::Response] The response object. def get(endpoint, force_refresh: false) # Use the cache policy to determine whether to fetch from cache or refresh. - @cache_policy.fetch(endpoint, force_refresh: force_refresh) do + @cache_policy.fetch(endpoint, force_refresh:) do handle_connection(endpoint) do |connection| connection.get(endpoint) end diff --git a/spec/unit/api_manager_spec.rb b/spec/unit/api_manager_spec.rb index e71f86b..9065f6b 100644 --- a/spec/unit/api_manager_spec.rb +++ b/spec/unit/api_manager_spec.rb @@ -8,7 +8,7 @@ RSpec.describe ApiWrapper::ApiManager do let(:api_configuration_path) { 'spec/fixtures/api_configuration.yml' } let(:cache_store) { ApiWrapper::Cache::CacheStore.new } - let(:api_manager) { described_class.new(api_configuration_path, cache_store: cache_store) } + let(:api_manager) { described_class.new(api_configuration_path, cache_store:) } describe '#initialize' do it 'loads API configuration from file' do