diff --git a/.document b/.document index 2a5f665c1..e583d2559 100644 --- a/.document +++ b/.document @@ -1,3 +1,3 @@ -README.rdoc +README.md lib/**/*.rb bin/* diff --git a/.gitignore b/.gitignore index 24924a069..eab4d501e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,14 +2,22 @@ *.gem *.rbc *.sw? +.rvmrc .bundle .DS_Store +.idea +.yardoc +/tests/.fog +bin/* +!bin/fog +.fog coverage doc/* docs/_site/* docs/about/supported_services.markdown Gemfile.lock -rdoc +yardoc pkg spec/credentials.yml -.idea +vendor/* +tags diff --git a/.irbrc b/.irbrc new file mode 100644 index 000000000..786a98ec7 --- /dev/null +++ b/.irbrc @@ -0,0 +1,82 @@ +## This is primarily used for easier testing and development or +# usage of Fog. +# +# How to use: +# 1. Add this at the end of your `.irbrc` in your home directory. +# +# @working_directory = Dir.pwd +# @local_irbrc = File.join(@working_directory, '.irbrc') +# +# if @working_directory != ENV['HOME'] +# load @local_irbrc if File.exists?(@local_irbrc) +# end +# +# remove_instance_variable(:@working_directory) +# remove_instance_variable(:@local_irbrc) +# +# 2. Inside the Fog execute `bundle exec irb` +# + +require 'fog' + +class ConnectionManager < Hash + def [](key) + $connection_manager_previous_key = key + super(key) + end + + def []=(key, value) + $connection_manager_previous_key = key + super(key, value) + end +end + +def connections + return @connections if @connections + @connections = ConnectionManager.new +end + +def connection + connections[$connection_manager_previous_key] +end + +def connect_openstack(username, password, tenant = nil, url = 'http://192.168.27.100:35357/') + parameters = { + :provider => 'openstack', + :openstack_api_key => password, + :openstack_username => username, + :openstack_auth_url => "#{url}v2.0/tokens" + } + + parameters.merge!(:openstack_tenant => tenant) if tenant + + key = username.to_sym + set_service(key, Fog::Identity, parameters) + set_service(key, Fog::Compute, parameters) + set_service(key, Fog::Volume, parameters) + set_service(key, Fog::Image, parameters) +end + +def connect(parameters) + connections_count = connections.count + connections[connections_count] = Hash.new + + set_service(connections_count, Fog::Identity, parameters) + set_service(connections_count, Fog::Compute , parameters) + set_service(connections_count, Fog::Storage , parameters) + set_service(connections_count, Fog::Volume , parameters) + set_service(connections_count, Fog::Image , parameters) + set_service(connections_count, Fog::DNS , parameters) + set_service(connections_count, Fog::CDN , parameters) + connection +end + +def set_service(connections_count, type, parameters) + service_symbol = type.to_s.split('::').last.downcase.to_sym + + connections[connections_count].merge!({ + service_symbol => type.new(parameters) + }) +rescue + # Service not available +end diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..4acdaf343 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: ruby + +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + +script: FOG_MOCK=true bundle exec shindont + +notifications: + email: false + irc: + channels: + - "irc.freenode.org#ruby-fog" + template: + - "[#%{build_number}] %{message} %{build_url}" + - "[#%{build_number}] %{commit} on %{branch} by %{author}" + - "[#%{build_number}] %{compare_url}" + on_success: always + on_failure: always + use_notice: false diff --git a/README.md b/README.md new file mode 100644 index 000000000..c12be352a --- /dev/null +++ b/README.md @@ -0,0 +1,156 @@ +![fog](http://geemus.s3.amazonaws.com/fog.png) + +fog is the Ruby cloud services library, top to bottom: + +* Collections provide a simplified interface, making clouds easier to work with and switch between. +* Requests allow power users to get the most out of the features of each individual cloud. +* Mocks make testing and integrating a breeze. + +[![Build Status](https://secure.travis-ci.org/fog/fog.png?branch=master)](http://travis-ci.org/fog/fog) +[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/fog/fog) +[![Gem Version](https://fury-badge.herokuapp.com/rb/fog.png)](http://badge.fury.io/rb/fog) +[![Dependency Status](https://gemnasium.com/fog/fog.png)](https://gemnasium.com/fog/fog) + +## Getting Started + + sudo gem install fog + +Now type `fog` to try stuff, confident that fog will let you know what to do. +Here is an example of wading through server creation for Amazon Elastic Compute Cloud: + + >> server = Compute[:aws].servers.create + ArgumentError: image_id is required for this operation + + >> server = Compute[:aws].servers.create(:image_id => 'ami-5ee70037') + + + >> server.destroy # cleanup after yourself or regret it, trust me + true + +## Collections + +A high level interface to each cloud is provided through collections, such as `images` and `servers`. +You can see a list of available collections by calling `collections` on the connection object. +You can try it out using the `fog` command: + + >> Compute[:aws].collections + [:addresses, :directories, ..., :volumes, :zones] + +Some collections are available across multiple providers: + +* compute providers have `flavors`, `images` and `servers` +* dns providers have `zones` and `records` +* storage providers have `directories` and `files` + +Collections share basic CRUD type operations, such as: + +* `all` - fetch every object of that type from the provider. +* `create` - initialize a new record locally and a remote resource with the provider. +* `get` - fetch a single object by it's identity from the provider. +* `new` - initialize a new record locally, but do not create a remote resource with the provider. + +As an example, we'll try initializing and persisting a Rackspace Cloud server: + + require 'fog' + + compute = Fog::Compute.new( + :provider => 'Rackspace', + :rackspace_api_key => key, + :rackspace_username => username + ) + + # boot a gentoo server (flavor 1 = 256, image 3 = gentoo 2008.0) + server = compute.servers.create(:flavor_id => 1, :image_id => 3, :name => 'my_server') + server.wait_for { ready? } # give server time to boot + + # DO STUFF + + server.destroy # cleanup after yourself or regret it, trust me + +## Models + +Many of the collection methods return individual objects, which also provide common methods: + +* `destroy` - will destroy the persisted object from the provider +* `save` - persist the object to the provider +* `wait_for` - takes a block and waits for either the block to return true for the object or for a timeout (defaults to 10 minutes) + +## Mocks + +As you might imagine, testing code using Fog can be slow and expensive, constantly turning on and and shutting down instances. +Mocking allows skipping this overhead by providing an in memory representation resources as you make requests. +Enabling mocking easy to use, before you run other commands, simply run: + + Fog.mock! + +Then proceed as usual, if you run into unimplemented mocks, fog will raise an error and as always contributions are welcome! + +## Requests + +Requests allow you to dive deeper when the models just can't cut it. +You can see a list of available requests by calling `#requests` on the connection object. + +For instance, ec2 provides methods related to reserved instances that don't have any models (yet). Here is how you can lookup your reserved instances: + + $ fog + >> Compute[:aws].describe_reserved_instances + # + +It will return an [excon](http://github.com/geemus/excon) response, which has `body`, `headers` and `status`. Both return nice hashes. + +## Go forth and conquer + +Play around and use the console to explore or check out [fog.io](http://fog.io) for more details and examples. +Once you are ready to start scripting fog, here is a quick hint on how to make connections without the command line thing to help you. + + # create a compute connection + compute = Fog::Compute.new(:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY) + # compute operations go here + + # create a storage connection + storage = Fog::Storage.new(:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY) + # storage operations go here + +geemus says: "That should give you everything you need to get started, but let me know if there is anything I can do to help!" + +## Contributing + +* Find something you would like to work on. + * Look for anything you can help with in the [issue tracker](https://github.com/fog/fog/issues). + * Look at the [code quality metrics](https://codeclimate.com/github/fog/fog) for anything you can help clean up. + * Or anything else! +* Fork the project and do your work in a topic branch. + * Make sure your changes will work on both Ruby 1.8.7 and Ruby 1.9 +* Add a config at `tests/.fog` for the component you want to test. +* Add shindo tests to prove your code works and run all the tests using `bundle exec rake`. +* Rebase your branch against `fog/fog` to make sure everything is up to date. +* Commit your changes and send a pull request. + +## Additional Resources + +[fog.io](http://fog.io) + +## Copyright + +(The MIT License) + +Copyright (c) 2013 [geemus (Wesley Beary)](http://github.com/geemus) + +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. diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index d3e6518ae..000000000 --- a/README.rdoc +++ /dev/null @@ -1,154 +0,0 @@ -http://geemus.s3.amazonaws.com/fog.png - -fog is the Ruby cloud computing library, top to bottom: - -* Collections provide a simplified interface, making clouds easier to work with and switch between. -* Requests allow power users to get the most out of the features of each individual cloud. -* Mocks make testing and integrating a breeze. - -== Getting Started - - sudo gem install fog - -Now type 'fog' to try stuff, confident that fog will let you know what to do. Here is an example of wading through server creation for Amazon Elastic Compute Cloud: - - >> server = Compute[:aws].servers.create - ArgumentError: image_id is required for this operation - - >> server = Compute[:aws].servers.create(:image_id => 'ami-5ee70037') - - - >> server.destroy # cleanup after yourself or regret it, trust me - true - -== Collections - -A high level interface to each cloud is provided through collections, such as `images` and `servers`. -You can see a list of available collections by calling `collections` on the connection object. You can try it out using the `fog` command: - - >> Compute[:aws].collections - [:addresses, :directories, ..., :volumes, :zones] - -Some collections are available across multiple providers: - -* compute providers have +flavors+, +images+ and +servers+ -* dns providers have +zones+ and +records+ -* storage providers have +directories+ and +files+ - -Collections share basic CRUD type operations, such as: -* +all+ - fetch every object of that type from the provider. -* +create+ - initialize a new record locally and a remote resource with the provider. -* +get+ - fetch a single object by it's identity from the provider. -* +new+ - initialize a new record locally, but do not create a remote resource with the provider. - -As an example, we'll try initializing and persisting a Rackspace Cloud server: - - require 'fog' - - compute = Fog::Compute.new( - :provider => 'Rackspace', - :rackspace_api_key => key, - :rackspace_username => username - ) - - # boot a gentoo server (flavor 1 = 256, image 3 = gentoo 2008.0) - server = compute.servers.create(:flavor_id => 1, :image_id => 3, :name => 'my_server') - server.wait_for { ready? } # give server time to boot - - # DO STUFF - - server.destroy # cleanup after yourself or regret it, trust me - -== Models - -Many of the collection methods return individual objects, which also provide common methods: -* +destroy+ - will destroy the persisted object from the provider -* +save+ - persist the object to the provider -* +wait_for+ - takes a block and waits for either the block to return true for the object or for a timeout (defaults to 10 minutes) - -== Mocks - -As you might imagine, testing code using Fog can be slow and expensive, constantly turning on and and shutting down instances. -Mocking allows skipping this overhead by providing an in memory representation resources as you make requests. -Enabling mocking easy to use, before you run other commands, simply run: - - Fog.mock! - -Then proceed as usual, if you run into unimplemented mocks fog will raise an error and as always contributions are welcome! - -== Requests - -Requests allow you to dive deeper when the models just can't cut it. -You can see a list of available requests by calling #requests on the connection object. - -For instance, ec2 provides methods related to reserved instances that don't have any models (yet). Here is how you can lookup your reserved instances: - - $ fog - >> Compute[:aws].describe_reserved_instances - # - -It will return an {excon}[http://github.com/geemus/excon] response, which has `body`, `headers` and `status`. Both return nice hashes. - -== Go forth and conquer - -Play around and use the console to explore or check out {fog.io}[http://fog.io] for more details and examples. Once you are ready to start scripting fog, here is a quick hint on how to make connections without the command line thing to help you. - - # create a compute connection - compute = Fog::Compute.new(:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY) - # compute operations go here - - # create a storage connection - storage = Fog::Storage.new(:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY) - # storage operations go here - -geemus says: "That should give you everything you need to get started, but let me know if there is anything I can do to help!" - -== Contributing - -* Find something you would like to work on. For suggestions look for the `easy`, `medium` and `hard` tags in the {issues}[http://github.com/geemus/fog/issues] -* Fork the project and do your work in a topic branch. -* Add shindo tests to prove your code works and run all the tests using `bundle exec rake`. -* Rebase your branch against geemus/fog to make sure everything is up to date. -* Commit your changes and send a pull request. - -== T-Shirts - -Wonder how you can get a lovely fog shirt? Look no further! - -* Blue shirts go to people who have contributed indirectly, great examples are writing blog posts or giving lightning talks. -* Grey shirts and a follow from @fog go to people who have made it on to the {contributors list}[https://github.com/geemus/fog/contributors] by submitting code. -* Black shirts go to people who have made it on to the {collaborators list}[https://github.com/api/v2/json/repos/show/geemus/fog/collaborators] by coercing geemus into adding them. - -== Additional Resources - -{fog.io}[http://fog.io] - -== Sponsorship - -http://www.engineyard.com/images/logo.png - -All new work on fog is sponsored by {Engine Yard}[http://engineyard.com] -== Copyright - -(The MIT License) - -Copyright (c) 2010 {geemus (Wesley Beary)}[http://github.com/geemus] - -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. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..9829bcf49 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,39 @@ +# Release process + +This is fog's current release process, documented so people know what is +currently done. + +## Versioning + +fog uses semantic versioning (http://semver.org/) + +## When we release + +Releases occur monthly and are manually handled by fog's Benevolent +Dictator Wes (@geemus). + +To request a new release please raise an issue. + +## Prepare the release + +* Ensure the code is passing on the CI server [![Build Status](https://secure.travis-ci.org/fog/fog.png?branch=master)](http://travis-ci.org/fog/fog) +* Ensure the code is passing for live tests (Requires Credentials for all +services) +* Ensure working on **master** +* Update the version number (`lib/fog/version.rb`) +* Run `rake changelog` to update `changelog.txt` +* Run `rake release` to prepare the release which does: + * Prepares the release (`rake release:prepare`) + * Builds the gem + * Tags the commit + * Creates commits for version + * Publishes the release (`rake release:publish`) + * Pushes commit and tag to Github (Requires Credentials) + * Pushes gem to Rubygems (Requires Credentials) + +## Announce the release + +Once the release is prepared and uploaded it needs to be announced. + +* Send an email to https://groups.google.com/forum/?fromgroups#!forum/ruby-fog +* Tweet as @fog on Twitter (Requires Credentials) diff --git a/Rakefile b/Rakefile index 6b219c3e2..6990b11e2 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ -require 'rubygems' require 'bundler/setup' require 'date' +require 'rubygems' +require 'rubygems/package_task' +require 'yard' require File.dirname(__FILE__) + '/lib/fog' ############################################################################# @@ -14,8 +16,7 @@ def name end def version - line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/] - line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1] + Fog::VERSION end def date @@ -44,58 +45,20 @@ end # ############################################################################# +GEM_NAME = "#{name}" task :default => :test +require "tasks/test_task" +Fog::Rake::TestTask.new + namespace :test do - task :dynect do - [false].each do |mock| - sh("export FOG_MOCK=#{mock} && bundle exec shindont tests/dns/requests/dynect") - #sh("export FOG_MOCK=#{mock} && bundle exec shindont tests/dns/models/") + task :vsphere do + [true].each do |mock| + sh("export FOG_MOCK=#{mock} && bundle exec shindont tests/vsphere") end end end -task :examples do - sh("export FOG_MOCK=false && bundle exec shindont examples") - # some don't provide mocks so we'll leave this out for now - # sh("export FOG_MOCK=true && bundle exec shindont examples") -end - -task :test do # => :examples do - Rake::Task[:mock_tests].invoke && Rake::Task[:examples].invoke && Rake::Task[:real_tests].invoke -end - -def tests(mocked) - Formatador.display_line - sh("export FOG_MOCK=#{mocked} && bundle exec spec spec") - Formatador.display_line - start = Time.now.to_i - threads = [] - Thread.main[:results] = [] - Fog.providers.each do |provider| - threads << Thread.new do - Thread.main[:results] << { - :provider => provider, - :success => sh("export FOG_MOCK=#{mocked} && bundle exec shindont +#{provider.downcase}") - } - end - end - threads.each do |thread| - thread.join - end - Formatador.display_table(Thread.main[:results].sort {|x,y| x[:provider] <=> y[:provider]}) - Formatador.display_line("[bold]FOG_MOCK=#{mocked}[/] tests completed in [bold]#{Time.now.to_i - start}[/] seconds") - Formatador.display_line -end - -task :mock_tests do - tests(true) -end - -task :real_tests do - tests(false) -end - task :nuke do Fog.providers.each do |provider| next if ['Vmfusion'].include?(provider) @@ -121,22 +84,6 @@ task :nuke do end end -desc "Generate RCov test coverage and open in your browser" -task :coverage do - require 'rcov' - sh "rm -fr coverage" - sh "rcov test/test_*.rb" - sh "open coverage/index.html" -end - -require 'rdoc/task' -RDoc::Task.new do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = "#{name} #{version}" - rdoc.rdoc_files.include('README*') - rdoc.rdoc_files.include('lib/**/*.rb') -end - desc "Open an irb session preloaded with this library" task :console do sh "irb -rubygems -r ./lib/#{name}.rb" @@ -148,18 +95,44 @@ end # ############################################################################# -task :release => :build do - unless `git branch` =~ /^\* master$/ - puts "You must be on the master branch to release!" - exit! +task :release => ["release:prepare", "release:publish"] + +namespace :release do + task :preflight do + unless `git branch` =~ /^\* master$/ + puts "You must be on the master branch to release!" + exit! + end + if `git tag` =~ /^\* v#{version}$/ + puts "Tag v#{version} already exists!" + exit! + end end - sh "gem install pkg/#{name}-#{version}.gem" + + task :prepare => :preflight do + Rake::Task[:build].invoke + sh "gem install pkg/#{name}-#{version}.gem" + Rake::Task[:git_mark_release].invoke + end + + task :publish do + Rake::Task[:git_push_release].invoke + Rake::Task[:gem_push].invoke + end +end + +task :git_mark_release do sh "git commit --allow-empty -a -m 'Release #{version}'" sh "git tag v#{version}" +end + +task :git_push_release do sh "git push origin master" sh "git push origin v#{version}" +end + +task :gem_push do sh "gem push pkg/#{name}-#{version}.gem" - Rake::Task[:docs].invoke end task :build => :gemspec do @@ -184,7 +157,7 @@ task :gemspec => :validate do end task :validate do - libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"] + libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}", "lib/tasks"] unless libfiles.empty? puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir." exit! @@ -195,256 +168,12 @@ task :validate do end end -task :changelog do - timestamp = Time.now.utc.strftime('%m/%d/%Y') - sha = `git log | head -1`.split(' ').last - changelog = ["#{version} #{timestamp} #{sha}"] - changelog << ('=' * changelog[0].length) - changelog << '' - - require 'multi_json' - github_repo_data = MultiJson.decode(Excon.get('http://github.com/api/v2/json/repos/show/geemus/fog').body) - data = github_repo_data['repository'].reject {|key, value| !['forks', 'open_issues', 'watchers'].include?(key)} - github_collaborator_data = MultiJson.decode(Excon.get('http://github.com/api/v2/json/repos/show/geemus/fog/collaborators').body) - data['collaborators'] = github_collaborator_data['collaborators'].length - rubygems_data = MultiJson.decode(Excon.get('https://rubygems.org/api/v1/gems/fog.json').body) - data['downloads'] = rubygems_data['downloads'] - stats = [] - for key in data.keys.sort - stats << "'#{key}' => #{data[key]}" - end - changelog << "Stats! { #{stats.join(', ')} }" - changelog << '' - - last_sha = `cat changelog.txt | head -1`.split(' ').last - shortlog = `git shortlog #{last_sha}..HEAD` - changes = {} - committers = {} - for line in shortlog.split("\n") - if line =~ /^\S/ - committer = line.split(' (', 2).first - committers[committer] = 0 - elsif line =~ /^\s*((Merge.*)|(Release.*))?$/ - # skip empty lines, Merge and Release commits - else - unless line[-1..-1] == '.' - line << '.' - end - line.lstrip! - line.gsub!(/^\[([^\]]*)\] /, '') - tag = $1 || 'misc' - changes[tag] ||= [] - changes[tag] << (line << ' thanks ' << committer) - committers[committer] += 1 - end - end - - for committer, commits in committers.to_a.sort {|x,y| y[1] <=> x[1]} - if [ - 'Aaron Suggs', - 'Brian Hartsock', - 'Christopher Oliver', - 'Dylan Egan', - 'geemus', - 'Henry Addison', - 'Lincoln Stoll', - 'Luqman Amjad', - 'nightshade427', - 'Patrick Debois', - 'Wesley Beary' - ].include?(committer) - next - end - changelog << "MVP! #{committer}" - changelog << '' - break - end - - for tag in changes.keys.sort - changelog << ('[' << tag << ']') - for commit in changes[tag] - changelog << (' ' << commit) - end - changelog << '' - end - - old_changelog = File.read('changelog.txt') - File.open('changelog.txt', 'w') do |file| - file.write(changelog.join("\n")) - file.write("\n\n") - file.write(old_changelog) - end +# Include Yard tasks for rake yard +YARDOC_LOCATION = "doc" +YARD::Rake::YardocTask.new do |t| + t.files = ['lib/**/*.rb', "README"] + t.options = ["--output-dir", YARDOC_LOCATION, "--title", "#{name} #{version}"] end -task :docs do - Rake::Task[:supported_services_docs].invoke - Rake::Task[:upload_fog_io].invoke - Rake::Task[:upload_rdoc].invoke - - # connect to storage provider - Fog.credential = :geemus - storage = Fog::Storage.new(:provider => 'AWS') - directory = storage.directories.new(:key => 'fog.io') - # write base index with redirect to new version - directory.files.create( - :body => redirecter('latest'), - :content_type => 'text/html', - :key => 'index.html', - :public => true - ) - - Formatador.display_line -end - -task :supported_services_docs do - support, shared = {}, [] - for key, values in Fog.services - unless values.length == 1 - shared |= [key] - values.each do |value| - support[value] ||= {} - support[value][key] = '+' - end - else - value = values.first - support[value] ||= {} - support[value][:other] ||= [] - support[value][:other] << key - end - end - shared.sort! {|x,y| x.to_s <=> y.to_s} - columns = [:provider] + shared + [:other] - data = [] - for key in support.keys.sort {|x,y| x.to_s <=> y.to_s} - data << { :provider => key }.merge!(support[key]) - end - - table = '' - table << "\n" - - table << " " - for column in columns - table << "" - end - table << "\n" - - for datum in data - table << " " - for column in columns - if value = datum[column] - case value - when Array - table << "" - when '+' - table << "" - else - table << "" - end - else - table << "" - end - end - table << "\n" - end - - table << "
#{column}
#{value.join(', ')}#{value}#{value}
\n" - - File.open('docs/about/supported_services.markdown', 'w') do |file| - file.puts <<-METADATA ---- -layout: default -title: Supported Services ---- - -METADATA - file.puts(table) - end -end - -task :upload_fog_io do - # connect to storage provider - Fog.credential = :geemus - storage = Fog::Storage.new(:provider => 'AWS') - directory = storage.directories.new(:key => 'fog.io') - - # build the docs locally - sh "jekyll docs docs/_site" - - # write web page files to versioned 'folder' - for file_path in Dir.glob('docs/_site/**/*') - next if File.directory?(file_path) - file_name = file_path.gsub('docs/_site/', '') - key = '' << version << '/' << file_name - Formatador.redisplay(' ' * 128) - Formatador.redisplay("Uploading [bold]#{key}[/]") - if File.extname(file_name) == '.html' - # rewrite links with version - body = File.read(file_path) - body.gsub!(/vX.Y.Z/, 'v' << version) - body.gsub!(/='\//, %{='/} << version << '/') - body.gsub!(/="\//, %{="/} << version << '/') - content_type = 'text/html' - directory.files.create( - :body => redirecter(key), - :content_type => 'text/html', - :key => 'latest/' << file_name, - :public => true - ) - else - body = File.open(file_path) - content_type = nil # leave it up to mime-types - end - directory.files.create( - :body => body, - :content_type => content_type, - :key => key, - :public => true - ) - end - Formatador.redisplay(' ' * 128) - Formatador.redisplay("Uploaded docs/_site\n") -end - -task :upload_rdoc do - # connect to storage provider - Fog.credential = :geemus - storage = Fog::Storage.new(:provider => 'AWS') - directory = storage.directories.new(:key => 'fog.io') - - # write rdoc files to versioned 'folder' - Rake::Task[:rdoc].invoke - for file_path in Dir.glob('rdoc/**/*') - next if File.directory?(file_path) - file_name = file_path.gsub('rdoc/', '') - key = '' << version << '/rdoc/' << file_name - Formatador.redisplay(' ' * 128) - Formatador.redisplay("Uploading [bold]#{key}[/]") - directory.files.create( - :body => File.open(file_path), - :key => key, - :public => true - ) - end - Formatador.redisplay(' ' * 128) - directory.files.create( - :body => redirecter("#{version}/rdoc/index.html"), - :content_type => 'text/html', - :key => 'latest/rdoc/index.html', - :public => true - ) - Formatador.redisplay("Uploaded rdoc\n") -end - -def redirecter(path) - redirecter = <<-HTML - - -fog - - - - redirecting to lastest (#{path}) - - -HTML -end +require "tasks/changelog_task" +Fog::Rake::ChangelogTask.new diff --git a/bin/fog b/bin/fog index 06876156f..c57f9b7b5 100755 --- a/bin/fog +++ b/bin/fog @@ -23,10 +23,8 @@ end if ARGV.length > 1 - require 'multi_json' - result = instance_eval(ARGV[1..-1].join(' ')) - puts(MultiJson.encode(result)) + puts(Fog::JSON.encode(result)) else @@ -39,6 +37,10 @@ else @irb.context.prompt_mode = :FOG @irb.context.workspace = IRB::WorkSpace.new(binding) + trap 'INT' do + @irb.signal_handle + end + Formatador.display_line('Welcome to fog interactive!') Formatador.display_line(":#{Fog.credential} provides #{providers}") providers = Fog.providers diff --git a/changelog.txt b/changelog.txt index b0c50b8ab..738738608 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,2241 @@ +1.8.0 12/01/2012 057c0c525a39e77cb2037c9fec3d851b209c151b +========================================================= + +Stats! { 'collaborators' => 41, 'downloads' => 1334733, 'forks' => 630, 'open_issues' => 98, 'watchers' => 2258 } + +[AWS] + Adds ModifyVolumeAttribute. thanks Eric Stonfer + +[Brightbox] + Removes incorrect yard tag. thanks Paul Thornthwaite + Updates request docs to use Yard. thanks Paul Thornthwaite + Adds baseline documentation. thanks Paul Thornthwaite + Documents #request method. thanks Paul Thornthwaite + Comments out rogue text. thanks Paul Thornthwaite + Fixes generated files EOF with newlines. thanks Paul Thornthwaite + Adds Servers#bootstrap. thanks Paul Thornthwaite + Adds way to check auth method. thanks Paul Thornthwaite + Adds reset FTP for scoped accounts. thanks Paul Thornthwaite + Fixes Compute#account to pass service. thanks Paul Thornthwaite + Fixes Account#reset_ftp_password. thanks Paul Thornthwaite + Fixes test to run out of sequence. thanks Paul Thornthwaite + Expands documentation for Compute class. thanks Paul Thornthwaite + Tests recognised options. thanks Paul Thornthwaite + Refactors credential code in Compute. thanks Paul Thornthwaite + Extracts authentication connection. thanks Paul Thornthwaite + Refactors how tokens are requested. thanks Paul Thornthwaite + Moves tokens to CredentialSet. thanks Paul Thornthwaite + Extracts parts of request out of compute. thanks Paul Thornthwaite + Adds support for refresh tokens. thanks Paul Thornthwaite + Adds option to disable token management. thanks Paul Thornthwaite + Adds means to update scoped account. thanks Paul Thornthwaite + Moves more of public API into Shared. thanks Paul Thornthwaite + Guards unimplemented mock tests. thanks Paul Thornthwaite + +[Docs] + Switches to using Yard for documentation. thanks Paul Thornthwaite + +[aws] + fixed auto scaling model group 'destroy' method where it needs to use merge! instead of merge to set the opts local variable in place, otherwise the options passed to the method are droppedon the floor. thanks Jay Perry + +[aws|compute] + add offeringType to output from describe_reserved_instances_offerings. thanks geemus + fix mocks/tests around describe_reserved_instances_offerings. thanks geemus + fix one more offeringType mock format test failure. thanks geemus + +[aws|dynamodb] + port off of sts for credentials, now uses signature v4. thanks geemus + +[aws|storage] + Add Fog::Storage::AWS#delete_multiple_objects. thanks Garret Alfert + Add mock for Fog::Storage::AWS#delete_multiple_objects. thanks Garret Alfert + Little improvements to delete_multiple_objects tests. thanks Garret Alfert + Add Fog::Storage::AWS#delete_multiple_objects. thanks Garret Alfert + Add mock for Fog::Storage::AWS#delete_multiple_objects. thanks Garret Alfert + Little improvements to delete_multiple_objects tests. thanks Garret Alfert + +[core] + Adds fog User-Agent header. thanks Paul Thornthwaite + Splits Fog::VERSION into own file. thanks Paul Thornthwaite + Adds fog User-Agent header. thanks Paul Thornthwaite + Updates Rakefile to use Fog::VERSION. thanks Paul Thornthwaite + +[dns] + Add more record tests. thanks Brian Hartsock + +[docs] + Updates link on fog.io to point to doc. thanks Paul Thornthwaite + Updates contributing notes. thanks Paul Thornthwaite + Replaces link to API to `rubydoc.info`. thanks Paul Thornthwaite + Adds 1.8.7 note to fog.io collaborators guide. thanks Paul Thornthwaite + +[misc] + Add support for AWS Australia (ap-southeast-2). thanks Amy Woodward + Add Hosted Zone ID for ap-southeast-2. thanks Amy Woodward + Do not add empty security group. thanks Dan Bode + Add attr group. thanks Dan Bode + Sync with latest OpenStack flavors extensions. thanks Dan Prince + OpenStack floating_ip (aka address) test fixes. thanks Dan Prince + OpenStack: Remove volumes from limits tests. thanks Dan Prince + OpenStack: updates to quota tests. thanks Dan Prince + OpenStack: security group test fixes. thanks Dan Prince + add support for Storage::Rackspace::File#access_control_allow_origin and #origin. thanks Dusty Jones + add support for Storage::Rackspace::File#access_control_allow_origin and #origin. thanks Dusty Jones + Save the file instance before testing for presence of attribute. thanks Dusty Jones + Fix describe_instances stateReason handling. thanks Edward Muller + added support for Storage::Rackspace::File#metadata. thanks Evan Smith + added support for Storage::Rackspace::File#metadata. thanks Evan Smith + merged with origin. thanks Evan Smith + Rackspace Cloud Files. can load metadata from existing file. can set metadata for new file. can unset metadata for existing file. thanks Evan Smith + merged with upstream master. thanks Evan Smith + Implemented bootstrap method for Rackspace Compute v2. Added ability to set "metadata" and "personality" fields when creating a server on Rackspace Compute v2. Improved response parsing when dealing with Rackspace DNS service. thanks Jesse Scott + Removed the commented out password setting line for Rackspace Compute v2 bootstrap method. thanks Jesse Scott + Clarified the logic for finding the newly created DNS record for Rackspace Cloud DNS. thanks Jesse Scott + fix warning message to follow correct bucket naming guidelines. thanks Michael Elfassy + Bucket names cannot begin with the "goog" prefix. Also change for DNS compliant subdomain. thanks Michael Elfassy + VMWare vsphere provider refactor. thanks Ohad Levy + do not force trailing / on path. thanks Ohad Levy + Removes dead link to DNS tests. thanks Paul Thornthwaite + Adds link to Code Climate metrics. thanks Paul Thornthwaite + Extracts Changelog Rake task to class. thanks Paul Thornthwaite + Moves fog.io generation a prerequsite. thanks Paul Thornthwaite + Extracts docs rake tasks to a class. thanks Paul Thornthwaite + Extracts testing Rake tasks to class. thanks Paul Thornthwaite + Moves new Task classes to better location. thanks Paul Thornthwaite + Revert "[core] Adds fog User-Agent header". thanks Paul Thornthwaite + Inconsistent usage of cpus / vpcus in libvirt / requests. Reported number of cpus was always 1 for libvirt domains. thanks Romain Vrignaud + use CGI.escape when encoding the POST body. thanks Sam Cooper + Added versioned delete_multiple_objects support. thanks Timur Alperovich + Add support for volume_pool_name. thanks Vincent Demeester + fixes issue#1313 ~ Creating user via `Aws.iam.users` ignores `:path`. thanks VirtualStaticVoid + revised create logic to default path to '/'. thanks VirtualStaticVoid + added test for create logic to default path to '/'. thanks VirtualStaticVoid + added support for mock. thanks VirtualStaticVoid + revised test order. thanks VirtualStaticVoid + README: s/'cloud computing'/'cloud services'. thanks Wesley Beary + Adding explicit support for metadata for Rackspace compute_v2. thanks heyryanw + removed Fog::AWS[:rds] this was creating issues with was security credentials. thanks mauro catenacci + Adding public_ip_address and private_ip_address to Fog::Compute::RackspaceV2::Server. thanks sashap + Adding bootstrap and setup for RackspaceV2 servers. thanks sashap + +[openstack] + Add Accept header with application/json media type to requests. thanks Andrew Donald Kennedy + Refactor Openstack Authentication. thanks Nelvin Driz + Fix Typo in Merge of Authentication Refactoring. thanks Nelvin Driz + Make use of the unscoped token for reauthentication. thanks Philip Mark M. Deazeta + +[openstack|compute] + Add "Reset Server State" request. thanks Nelvin Driz + Add `get_limits` request. thanks Nelvin Driz + +[openstack|identity] + use tenant_id parameter in users model. thanks Philip Mark M. Deazeta + Add `attr_accessor :unscoped_token` to Mock. thanks Philip Mark M. Deazeta + +[opnestack|identity] + Added set_tenant request for identity service. thanks Philip Mark M. Deazeta + +[rackspace|computev2] + aded test for bootstrap. thanks Brian Hartsock + +[rackspace|dns] + fixed tests, merged some formatting to reduce duplication. thanks Brian Hartsock + +[rackspace|storage] + rackspace files tests should be pending in mocked mode. thanks geemus + +[readme] + update outdated sponsorship section. thanks geemus + +[vsphere] + ensure reload works correctly for server. thanks Ohad Levy + + +1.7.0 11/04/2012 aa853488c9d84d849f52cf348787030fbb963163 +========================================================= + +Stats! { 'collaborators' => 41, 'downloads' => 1216554, 'forks' => 599, 'open_issues' => 80, 'watchers' => 2206 } + +MVP! Nick Osborn + +[AWS::Mock|create_image] + automatic registration of ebs image upon image_create. thanks Chielo Zimmerman + +[AWS|Glacier] + Fix description header not being passed through Fog.escape. thanks Frederick Cheung + +[Brightbox] + Change code to return Single user. thanks Hemant Kumar + Adds ApiClient Model. thanks Hemant Kumar + Add identifier to get_account method. thanks Hemant Kumar + Reuses connection for image selection. thanks Paul Thornthwaite + Fixes cloud IP options default. thanks Paul Thornthwaite + Deprecates overloaded requests. thanks Paul Thornthwaite + Standardises update_firewall_rule. thanks Paul Thornthwaite + Deprecates old account update request. thanks Paul Thornthwaite + Use correct request to update account. thanks Paul Thornthwaite + Brightbox tests should select the smallest official image. thanks Steve Smith + Allows authentication as user. thanks Steve Smith + Allow users to lists all accounts associated with the current credentials. thanks Steve Smith + add support for User Applications. thanks Steve Smith + +[HP|Storage] + remove debug output. thanks geemus + +[Ninefold|Storage] + Use Atmos in Ninefold storage. thanks Timur Alperovich + +[aws|auto_scaling] + update display_*_types. thanks Nick Osborn + Fix documentation URL. thanks Nick Osborn + support termination policies. thanks Nick Osborn + correct DefaultCooldown in mocks. thanks Nick Osborn + documentation tinkering. thanks Nick Osborn + support ForceDelete for delete_auto_scaling_group. thanks Nick Osborn + better tag handling. thanks Nick Osborn + DRY out ARNs in mocks. thanks Nick Osborn + document Tags option to create_auto_scaling_group. thanks Nick Osborn + fix AutoScalingGroupName in mock. thanks Nick Osborn + expose delete_notification_configuration request. thanks Nick Osborn + improve describe_*_types test. thanks Nick Osborn + improve notification configurations. thanks Nick Osborn + s/data/self.data/ in mocks. thanks Nick Osborn + mark describe_*_types requests as idempotent. thanks Nick Osborn + tags support. thanks Nick Osborn + expose termination policies in group model. thanks Nick Osborn + +[aws|autoscaling] + fix casting availability_zones to array in create_auto_scaling_group mock. thanks geemus + mark problematic auto_scaling mocked tests as pending see also #1183. thanks geemus + +[aws|cdn] + cover AWS CDN with some non-exhaustive tests. thanks Brice Figureau + Implements AWS CDN get_invalidation request. thanks Brice Figureau + fix incorrect get_invalidation result. thanks Brice Figureau + add aws cdn tests for streaming distributions. thanks Brice Figureau + fix cdn documentation. thanks Brice Figureau + AWS CDN models. thanks Brice Figureau + add request mock support for AWS Cloudfront. thanks Brice Figureau + fix up failing mocked tests around invalidations. thanks geemus + +[aws|cloud_watch] + Add instrumentation support. thanks Michael Hale + +[aws|ec2] + describe_availability_zones parser handles nested tags. thanks Aaron Suggs + +[aws|rds] + add region and owner_id as RDS connection attributes. thanks Benton Roberts + add request definitions for RDS tagging and increment RDS API version. thanks Benton Roberts + add tests for RDS tagging requests. thanks Benton Roberts + add tagging methods to RDS server model. thanks Benton Roberts + add tagging tests for RDS server model. thanks Benton Roberts + store mocked RDS instance tags in connection object. thanks Benton Roberts + FIX non-1.8-compliant syntax bug. thanks Benton Roberts + +[misc] + modified create function to include options. changed "diskConfig" to "OS-DCF:diskConfig" to allow disk configuration to be properly set. thanks Alex Dunn + Removed options attribute and used the already existing disk_config attribute instead. Passed in options hash to create_server method with disk_config attribute unless nil. thanks Alex Dunn + Replace nil return value with private IP, implementation as in public_ip_address method. thanks Andrew Taylor + Change the metadata method to support amazon tags such as x-amz-website-redirect-location. thanks Arthur Gunawan + Fix issue #1245 - mock register_image fails with block device mapping. thanks Brice Figureau + Added ninefold load balancers. thanks Carl Woodward + Added other commands for load balancers. thanks Carl Woodward + Fix create load balancer test. thanks Carl Woodward + Add assign list to load balancer rules and update load balancer rule for Ninefold. thanks Carl Woodward + Add remove from load balancer test. thanks Carl Woodward + Move ssh private_key, public_key, username to Server model to reduce duplication. thanks Carlos Sanchez + Joyent server creation should not wait for server to be ready. thanks Carlos Sanchez + Added ParameterValue to engine_defaults_parser. thanks Curtis Stewart + Added outputs 'Description' field to DescribeStacks parser. thanks Curtis Stewart + Make region available to mock. thanks Edward Muller + Added OpenStack::Server#created and #updated. thanks Eric Hodel + Use :default from tests/.fog for test credentials. thanks Eric Hodel + Only run mocked tests by default. thanks Eric Hodel + Tested handling of Openstack server created and updated times. thanks Eric Hodel + create image now supports block device mapping. thanks Eric Stonfer + create image extended to allow for EBS volume handling. thanks Eric Stonfer + fix indexed_param usage. thanks Eric Stonfer + forgot to commit some changes. thanks Eric Stonfer + when querying servers by icenter group, servers will return nil. fixed this. thanks Eugene Howe + fixed bad request names. thanks Eugene Howe + correct the options checking in BlueBox create_block. thanks Josh Kalderimis + changed list nova servers request to get details. thanks Julio Feijo + Correct the handling of the power_on option. thanks Karan Misra + Added support for scheduler_hints in OpenStack. thanks Mariusz Pietrzyk + add force option to auto scaling group destroy method. thanks Michael Hale + use hash args. thanks Michael Hale + [AWS|cloud_watch]: fix list_metrics NextMarker should be NextToken. thanks Michael Hale + Fix to resolve "objectid is required for this operation" error message when calling public_url. thanks Michael Harrison + Fix to resolve "objectid is required for this operation" error message when calling public_url. thanks Michael Harrison + Return nil on public_url if the file isn't present on the cloud storage. thanks Michael Harrison + Added file existence check before file deletion attempt. thanks Michael Harrison + Rolled back deletion guard as some may be using the exception raised in their code. thanks Michael Harrison + Changed Atmos::FIle.public_url so an exception is thrown if the file doesn't exist on the cloud storage. thanks Michael Harrison + Changed Atmos::FIle.public_url so returns nil if the file doesn't exist on the cloud storage. This brings the method in line with other storage implementations such as AWS and Rackspace. thanks Michael Harrison + Changed Atmos::FIle.public_url so checks for existence of the file on storage on every call to the method minimising the potential for a 404 error. thanks Michael Harrison + added documentation. thanks Nick Huanuca + ammend dest_folder disclaimer. thanks Nick Huanuca + fixed vm listing problem. thanks Ohad Levy + Allows tests to run against FOG_RC setting. thanks Paul Thornthwaite + Beginning implementation of RDS subnet groups. thanks Rusty Geldmacher + Changes RDS subnet attribute name from subnets to subnet_ids. thanks Rusty Geldmacher + allow port to be included in queue_url. thanks Sairam + Fixed typos in elasticache and rds describe_events. Added better documentation of describe_events. thanks Sean Hart + Added test for describe_events.rb. It is very simple, and I'm not familiar with Shindo, so may need some assistance expanding. thanks Sean Hart + Added parsing for Marker. AWS limits response to 100 lines and gives you a marker to get the next batch with. thanks Sean Hart + Added missing header. thanks Stephen von Takach + Bumped mocked maximum value for provisioned iops. thanks Thom Mahoney + Ignore existing directory when creating on local storage. thanks Thomas Wright + Add config instructions to README. thanks Thomas Wright + Fix reference to config file. thanks Thomas Wright + expect public_key option instead of ssh_key on block create. thanks Trevor Bramble + Added usagePrice the hourly cost for a reserved instance. thanks Ulf Mansson + Added RDS describe_events. thanks Your Name + Created describe events for RDS. thanks Your Name + Update lib/fog/vsphere/requests/compute/vm_clone.rb. thanks endzyme + Update lib/fog/vsphere/requests/compute/vm_clone.rb. thanks endzyme + Update lib/fog/vsphere/requests/compute/vm_clone.rb. thanks endzyme + +[ninefold|compute] + update load balancer tests to pass hash parameters for backwards compatability. thanks geemus + mark before/after blocks as pending in mocked mode also. thanks geemus + +[openstack] + Authentication Mocks. thanks Nelvin Driz + Fix Failing Shindo Tests. thanks Nelvin Driz + Ensure String Username for Authentication. thanks Nelvin Driz + Changed volumes attributes of mocks from camelcase to snakecase. thanks Philip Mark M. Deazeta + Updated mocks for quota, image, tenant and volumes. thanks Philip Mark M. Deazeta + Fixed mocks for failing shindo tests. thanks Philip Mark M. Deazeta + Updated 'image update' mocks. thanks Philip Mark M. Deazeta + +[openstack|compute] + Added auth_token_expiration. thanks Alfonso Juan Dillera + Fixed security groups typos. thanks Alfonso Juan Dillera + Fix Server Mocks and `find_by_id` method. thanks Nelvin Driz + +[openstack|identity] + Update for failing mock test. thanks Alvin Garcia + Update Identity Mocking Process. thanks Nelvin Driz + Update Fog Mocks on Authentication, User and Roles. thanks Nelvin Driz + +[openstack|image] + Added update_members function. thanks Alvin Garcia + Added updateable attributes. thanks Alvin Garcia + Added optional attributes to set on create image. thanks Alvin Garcia + Fixed update image and list public images mocks. thanks Alvin Garcia + Fix Hash Access on Mock of Create Image. thanks Nelvin Driz + +[openstack|network] + Add support for OpenStack Quantum. thanks Ferran Rodenas + Add filters to networks, ports and subnets. thanks Ferran Rodenas + +[rackspace|identity] + user should be alphanumeric. thanks geemus + + +1.6.0 09/15/2012 4bd909557fd595a656ebd86a3d7c5849bd923fe1 +========================================================= + +Stats! { 'collaborators' => 40, 'downloads' => 1015900, 'forks' => 539, 'open_issues' => 55, 'watchers' => 2119 } + +[AWS] + Implement signature v4. thanks Frederick Cheung + Create the time directly in tests, avoids using a method not present in 1.8.7. thanks Frederick Cheung + avoid spurious test failure when tag test returns before images test. thanks Frederick Cheung + Adding missing :glacier case for AWS.collections. thanks Frederick Cheung + +[AWS|AutoScaling] + Typo in delete_autoscaling_group mock: Autoscaling->AutoScaling. thanks Frederick Cheung + fix group#instances. thanks Frederick Cheung + Fix describe_auto_scaling_groups parser added spurious nil groups. thanks Frederick Cheung + Fix delete_auto_scaling_group.rb mock not raising the same error as real code. thanks Frederick Cheung + +[AWS|Compute] + Add the ablity to pass :version and use newer AWS API. thanks Zuhaib M Siddique + +[AWS|Glacier] + Bare glacier service. thanks Frederick Cheung + single part uploads. thanks Frederick Cheung + multipart uploads. thanks Frederick Cheung + Jobs requests. thanks Frederick Cheung + vaults model. thanks Frederick Cheung + Use bytesize rather than length. thanks Frederick Cheung + models for archives. thanks Frederick Cheung + jobs model. thanks Frederick Cheung + Add notification configuration to model. thanks Frederick Cheung + mark tests as pending. thanks Frederick Cheung + byteslice is only available in 1.9.3 - add fallback for 1.9.2. thanks Frederick Cheung + fix 1.9.2 fallback. thanks Frederick Cheung + make 1.8.7 friendly. thanks Frederick Cheung + Fix job type constant. thanks Frederick Cheung + fix setting description on multipart upload. thanks Frederick Cheung + fix name of header used for description. thanks Frederick Cheung + Allow filtering of jobs collection. thanks Frederick Cheung + Don't try to deserialize json when body is empty. thanks Frederick Cheung + +[AWS|RDS] + expose the SnapshotType attribute & allow filtering by it. thanks Frederick Cheung + +[AWS|Signaturev4] + allow symbols to be used as header/query keys. thanks Frederick Cheung + +[AWS|Storage] + mark upload_part as idempotent so it will be retried automatically. thanks Frederick Cheung + +[Brightbox] + Fix output format for brightbox cloud ip. thanks Hemant Kumar + +[Brightbox|CloudIp] + Remove duplicate constant definition for port translators. thanks Hemant Kumar + +[Cloudstack] + 1.8.7 compat: on 1.8.7 '123'[0] returns the byte value of '0' and not '1'. thanks Frederick Cheung + +[Core] + fix format_helper assuming p returns nil. thanks Frederick Cheung + +[HP] + delete_if returns the array, not what was deleted. thanks Frederick Cheung + +[OpenStack] + fixes wrong method name. thanks Ohad Levy + +[Openstack] + Fix mock returning a hash instead of an array. thanks Frederick Cheung + +[Openstack|Compute] + Security Groups are not assigned correctly to servers. thanks Ohad Levy + +[aws|auto_scaling] + Add instrumentation support. thanks Michael Hale + +[aws|compute] + fix typo in deprecation warning. thanks Aaron Suggs + Nicer interface for security group authorizations. thanks Aaron Suggs + Add instrumentation support. thanks Dan Peterson + Support creating and describing volumes with provisioned IOPS. thanks Dan Peterson + Get instance requests tests working. thanks Dan Peterson + Support for EBS-optimized instances. thanks Dan Peterson + Pass empty groupIds when mocking. thanks Dan Peterson + DescribeInstanceStatus code within eventsSet goes on the item. thanks Dan Peterson + fixes for spot request waiting see also #841. thanks geemus + remove brittle instance tests which rely on tests running fast p.s. these fail on travis-ci. thanks geemus + fix mock filters for internet gateways/subnets/vpcs. thanks geemus + +[aws|elb] + Add instrumentation support. thanks Dan Peterson + fixes for mock tests. thanks geemus + +[aws|iam] + Add instrumentation support. thanks Dan Peterson + +[aws|rds] + Correct server#read_replica_identifiers when mocking. thanks Aaron Suggs + Mocking better supports reboot state. thanks Aaron Suggs + Mocking better supports modifying state. thanks Aaron Suggs + Fix server tests. thanks Aaron Suggs + Mocking support for read replicas. thanks Aaron Suggs + Mock support for setting AZ and MultiAZ. thanks Aaron Suggs + +[brightbox] + Use first available image for server tests. thanks Steve Smith + +[brightbox|ServerGroup] + ServerGroups can have a nil name. thanks Steve Smith + +[brightbox|compute] + Merged outstanding work from Brightbox's fork. thanks Paul Thornthwaite + Implemented reboot using available API commands. thanks Paul Thornthwaite + Updates to Test helper for select image. thanks Paul Thornthwaite + Helper to get default image from API. thanks Paul Thornthwaite + +[cloudstack|compute] + remove erroneous comma in merge command. thanks geemus + +[compute|Ecloud] + Ecloud should not show up as a valid provider when not providing credentials. thanks Eugene Howe + +[dynect|dns] + Only JSON decode when Content-Type says so. Fixes job handling. thanks Dan Peterson + Job polling should use original expected statuses. thanks Dan Peterson + +[google/storage] + Fix docs for new GCS urls. thanks Nat Welch + +[google|storage] + update expected format to remove StorageClass. thanks geemus + also update mocks to omit storageclass. thanks geemus + +[hp|storage] + Use response_block param, as excon has deprecated implicit blocks. thanks Ferran Rodenas + +[misc] + When using mock mode, Range header is now not ignored in get_object(). thanks Ahmed Al Hafoudh + Documentation error for delete_object. thanks Alex Tambellini + Add barebones configuration for Travis CI. thanks Alexander Wenzowski + add Travis CI build status image. thanks Alexander Wenzowski + notify #ruby-fog on freenode instead of emailing. thanks Alexander Wenzowski + remove repository_url from notification template Interpolation of %{repository_url} is currently broken on Travis CI. thanks Alexander Wenzowski + CloudStack: added registerTemplate request. thanks Aliaksei Kliuchnikau + CloudStack: listTemplates, registerTemplate requests return hypervisor in the response. thanks Aliaksei Kliuchnikau + Enable AWS spot requests in a VPC by specifying subnet_id. thanks Ben Turley + Fix for RDS VPC subnet groups. thanks Ben Turley + parse ASCII code * in wildcard domain. Fixes #1093. thanks Blake Gentry + automatically figure out the elb hosted_zone_id if possible. thanks Blake Gentry + Add source for getting instance mac address. thanks Carl Caum + Only add VNC password and listen port if present. thanks Carl Caum + Revert 530122d. thanks Carl Caum + Abillity to List Images and List SSH Keys. thanks Chirag Jog + Add support to create, delete internet services. thanks Chirag Jog + Accept vCPUS and Memory as parameters while creating servers. thanks Chirag Jog + Minor Fixes: Remove unncessary prints. Use override_path instead of replace class variable path. thanks Chirag Jog + Fix support to add internet service to the existing Public Ip. thanks Chirag Jog + Support to configure vapp and add multiple internet services. thanks Chirag Jog + Remove uneccessary puts. thanks Chirag Jog + Add support to build/re-build/clobber gem/package/docs. thanks Chirag Jog + Fix minor issue. thanks Chirag Jog + Re-work based on Geemus's review. Manage InternetService and NodeService as separate entities Reload server status properly. thanks Chirag Jog + Revert Rakefile changes. thanks Chirag Jog + 1.Ability to fetch/list Orgs, Vdcs, Vapps, Servers. 2.Support to customize CPUs and Password. thanks Chirag Jog + Add ability to configure a vApp with an Org-wide network and associated firewall, NAT rules(limited support). thanks Chirag Jog + 1.Fix Catalog Listing for vCD 1.5 2.Construct Valid XML to memory configuration 3.Fix Undeploy vCD 1.5. thanks Chirag Jog + Added m1.medium instance type for AWS flavors. thanks Curtis Stewart + - Updated "@host" variable to "noc.newservers.com" which is the current host for API calls - Added two calls: add_server_by_configuration.rb and list_configurations.rb -- These calls should be used instead of add_server and list_plans, although we still support them. - General comments were updated. thanks Diego Desani + Add gsub to replace URL-encoded characters in the public_url method. thanks Eric Chernuka + fix reboot guest in vsphere to reboot rather than shutdown guest. thanks Eric Stonfer + added file upload and ip add capabilities. thanks Eugene Howe + added error handling for edge cases where there are no networks or ips. thanks Eugene Howe + [AWS|Glacier} basic vault operations. thanks Frederick Cheung + fix mock not returning the right data. thanks Frederick Cheung + set Content-MD5. thanks Frederick Cheung + Add fqdn to server attributes. thanks Hemant Kumar + Brightbox : Include licence_name in Image. thanks Hemant Kumar + Brightbox: Change licence_name type to Fog::Nullable::String. thanks Hemant Kumar + Add support for port translators. thanks Hemant Kumar + Rackspace Storage: new request, get_object_https_url. thanks James Healy + Rackspace Storage: new request, post_set_meta_temp_url_key. thanks James Healy + Rackspace Storage: a backslash shouldn't be escaped when signing URLS. thanks James Healy + add a basic spec for Rackspace::Storage#get_object_https_url. thanks James Healy + add basic spec for Rackspace::Storage##post_set_meta_temp_url_key. thanks James Healy + Rackspace Storage: fix expiring URLs that contain a hyphen. thanks James Healy + Add Serverlove directory. thanks James Rose + Basic Serverlove implementation. thanks James Rose + Wrong directory. thanks James Rose + Typo. thanks James Rose + Proper request arguments. thanks James Rose + Typo. thanks James Rose + Still wrong. thanks James Rose + Works. thanks James Rose + We want JSON. thanks James Rose + Typo. thanks James Rose + add high io flavor to aws flavors. thanks Josh Lane + Move Dynect endpoint from api2 to api-v4. thanks Marc Seeger + don't let the Paulistas be left out of the party. thanks Martin Englund + use 10.04 instead of 12.04. thanks Martin Englund + Google changed their URL scheme for Cloud Storage. thanks Nat Welch + Also change GCS url in dir and file models. thanks Nat Welch + Update lib/fog/hp/models/compute/image.rb. thanks Neill Turner + Update lib/fog/hp/models/compute/server.rb. thanks Neill Turner + Update lib/fog/aws/requests/compute/describe_instance_status.rb. thanks Oleg + Added new Server#fqdn attribute to test helper. thanks Paul Thornthwaite + Rewrite tests to use 1.8 compatible Hash syntax. thanks Paul Thornthwaite + Add missing providers to the all_providers list for testing. thanks Paul Thornthwaite + Use string not symbols for Storage tests to work with Shindo tagging. thanks Paul Thornthwaite + Retagged tests with strings to be skipped by Shindo. thanks Paul Thornthwaite + Tagged AWS URL test so correctly ignored by Shindo. thanks Paul Thornthwaite + Reduce maintenance of tests by using a dynamic list of providers. thanks Paul Thornthwaite + add support for multiple regions in Opentack. thanks Pedro Perez + Fixed the link to GitHub issues. thanks Postmodern + Change iprange --> ec2_secg in Mock. thanks Rob Lockstone + Added support for RDS VPC subnet groups. Bumped RDS API version to 2012-01-15. thanks Rusty Geldmacher + Added DBSubnetGroupName to test format for RDS instances. thanks Rusty Geldmacher + Adding server love disk model. thanks Sean Handley + Changed disk model based on responses from real API requests. thanks Sean Handley + Set up drive objects (not disks). thanks Sean Handley + If you use info, you get all the info. thanks Sean Handley + Alias the encryption cipher. thanks Sean Handley + Sometimes the response body is empty. thanks Sean Handley + Destroying drives is easy. thanks Sean Handley + Allowed setting of params as k/v pairs. thanks Sean Handley + Added create/update functionality. thanks Sean Handley + Made create/save conform to the Fog API. thanks Sean Handley + Returning self is totes better than bools. thanks Sean Handley + Fog calls drives "images", rename for consistency. thanks Sean Handley + Beginnings of shin do request tests. thanks Sean Handley + Need these to run the server love tests. thanks Sean Handley + Beginnings of tests for image operations. thanks Sean Handley + Adding mock for easier testing. thanks Sean Handley + Added get_image function. thanks Sean Handley + Added meaningful test for updating images. thanks Sean Handley + Typo!. thanks Sean Handley + Fix conflict. thanks Sean Handley + This shouldn't be here. thanks Sean Handley + Can't run shindo tests with old references. thanks Sean Handley + Added loading of standard image. thanks Sean Handley + Shindo tests pass. thanks Sean Handley + Test that we can view servers. thanks Sean Handley + Whitespace adjustments. thanks Sean Handley + CRUDs + tests for servers. thanks Sean Handley + Added server power cycle actions + basic tests. thanks Sean Handley + Add new request methods to server object. thanks Sean Handley + Use get_server, not get_image. thanks Sean Handley + Need a mock server id. thanks Sean Handley + This was plain wrong - works now!. thanks Sean Handley + Don't start servers by default. thanks Sean Handley + Contrary to the documentation, this actually returns a 200 status rather than a 204. thanks Sean Handley + Allow setting of memory and disk drives. thanks Sean Handley + Allow DHCP assignment by default. thanks Sean Handley + Key 'vnc:ip' was invalid. thanks Sean Handley + Update allowed attributes and defaults. thanks Sean Handley + Increase test drive size to accommodate a real image. thanks Sean Handley + Without setting SMP the web UI won't load :-/. thanks Sean Handley + Reduce from 80GB to 20GB - big enough, save space. thanks Sean Handley + Standard images need to be unzipped. thanks Sean Handley + Need to wait for imaging to complete. thanks Sean Handley + Add a pseudorandom password generator for VNC. thanks Sean Handley + Auto generate VNC password randomly. thanks Sean Handley + Used the amazon published endpoints for sqs as defined at http://docs.amazonwebservices.com/general/latest/gr/rande.html#sqs_region. thanks Stuart Eccles + Better mocks for invalid Provisioned IOPS values. thanks Thom Mahoney + Add generic support for EMC Atmos. thanks Timur Alperovich + Submit password/ssh_key/username through POST body. thanks Trevor Bramble + Update public_url to handle new header casings from Rackspace. thanks Zachary Danger Campbell + CloudStack: images.get always returns nil - fixed. thanks alex + add changelog for 1.5.0. thanks geemus + fixes for cloudstack mock tests see #1090. thanks geemus + fix mocked elb tests by including InstanceProtocol closes #1090. thanks geemus + expand travis config, build more rubies, use non-threaded runner. thanks geemus + just run mri for now on travis. thanks geemus + remove empty failure block from model_helper. thanks geemus + allow 1.8.7 to fail and not report for now (until I can work out why it fails when 1.9.x works. thanks geemus + return to expecting 1.8.7 to pass. thanks geemus + fix deprecated requires in Rakefile. thanks geemus + Made steps to get update/create working. Work in progress. thanks seanhandley + Update lib/fog/aws/models/compute/security_group.rb. thanks vkhatri + +[rackspace|blockstorage] + Add volume tests. thanks Brad Gignac + Add volume type tests. thanks Brad Gignac + Add snapshot tests. thanks Brad Gignac + Add relationship between volumes and snapshots. thanks Brad Gignac + Add block storage provider. thanks Julio Feijo + Add volume types to block storage. thanks Julio Feijo + Add snapshots to block storage. thanks Julio Feijo + +[rackspace|compute] + Add service for Cloud Servers v2.0. thanks Brad Gignac + Add flavors and images. thanks Brad Gignac + Add servers model and collection. thanks Brad Gignac + Set password attribute on V2 servers. thanks Brad Gignac + Don't intern nil strings. thanks Brad Gignac + Add method for listing attachments. thanks Brad Gignac + Add tests for volume attachments. thanks Brad Gignac + Improve attachment test reliability. thanks Brad Gignac + Add attachments model and collection. thanks Julio Feijo + +[rackspace|storage] + Override path when generating sha1 to make tests past. thanks Brian Hartsock + +[serverlove|compute] + fix serverlove tests for 1.8.7 compatibility. thanks Frederick Cheung + fix serverlove tests for 1.8.7 compatibility. thanks geemus + + +1.5.0 07/28/2012 2e57e2029abbb618411c20f8974e64d8d3fd31fe +========================================================= + +Stats! { 'collaborators' => 36, 'downloads' => 870008, 'forks' => 500, 'open_issues' => 44, 'watchers' => 2074 } + +[AWS|Autoscaling] + fix group#instances returning all autoscaled instances in the account. thanks Frederick Cheung + +[Libvirt] + fixed incorrect mock method signature. thanks Ohad Levy + ensure Fog volumes do not raise on LVM based volumes. thanks Ohad Levy + +[aws|compute] + Address#destroy handles VPC addresses, improve address allocate/release mocking for VPC. thanks Dan Peterson + +[aws|elasticache] + Fix bug in cache cluster test. thanks Benton Roberts + Remove erroneous whitespace trimming. thanks Benton Roberts + Add Elasticache service-level mocking support. thanks Benton Roberts + Add mocking for cache cluster requests. thanks Benton Roberts + Change modify_cache_cluster test to work in mocking mode. thanks Benton Roberts + Enable mocking for elasticache cluster tests. thanks Benton Roberts + Mock raises NotFound Exception when AWS does. thanks Benton Roberts + +[aws|storage] + Default to false for persistent connections. thanks Kenny Johnston + +[cloudstack|security_group] + fix rule revoke mock. thanks Josh Lane + +[cloudstack|security_groups] + add groups and rules. thanks Josh Lane & Jason Hansen + +[cloudstack|server] + assign security group. thanks Josh Lane & Jason Hansen + +[dynect|dns] + No more recursion when polling jobs. Raise an error if the body indicates failure. thanks Dan Peterson + +[fix-ephemeral-naming] + Typo in ephemeral naming. thanks Josh Pasqualetto + +[joyent|compute] + fix dataset format in tests. thanks geemus + +[local|storage] + mark tests pending in mock mode. thanks geemus + +[misc] + fix changelog task for github API v3. thanks Aaron Suggs + update changelog for release 1.4.0. thanks Aaron Suggs + changelog: backdate to release data. thanks Aaron Suggs + Local storage support for #public_url. thanks Adam Tanner + Bugfix in Fog::DNS::AWS::Records.all!. thanks Alexander Kolesen + Fix for stopping all the servers instead of just specified servers. thanks Avrohom Katz + private ip address should start with a 10. thanks Avrohom Katz + Use proper signature when testing with aws mock. thanks Bohuslav Kabrda + The user must be destroyed even in mock mode, otherwise completely unrelated tests fail (e.g. tests/aws/models/iam/users_tests.rb). thanks Bohuslav Kabrda + The condition here should be the same as for destroying, so that we test iff the instance gets destroyed. thanks Bohuslav Kabrda + The assignment correctly returns nil, just the test has to react to it. thanks Bohuslav Kabrda + The assignment correctly returns false, just the test has to react to it. thanks Bohuslav Kabrda + Include this to make refresh_credentials_if_expired method work properly with Mock. thanks Bohuslav Kabrda + Fix the number where credentials expire - if too high, other tests will fail. thanks Bohuslav Kabrda + Fix openstack tests. thanks Bohuslav Kabrda + Fix more openstack mock tests failures. thanks Bohuslav Kabrda + Add the mock urls to fix some more openstack tests. thanks Bohuslav Kabrda + Fix minor typos and incorrect types in openstack volume tests. thanks Bohuslav Kabrda + More typos in openstack server tests. thanks Bohuslav Kabrda + Rework the quota mock testing to work and be more comfortable. thanks Bohuslav Kabrda + Must use values, so that connection.list_roles gets corrent argument. thanks Bohuslav Kabrda + Deleting returns nothing, so do not expect role. thanks Bohuslav Kabrda + Properly check whether role is present. thanks Bohuslav Kabrda + Return the properly updated image. thanks Bohuslav Kabrda + Add the 'new_image' public images, so that find_by_id can find it. thanks Bohuslav Kabrda + The pending block fails the outer one => make sure we return proper result. thanks Bohuslav Kabrda + Use proper parameters when testing deploying cloudstact VMs. thanks Bohuslav Kabrda + This was implemented right previously, shouldn't have changed it. thanks Bohuslav Kabrda + Correct solution for subnet failing tests - use a collection in self.data. thanks Bohuslav Kabrda + Do the same thing for vpcs as previously done for subnets. thanks Bohuslav Kabrda + ...and the same for dhcp_options. thanks Bohuslav Kabrda + And the same for internet gateways. thanks Bohuslav Kabrda + Fixes the failure for hp storage. thanks Bohuslav Kabrda + [rackspace|databases| Add service tests. thanks Brad Gignac + fix for RDS mocking to avoid state flipping between "modifying" and "available". thanks Brian Nelson + Fix typo listing datacenters. thanks Carlos Sanchez + Stop vSphere vms before destroying, or destroy will fail. thanks Carlos Sanchez + Add a failure for #1014. :v:. thanks Dylan Egan + Only dup @attributes if it's not nil. thanks Edward Muller + each based pagination for Fog::AWS::IAM#users. thanks Edward Muller + fixes elb test in mocking mode. thanks Eric Stonfer + fix running subnet tests in mocking mode. thanks Eric Stonfer + fix subnet tests in mocking mode. thanks Eric Stonfer + fog bombs out on ruby 1.8.x because it cannot find Mutex. thanks Eric Stonfer + fix not pulling InstanceProtocol from the xml. thanks Frederick Cheung + Add Sao Paulo server to Amazon RDS known regions. thanks Irio Irineu Musskopf Junior + Add Sao Paulo server to Amazon SQS known regions. thanks Irio Irineu Musskopf Junior + Fix bug in local storage #copy_object. thanks Jade Tucker + Add and get SSL certificates to Rackspace Soft LB. thanks Justin Barry + Default to being less pessimistic about excon. thanks Kevin Moore + Fix ssh key behavior when passing specified private keys to ssh/scp. thanks Marc Seeger + Should not modify passed in "params" variable since block might run several times due to authentication failure producing erroneous path. thanks Max Stepanov + As discussed in #991, this converts the readme from SimpleMarkup to Markdown. thanks Mike Fiedler + added PeopleAdmin to list of users. thanks Mike Manewitz + Fixing typo bug in rackspace load balancer set_ssl_termination request. thanks Paul + add us-east-1e to mock. thanks Shai Rosenfeld + Pass up all the options that have been assigned. thanks Trotter Cashion + Pass options on to AutoScalingGroup. thanks Trotter Cashion + Add better ScalingPolicy support. thanks Trotter Cashion + Add more AWS Alarm functionality. thanks Trotter Cashion + Add delete mocks. thanks Trotter Cashion + Properly array-ify keys for create_auto_scaling_group. thanks Trotter Cashion + Add tags to autoscaling groups. thanks Trotter Cashion + Enable tests when mocking. thanks Trotter Cashion + Recognize ninefold_api_url option for pre-production testing. thanks Warren Bain + remove specs (likely from a bad merge). thanks geemus + update tests/helper to have bare_metal_cloud instead of new_servers. thanks geemus + Mock for filter ec2 instances by group name. thanks phillc + +[openstack] + Fix Authentication for OpenStack v1.1 Authentication. thanks Nelvin Driz + +[openstack|compute] + Add filters to list servers details. thanks Ferran Rodenas + Added adminPass attribute in create_server. thanks Philip Mark M. Deazeta + fix method signature for mock list_servers_detail. thanks geemus + +[openstack|image] + Stream OpenStack image. thanks Vadim Spivak + +[rackspace|databases] + Add read-only support for Rackspace Cloud Databases. thanks Brad Gignac + Add write support for Rackspace Cloud Databases. thanks Brad Gignac + Register Rackspace Cloud Databases service with Fog. thanks Brad Gignac + Remove "list/details" API calls in favor of "list" calls. thanks Brad Gignac + Add model tests. thanks Brad Gignac + Finish request tests. thanks Brad Gignac + Remove old comments. thanks Brad Gignac + Handle breaking API changes. thanks Brad Gignac + Initial pass at request tests. thanks Brian Hartsock + +[rackspace|identity] + Add Rackspace identity service. thanks Brad Gignac + Add requests and request tests. thanks Brad Gignac + Add user model and collection with tests. thanks Brad Gignac + Handle non-array responses from list calls. thanks Brad Gignac + Better checking around hash/array responses. thanks Brad Gignac + Handle NotAuthorized respones from the identity API in the user model. thanks Brian Hartsock + use a valid username in tests. thanks geemus + +[rackspace|lb] + fixed broken tests because of API format changes. thanks Brian Hartsock + ssl termination fixes. thanks Brian Hartsock + moved to Fog::JSON.encode instead of MultiJson.encode. thanks Brian Hartsock + + +1.4.0 06/24/2012 24e0be755e251159f07d5d82beb1e8ef57c962d9 +========================================================= + +Stats! { 'collaborators' => 35, 'downloads' => 800348, 'forks' => 477, 'open_issues' => 43, 'watchers' => 2080 } + +MVP! Nelvin Driz + +[AWS] + make beanstalk, cdn, cloudformation, cloudwatch, elasticache, elb, storage, rds, ses, sns, route53 temporary credential friendly. thanks Frederick Cheung + +[AWS|Auto Scale] + Add support for put_notification_configuration and change AWS API to use 01-01-2011 Spec. thanks Zuhaib M Siddique + +[AWS|Autoscale] + Fixing Parameters notes for autoscale create launch configuration for InstanceMonitoring. Credit goes to boto, https://github.com/boto/boto/blob/develop/boto/ec2/autoscale/__init__.py , for having it correct. thanks Zuhaib M Siddique + Fixing Parameters notes for autoscale create launch configuration for InstanceMonitoring. Credit goes to boto, https://github.com/boto/boto/blob/develop/boto/ec2/autoscale/__init__.py , for having it correct. thanks Zuhaib M Siddique + +[Openstack|Compute] + Usage Requests. thanks Hunter Nield + Migration and Console output. thanks Hunter Nield + server methods for console and migration. thanks Hunter Nield + Minor address cleanup. thanks Hunter Nield + +[aws|address] + fixes release_address for VPC EIPs * amazon requires allocation_id only for vpc eips, and public_ip otherwise. thanks Albert Choi + +[aws|beanstalk] + Added missing :beanstalk case. thanks George Scott + Added #load_balancer method. thanks George Scott + Serialize keys for SourceConfiguration. thanks George Scott + Added modify method for template. thanks George Scott + Support different AWS regions. thanks George Scott + Added swap_cnames method. thanks George Scott + +[aws|compute] + add networkInterfaceSet context to EC2 instance parser. thanks Benton Roberts + +[aws|dns] + Allow both Ruby and AWS style names for alias. thanks George Scott + Support for latency/weighted resource sets. thanks George Scott + Fixed #all iteration. thanks George Scott + Reimplemented #get. thanks George Scott + Added #all! method to Records. thanks George Scott + +[aws|dynamodb] + correct batch_put_item to batch_write_item for consistency with API. thanks geemus + +[aws|elb] + Failing test for load_balancers marker support. thanks Dan Peterson + Deprecate describe_load_balancers with just an array of names. thanks Dan Peterson + Marker support for describe_load_balancers. thanks Dan Peterson + Fix use of describe_load_balancers in tests. thanks Dan Peterson + load_balancers.get(nil) returns nil instead of the first of all load balancers. thanks Dan Peterson + +[aws|iam] + Add test for AWS[:iam].get_user. thanks Benton Roberts + add test for AWS[:iam].get_user_policy. thanks Benton Roberts + FIX - make arguments AWS::IAM.get_user conform to expected standard for this module. thanks Benton Roberts + Fix Users model to comply with updated request parameter set. thanks Benton Roberts + mark role tests as pending in mock mode. thanks geemus + +[aws|storage] + fix flipped logic on valid acl check closes #889. thanks geemus + fix method signature for setup_credentials. thanks geemus + +[aws|storage|] + Make get_object_http_url use correct S3 host in returned URL. thanks Michiel Sikkes + Make get_object_http_url use correct S3 host in returned URL. thanks Michiel Sikkes + +[brightbox|compute] + Updated image reference where unfortunately hardcoded. thanks Paul Thornthwaite + Remove resize request since not available. thanks Paul Thornthwaite + Update format tests for new attributes on Cloud IPs. thanks Paul Thornthwaite + Update format tests for "fqdn" attribute. thanks Paul Thornthwaite + Update format tests for updates to Image. thanks Paul Thornthwaite + +[cloudstack] + prevent mock test failure when cloudstack credentials are not defined. thanks geemus + add to list of providers so it can be skipped when lacking credentials. thanks geemus + +[cloudstack|compute] + zones,flavors,images,address. thanks Jason Hansen & Josh Lane + support async jobs. thanks Jason Hansen & Josh Lane + server abstraction and mocks. thanks Josh Lane & Jason Hansen + volumes support. thanks Josh Lane & Jason Hansen + +[compute] + volume tests. thanks Josh Lane & Jason Hansen + +[compute|aws] + Apply tags to volume at creation. thanks Dan Carley + Respect extra register_image options when mocking. thanks Dan Peterson + extend polling interval for spot_requests bootstrap. thanks geemus + cleanup internet_gateway mocks and remove debug output. thanks geemus + +[compute|openstack] + update server attributes for shared compute tests. thanks geemus + cleanup for list security groups request/mock. thanks geemus + +[docs] + fix link to EngineYard logo (broken in /storage, /compute, etc.). thanks Len + +[ecloud|compute] + Adding multiple disks at once was not working properly. thanks Eugene Howe + fix optional params for validate_data closes #969. thanks geemus + +[glesys|compute] + update server/status format to include cpu hash and warnings. thanks Anton Lindström + add reboot and compute test params. thanks Anton Lindström + +[hp|compute] + fix tests to properly set default base image. thanks geemus + +[ibm|compute] + Typo in parameter name, should be storageID. thanks Decklin Foster + +[joyent|compute] + Fixes issue where params are not properly passed to #keys_create from #create_key. thanks Kevin Chan + Added #list_datacenters. thanks Kevin Chan + Support for DSA keys for auth. thanks Kevin Chan + +[libVirt] + added tests. thanks Amos Benari + +[libvirt] + refactored libvirt entire code. thanks Ohad Levy + expose node hostname. thanks Ohad Levy + added display attributes and allowed to change display of a running server. thanks Ohad Levy + volumes dev names must be uniq. thanks Ohad Levy + makes libvirt code more debian friendly. thanks Ohad Levy + - ensure no nil pools are returned. thanks Ohad Levy + Fix SSH keyfile being pulled from wrong param. thanks brookemckim + skip tests if ruby-libvirt is unavailable. thanks geemus + correct error message when skipping tests. thanks geemus + +[misc] + Add support for internal ELBs in VPC. thanks Aaron Bell + cleaning up model. thanks Aaron Bell + fix parser to show scheme, add test for internal ELB creation. thanks Aaron Bell + fixing test. thanks Aaron Bell + add scheme to elb helper. thanks Aaron Bell + adds batch_put_item functionality to AWS dynamodb + test. thanks Alex Gaudio + Fixed non-persistent connections handling to AWS. thanks Alexander Kolesen + Fixed handling options[:persistent] in some cases. thanks Alexander Kolesen + added mock implementation. thanks Amos Benari + removed unneeded dependency,. thanks Amos Benari + new rbovirt version. thanks Amos Benari + use constant for GB. thanks Amos Benari + Adding network interface information and security group ids. thanks Artem Veremey + Adding network interface information and security group ids to the model. thanks Artem Veremey + Store the region for S3. thanks Ben Butler-Cole + add create_hosted_zone and get_hosted_zone request mocks. thanks Bulat Shakirzyanov + add list_hosted_zones request mock. thanks Bulat Shakirzyanov + add change_resource_record_set request mock. thanks Bulat Shakirzyanov + fix response codes and formatting. thanks Bulat Shakirzyanov + fix typos. thanks Bulat Shakirzyanov + fix identifiers. thanks Bulat Shakirzyanov + use hard-coded sample value to eliminate randomness. thanks Bulat Shakirzyanov + fix typos. thanks Bulat Shakirzyanov + fix zone id in create_hosted_zone response. thanks Bulat Shakirzyanov + fix attribute name. thanks Bulat Shakirzyanov + add authorize and revoke port range for security group. thanks Bulat Shakirzyanov + Fix typo. thanks Christopher Meiklejohn + Specify image_ref rather than trying to instantiate object. thanks Christopher Meiklejohn + Fog::Compute::AWS::Address#server -> assigned Server. thanks Dr Nic Williams + fix auto-discovery for HP Cloud by fog bin. thanks Dr Nic Williams + whitespace. :bomb: :v:. thanks Dylan Egan + Default to false for persistent connections. You can't pass in false. This now behaves like other connections in fog. :v:. thanks Dylan Egan + Idempotent Dynect calls. :v:. thanks Dylan Egan + Fix up describe_volume_status to work with THE ARRAYZ. :v:. thanks Dylan Egan + Fog::AWS.indexed_reuqest_param. thanks Edward Muller + include the nextToken in the body. thanks Edward Muller + complete Request param support. thanks Edward Muller + refactor to use Fog::AWS.indexed_request_param. thanks Edward Muller + the old parser was not working properly. thanks Edward Muller + All directories.create on us-east-1. thanks Edward Muller + us-west-2 default ami. thanks Edward Muller + some small fixups. thanks Edward Muller + make the aws region accessible. thanks Edward Muller + Fog::Compute::Server#private_key=. thanks Edward Muller + Fog::Compute::Server#sshable?. thanks Edward Muller + ssh/run optionally takes a block. thanks Edward Muller + Cleanup after talking to @dpiddy. thanks Edward Muller + return '' not nil. thanks Edward Muller + Revert "Add debug option to Fog::Compute::Server#ssh". thanks Edward Muller + Mock stop_instances. thanks Edward Muller + Mock aws compute start_instances. thanks Edward Muller + Don't duplicate effort. thanks Edward Muller + Add ssh_port to Fog::Compute::Server. thanks Edward Muller + Generalize NoLeak Inspector for Fog::Service. thanks Edward Muller + Don't leak HP cdn & storage. thanks Edward Muller + Make aws compute server retry SSH on EHOSTUNREACH. thanks Eric Boehs + Copied auth token reauthentication from rackspace|compute. thanks Eric Hankins + https://github.com/fog/fog/issues/810 - Add ENI support by maf23. thanks Eric Stonfer + minor fix to ENI tests. thanks Eric Stonfer + VPC ELBs, Tests, and the introduction of the InternetGateway object. thanks Eric Stonfer + clean up conflict. thanks Eric Stonfer + this adds the dhcp_options object and associated operations. thanks Eric Stonfer + merge upstream. thanks Eric Stonfer + forgot to commit dhcp_options tests. thanks Eric Stonfer + fix describe_volume_status parser. thanks Eric Stonfer + add some more explanation to the server creation process. thanks Eric Stonfer + testing. thanks Eugene Howe + added requests and models for compute_pools. thanks Eugene Howe + changed to urn:tmrk:eCloudExtensions-2.8. thanks Eugene Howe + require compute pool to be specified on vapp creation. thanks Eugene Howe + set default value for computePool on vapp creation. thanks Eugene Howe + Made computePool an optional parameter, specs now pass without issue. thanks Eugene Howe + Removed non-functioning Mock classes. thanks Eugene Howe + fixed method name. thanks Eugene Howe + start an instance with an IAM profile and access the credentials. thanks Frederick Cheung + add new iam requests to support iam roles. thanks Frederick Cheung + request tests for the new iam role requests. thanks Frederick Cheung + test credential fetching. thanks Frederick Cheung + use excon rather than net/http. thanks Frederick Cheung + remove stray multijson require. thanks Frederick Cheung + fix errant use of net/http. thanks Frederick Cheung + Add debug option to Fog::Compute::Server#ssh. thanks Gabriel Horner + Correct docs for change_resource_record_sets. thanks Gavin Sandie + add cc2.8xlarge AWS flavor. thanks Ian Downes + Fix user-data attribute name. thanks Igor Bolotin + Refactor AWS Directory. thanks James Herdman + Remove unused variable. thanks James Herdman + Fix indentation warning. thanks James Herdman + Remove unnecessary full path usage with require. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused accessor. thanks James Herdman + Silence warning regarding splat operator. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Silence warnings about potentially private attribute. thanks James Herdman + Remove unused variable. thanks James Herdman + Silence warning about potentially private attribute. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove duplicate require. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove absolute path when requiring. thanks James Herdman + Remove unused variable. thanks James Herdman + Remove duplicate Mock class definition. thanks James Herdman + implement Fog::SSH::Mock#run. thanks Jason Hansen & Josh Lane + add a method to IPAddr instead of breaking a useful one. thanks Jesse Newland + Adjusts regex to fix issues with S3 paths that include periods. thanks John Feminella + fix response-cache-control type for AWS signed urls. thanks John Nishinaga + remove FOG_PROVIDER env override. thanks Josh Lane + more robust resource pool discovery. thanks Justin Clayton + Removed duplicate property :ips on server. thanks Kevin Chan + Fixes invalid call to #resize, should be #resize_machine. thanks Kevin Chan + Fixed #875: Loosen multi_json version. thanks Kevin Menard + Bad string replace. thanks Kevin Menard + Actually call the new MultiJSON 1.3.2 API methods. thanks Kevin Menard + Rename dd_belatedpng.js to dd_belatedpng.min.js. thanks Laurent Bigonville + Add non-minified javascript files used in docs/ (#939). thanks Laurent Bigonville + Catch Errno::ETIMEDOUT timeout error when connecting to a freshly created EC2 machine. thanks Marc Seeger + fix get, all, and all!. thanks Michael Keirnan + Make `.irbrc` service agnostic. thanks Nelvin Driz + Nested Credentials with Array gets flattened; restrict flatten to 1L. thanks Nelvin Driz + Allow for stringified options keys. thanks Nikita Pomyashchiy + add supports for defining/extracting libvit boot order. thanks Ohad Levy + libvirt volume sizes are in GB, ensuring both requests and setters are in GB. thanks Ohad Levy + adds deprecation on vnc_port. thanks Ohad Levy + monitoring-state is enabled or disabled, if enabled returns true. thanks Ozgur Akan + reserved instances hourly cost was returning empty. thanks Ozgur Akan + Modify url regexp to handle periods in bucket names. thanks Parker Selbert + Tag generated model tests with string not symbol. thanks Paul Thornthwaite + added missing server attributes for openstack compute model. thanks Pedro Perez + openstack: extended list_servers and list_server_detail to allow all_tenants param. thanks Pedro Perez + depend on excon >= 0.13.0. thanks Prashant Nadarajan + use pessimistic gem version constraint for excon (~>0.14.0). thanks Prashant Nadarajan + aim users model and nested model policy. thanks Rodrigo Estebanez + IAM access_key model implemented. thanks Rodrigo Estebanez + get_user Mock implemented. Basic shindo user_tests added. thanks Rodrigo Estebanez + Refactor aim modeling for nested models (policies and access keys). thanks Rodrigo Estebanez + shindo tests for IAM models: users, policies and access_keys. Mock implementation for get_user_policy. thanks Rodrigo Estebanez + @users -> @user. Clean up the @user after the policies and access_keys test. thanks Rodrigo Estebanez + Fix encoding issue: https://github.com/fog/fog/pull/189. thanks Rodrigo Estebanez + aim users model and nested model policy. thanks Rodrigo Estebanez + IAM access_key model implemented. thanks Rodrigo Estebanez + get_user Mock implemented. Basic shindo user_tests added. thanks Rodrigo Estebanez + Refactor aim modeling for nested models (policies and access keys). thanks Rodrigo Estebanez + shindo tests for IAM models: users, policies and access_keys. Mock implementation for get_user_policy. thanks Rodrigo Estebanez + @users -> @user. Clean up the @user after the policies and access_keys test. thanks Rodrigo Estebanez + Fix encoding issue: https://github.com/fog/fog/pull/189. thanks Rodrigo Estebanez + For some reason, there was a missing comma in the mock class. thanks Rodrigo Estebanez + Fix get_user_policy. The actual AWS data has to be in a ['Policy'] hash section. thanks Rodrigo Estebanez + add IAM mocking for get_group method. thanks Rodrigo Estebanez + add IAM mocking for get_group method. thanks Rodrigo Estebanez + Add new HP providers for Object Storage, Compute and CDN services. thanks Rupak Ganguly + Be sure to reload when checking for a started spot instance, also add private/public key options into spot_requests, then set those on the server when loaded. thanks Ryan Stout + Use spot request's public_key when setting up keypair. thanks Ryan Stout + ensure apiKey and command are included in parameter sorting. thanks Sean Caffery + * [xenserver|compute] initial release. thanks Sergio Rubio + * Added VIF model and collection tests * added network and server wrappers to VIF model. thanks Sergio Rubio + * Added VIF collection Shindo tests. thanks Sergio Rubio + * Added PIFs collection Shindo tests. thanks Sergio Rubio + * Added VBD Shindo tests * added server wrapper to VBD model. thanks Sergio Rubio + * Added Network collection Shindo tests * Fixed PBD and PIF tests descriptions. thanks Sergio Rubio + * Added Pool and StorageRepository models and collections Shindo tests * Added missing attributes to Pool and StorageRepository models. thanks Sergio Rubio + * Define missing InvalidLogin exception * Add login tests. thanks Sergio Rubio + * Added custom_templates and templates methods to Host model. thanks Sergio Rubio + * Added more tests and extended existing ones * Added missing exceptions NotFound and RequestFailed * connection.request now raises exception if request failed * refactored most get_* request into get_record and get_records * Compute.default_template more robust * Base parser now replaces OpaqueRef:NULL with nil * create_server request fixes. thanks Sergio Rubio + * Added some more tests * Lots of fixes and some refactoring. thanks Sergio Rubio + * Fix Servers.templates method. thanks Sergio Rubio + * Added clone_server request. thanks Sergio Rubio + * Added create_vif tests * Server.save now properly creates additional VIFs when required * Added create_vif_custome request to create VIFs with custom params. thanks Sergio Rubio + * Added Vif.destroy and destroy_vif request * add :auto_start parameter to Server.save. thanks Sergio Rubio + * Added create_vdi request * Added missing VDI methods and attributes. thanks Sergio Rubio + * Added missing VBD operations. thanks Sergio Rubio + * Added set_attribute request and tests * Added missing PV_bootloaer attribute to Server * Added Server.set_attribute method and tests. thanks Sergio Rubio + * Added create_vbd and provision_server requests * Do not provision server when :auto_start is false * Add Server.provisio method * Add VBD.save method. thanks Sergio Rubio + * renamed some tests * Added missing VDI attributes and methods * added create/destroy request tests * Added valid_ref? test helper * Fixes in get_record_tests. thanks Sergio Rubio + * Added missing attributes to Server model * Added create_server_raw request and tests * Added VIF.save action * more tests. thanks Sergio Rubio + * Fix: do not try to retrive guest_metrics when guest_metrics ref is nil * ruby 1.8.7 compatibility fixes * Sane defaults for create_server_raw request. thanks Sergio Rubio + * Added new scan_sr request * Added StorageRepository.scan method * set_attribute request is now generic and can be used by any model * Added VDI.set_attribute method. thanks Sergio Rubio + * [xenserver|compute] set_attribute request now accepts var args - added new tests. thanks Sergio Rubio + updating gitignore for eclipse settings. thanks Spencer Dillard + first pass at updates for VPC. thanks Spencer Dillard + updating for SSL ciphers and protocols. thanks Spencer Dillard + updating to master. thanks Spencer Dillard + regularize examples showing use of AWS access keys. thanks Stephen Bannasch + Use MultiJSON #dump and #load rather than #encode and #decode. thanks Steve Smith + Add support for ports in AWS storage URLs. thanks Tim Carey-Smith + Mock implementations for SCP upload and download. thanks Tom Mornini + add Linode Mock classes to request primitives. thanks Wes Morgan + make Mock#linode_disk_delete return the response object. thanks Wes Morgan + make Mock#linode_disk_list return the response object. thanks Wes Morgan + use kernel_id for mocked kernel, not stackscript_id. thanks Wes Morgan + Adds new method delete_notification_configuration which allows you notifications created by put_notification_configuration. thanks Zuhaib Siddique + Fix for stacks that have capabilities. Without this the parser misinterprets stacks with capabilities set. thanks atlantacs + volume(s) are not considered to be universally available. thanks geemus + catch passing an invalid openstack_tenant. thanks mattray + addresses['internet'] (like on TryStack.org) supported and public and private_ip_address now work. thanks mattray + don't assume 'internet' for addresses. thanks mattray + Added offering type for reserved instances response. thanks questionnet + +[oVirt] + added volumes to server and template. thanks Amos Benari + added volume size in GB accessor. thanks Amos Benari + fixed create_vm and get_virtual_machine requests mock implementation. thanks Amos Benari + +[openstack] + Fix create snapshot. thanks Ferran Rodenas + Match both OS API 1.1 and v2 since they are the same. thanks Josh Kearney + Update Reinitialization Process of Existing Auth Token. thanks Nelvin Driz + Add Export of Credentials. thanks Nelvin Driz + Wrong instance variables accessed for #credentials. thanks Nelvin Driz + Update Authentication through X-Auth-Token. thanks Nelvin Driz + Update mocks for login and identity request #get_user_by_id. thanks Nelvin Driz + Fix authentication without specifying tenant name. thanks Nelvin Driz + Make current_user and current_token accessible to services. thanks Nelvin Driz + Fix Authentication as well as Fog::JSON call bugs. thanks Nelvin Driz + Raise error when no tenant is found for the user logging in. thanks Nelvin Driz + Ensure password sent is of type string. thanks Nelvin Driz + Modify authentication process. thanks Philip Mark Deazeta + +[openstack|compute] + Add requests and tests for security groups. thanks Alfonso Juan Dillera + Add requests, models and tests for keypairs. thanks Alfonso Juan Dillera + Add requests, models and tests for address management. thanks Alfonso Juan Dillera + Add requests, models and tests for address management. thanks Alfonso Juan Dillera + Add flavor CRUD. thanks Alfonso Juan Dillera + Add auth_token. thanks Alfonso Juan Dillera + Added request for boot_from_snapshot. thanks Alfonso Juan Dillera + Added id attribute to the keypair. thanks Alfonso Juan Dillera + Update fetching of addresses and added fetching for address pools. thanks Alvin Garcia + Fixed creating image of a server. thanks Alvin Garcia + Added requests for quota. thanks Alvin Garcia + Initial extension support for addresses. thanks Hunter Nield + Initial extension support for key pairs. thanks Hunter Nield + Initial extension support for security groups. thanks Hunter Nield + Added Address models. thanks Hunter Nield + Added key pair models. thanks Hunter Nield + added security group models. thanks Hunter Nield + Updates to server model. thanks Hunter Nield + Added list/get support for /os-hosts. thanks Hunter Nield + Add Tenants and Fix Authentication Implementation. thanks Nelvin Driz + Fix Requests on Compute. thanks Nelvin Driz + General Cleanup and Update. thanks Nelvin Driz + Fix Compute Identity Endpoint Credential Export. thanks Nelvin Driz + Add Identity Enpoint to Recognized Init Parameters. thanks Nelvin Driz + Update requests and response of server actions. thanks Nelvin Driz + Fix Bug on Key Pair Mock. thanks Nelvin Driz + Update Mocks for Volumes. thanks Nelvin Driz + Update Mocks for Security Groups and Volumes. thanks Nelvin Driz + Add Instance Name to Fog. thanks Nelvin Driz + Update Image Mocks. thanks Nelvin Driz + Update List Security Groups to list those assigned to a server. thanks Nelvin Driz + Assert Timezone to UTC and fix format for OS on `get_usage`. thanks Nelvin Driz + Added get_usage function, mocks, tests. thanks Philip Mark Deazeta + Added get server volumes request. thanks Philip Mark M. Deazeta + Added key_pair and security_groups options int create server requrest. thanks Philip Mark M. Deazeta + added key_name and security_groups in boot from snapshot request. thanks Philip Mark M. Deazeta + authenticate_v2 fixes. thanks Sergio Rubio + +[openstack|identity] + Added current user id. thanks Alfonso Juan Dillera + Updated current user id for identity. thanks Alfonso Juan Dillera + Keystone Roles. thanks Alvin Garcia + Keystone Roles and Users. thanks Alvin Garcia + Update users collections and model. thanks Alvin Garcia + Update users model initialization and save. thanks Alvin Garcia + Fixed users fetching. thanks Alvin Garcia + Rough implementation of the Keystone API (untested). thanks Hunter Nield + Correction in Roles#all method. thanks Mark Maglana + Express the "add user role" intent more clearly. thanks Mark Maglana + Fix Authentication Implementation. thanks Nelvin Driz + Update Tenants. thanks Nelvin Driz + Update Tenants (Complete CRUD). thanks Nelvin Driz + Fix Identity Authentication Conditions on Endpoint Detection. thanks Nelvin Driz + Add User List and Delete User Mocks. thanks Nelvin Driz + Update Fog to Accomodate Tenant Deletion Workaround Workflow. thanks Nelvin Driz + Fix status code expectation. thanks Nelvin Driz + Added function to add user to a tenant. thanks Philip Mark Deazeta + Added function to add user to a tenant. thanks Philip Mark Deazeta + fixes for mocks. thanks geemus + +[openstack|image] + Added set_tenant. thanks Alvin Garcia + Added copy_from attribute. thanks Alvin Garcia + Update Image Service Authentication Options. thanks Nelvin Driz + Added image service, model and request. thanks Philip Mark Deazeta + Added test for models and request. thanks Philip Mark Deazeta + Added image module, model and request. thanks Philip Mark Deazeta + Image Model Updates. thanks Philip Mark Deazeta + Refactor Dynamic Methods on Image Model. thanks Philip Mark Deazeta + +[openstack|volume] + Volume Endpoints Support. thanks Marjun Pagalan + Volume Snapshot CRUD. thanks Marjun Pagalan + Volume attach/detach to Server. thanks Marjun Pagalan + Added volume service requests. thanks Philip Mark M. Deazeta + fix on module name. thanks Philip Mark M. Deazeta + Added volume model. thanks Philip Mark M. Deazeta + +[ovirt] + fixed list storage domain test. thanks Amos Benari + +[rackspace|compute] + fix rackspace server compare. thanks Josh Lane & Jason Hansen + default images. thanks Josh Lane & Jason Hansen + Images#all returns data. thanks Josh Lane & Jason Hansen + fixes for mock images. thanks geemus + +[rackspace|lb] + added support for algorithm on create. thanks Brian Hartsock + fixed broken tests due to API contract changes. thanks Brian Hartsock + +[rackspace|loadbalancers] + fixed broken tests. thanks Brian Hartsock + +[rackspace|storage|file] + copy method now use the options hash and apply content type. thanks Matthias Gröbner + +[rackspace|storage|files] + fix iteration. thanks Matthias Gröbner + +[slicehost] + remove (now deprecated) slicehost support. thanks geemus + +[storage|aws] + fix location stuff to allow creating new buckets properly. thanks geemus + +[vcloud] + Remove some un-needed debug information. thanks Lincoln Stoll + +[vpc-fixes] + AWS security group model + VPC. thanks Sean Porter + +[vsphere] + force poweroff of instance of vmware tools are not installed. thanks Ohad Levy + adds memory and cpu server attributes. thanks Ohad Levy + adds support to get and set vnc console. thanks Ohad Levy + +[xenserver] + Added missing Server.tags attribute. thanks Sergio Rubio + fix tags to skip tests without credentials. thanks geemus + + +1.3.1 03/27/2012 f0f692456956fe2e414ef8205d0268259901644a +========================================================= + +Stats! { 'collaborators' => 32, 'downloads' => 527366, 'forks' => 392, 'open_issues' => 27, 'watchers' => 1901 } + +MVP! George Scott + +[aws|dns] + Preserves change_id. Support for checking sync status via reload. thanks George Scott + Changed #insync? to #ready?. thanks George Scott + +[ibm] + avoid using constants (Rails loads files multiple times, issue #807). thanks Decklin Foster + Make usage of #state rather than #status consistent. thanks Decklin Foster + +[ibm|compute] + Add clone/destroy methods and tests to Image. thanks Decklin Foster + Add request test for list_vlans and fix mock. thanks Decklin Foster + +[ibm|storage] + Restore storage_area, platform_version, clone_status Volume attributes. thanks Decklin Foster + +[misc] + Allow custom headers in Storage#put_object_url. thanks Jacob Mattingley + Use https_url instead of deprecated url for put_object_url. thanks Jacob Mattingley + Adding Vlan class to IBM SmartCloud. thanks Joe Kinsella + bump excon dep to get jruby openssl fixes. thanks geemus + +[storage] + properly update content-type at save time for file models. thanks geemus + + +1.3.0 03/21/2012 f78afe98242a60ae4dbbfcd8c5ab67ba71c6d773 +========================================================= + +Stats! { 'collaborators' => 32, 'downloads' => 513974, 'forks' => 387, 'open_issues' => 24, 'watchers' => 1893 } + +MVP! Decklin Foster + +[aws|cloud_watch] + GitHub Edit! s/prodide/provide/ :v:. thanks Dylan Egan + +[aws|simpledb] + fix region/host for us-east-1. thanks geemus + +[ibm] + Added Mocking and Tests. thanks Carl Hicks + Moar convenience methods for servers. thanks Carl Hicks + Update model for Volume. thanks Carl Hicks + Added request tests for addresses. thanks Carl Hicks + Initial IBM SmartCloud support. thanks Decklin Foster + Add Location model and requests. thanks Decklin Foster + Rename collection requests get->list so we have get_foo and list_foos. thanks Decklin Foster + Don't need json_body, so we can simplify requests; remove unused params. thanks Decklin Foster + Pass optional params to requests with hashes. thanks Decklin Foster + Add a InstanceType model, returned as part of Images. thanks Decklin Foster + Rename model test files into compute, storage dirs. thanks Decklin Foster + Remove trailing whitespace. thanks Decklin Foster + Update tests to match model arguments (attribs hash) and lower-level request methods. thanks Decklin Foster + Update mocks to reflect moving volume models from from compute to storage. thanks Decklin Foster + Add some missing mocks, fix list_instances. thanks Decklin Foster + Raise NotFound in mock instead of returning a 404. thanks Decklin Foster + Fix form_encode to stringify args (e.g. booleans) to URI.escape. thanks Decklin Foster + Typos in state names and status vs. state. thanks Decklin Foster + Fix key model for passing public_key, add setting/testing whether key is default. thanks Decklin Foster + Setting default key returns success, not key name. thanks Decklin Foster + Typo, assignment instead of equality, made some tests incorrectly pass. thanks Decklin Foster + Flesh out modify_instance and modify_key for different modes. thanks Decklin Foster + Restarting should return success, changing expiration should only return time. thanks Decklin Foster + Delete instance mock should return success. thanks Decklin Foster + Remove IBM from flavors tests. thanks Decklin Foster + Make names used in tests unique using current time. thanks Decklin Foster + Add vlan_id attrib so that it can be used in creating an instance. thanks Decklin Foster + Return nil for public_hostname if primary_ip unset (e.g. state is Failed). thanks Decklin Foster + Change default location and image ID. thanks Decklin Foster + Rename ibm_user_id -> ibm_username. thanks Decklin Foster + Create temporary keys in tests that need to create instances. thanks Decklin Foster + servers are not sorted, don't assume we can just take the last. thanks Decklin Foster + create_image should do a PUT, not a POST, and needs 'state' param. thanks Decklin Foster + Correct spelling of test volume format ('RAW') and fix parameter typo. thanks Decklin Foster + Rename data -> body. thanks Decklin Foster + Don't reboot or immediately expire, interferes with other tests. thanks Decklin Foster + Use Raleigh location for tests. thanks Decklin Foster + Nullable formats for attributes that may not be returned. thanks Decklin Foster + Set expire a few seconds in the future since it takes a while to process. thanks Decklin Foster + Return nil if instance_id is nil. thanks Decklin Foster + Can't access Fog::Compute::IBM::Location class from here, just check if ID returned. thanks Decklin Foster + servers.length will include already existing servers. thanks Decklin Foster + Add state and ready? method to Image. thanks Decklin Foster + Change public key format. thanks Decklin Foster + vlan is part of primaryIP. thanks Decklin Foster + Rename root_only -> is_mini_ephemeral. thanks Decklin Foster + Description is mandatory. thanks Decklin Foster + Wait for instance to be ready before deleting it or creating image. thanks Decklin Foster + Add state/ready? methods for Address. thanks Decklin Foster + Expiration time should be epoch in ms. thanks Decklin Foster + launched_at convenience method. thanks Decklin Foster + Don't set server to nil. thanks Decklin Foster + Set a longer timeout on all wait_for calls. thanks Decklin Foster + Generated key needs different name, supplied key only returns success. thanks Decklin Foster + Invalid instance creation will return a 412 and thus raise PreconditionFailed. thanks Decklin Foster + Don't calculate expiration time until ready to make the request. thanks Decklin Foster + Fix volume formats and mocks. thanks Decklin Foster + Wait for volume to be ready before deleting. thanks Decklin Foster + Mark volume attach/detach pending, won't create instance. thanks Decklin Foster + Return pending if provisioning times out in the real tests. thanks Decklin Foster + adding documentation. thanks Wyatt Walter + add bin helpers for storage. thanks geemus + +[misc] + ovirt added support for 'set vm ticket'. This api call is needed for openning a console to the server. thanks Amos Benari + wrangled security tests into working. thanks Eric Stonfer + Changes to the security group handling: * CreateSecurityGroup now includes the group id in the reply, this patch makes the code store this * The patch also changes the delete call to use the group id if present (since you must use the id when deleting VPC groups). thanks MaF + Changes to the security group handling: * CreateSecurityGroup now includes the group id in the reply, this patch makes the code store this * The patch also changes the delete call to use the group id if present (since you must use the id when deleting VPC groups) * Fix teh security group mock and test code to handle this new behavior. thanks MaF + Removed merge commit. thanks MaF + +[release] + add Kevin Menard to future MVP exclusion list. thanks geemus + +[storage|aws] + fix hardcoded host in get_object_http(s)_url methods. thanks geemus + + +1.2.0 03/19/2012 70e0f48fa446dbf233ae31c4f055eb26ea2dadd1 +========================================================= + +Stats! { 'collaborators' => 30, 'downloads' => 508132, 'forks' => 384, 'open_issues' => 23, 'watchers' => 1874 } + +MVP! Kevin Menard + +[AWS] + Compute: The security group parser was not parsing groupid properly. thanks Christopher Oliver + +[AWS|DynamoDB] + table requests. thanks geemus + cleanup/fixes for tables. thanks geemus + item requests. thanks geemus + update item should not be idempotent when an action is specified. thanks geemus + fix for UpdateItem idempotency. thanks geemus + first pass at query/scan requests. thanks geemus + ConsumedCapacityUnits should be a Float. thanks geemus + add missing pending for mocked tests. thanks geemus + +[AWS|ELB] + Added support for InstanceProtocol to listeners. thanks James Stremick + Updating listener and LB tests to include InstancePort checks. thanks James Stremick + +[AWS|Storage] + versioning related fixes copy_object mocks. thanks geemus + fix for put_bucket_website mock. thanks geemus + remove redundant mock setup in tests #731. thanks geemus + +[AWS|storage] + fix for versioned copy_object. thanks geemus + +[Brightbox] + Updates to format tests. thanks Paul Thornthwaite + Updated Server output format. thanks Paul Thornthwaite + Updated format test to use correct link name. thanks Paul Thornthwaite + Updated Image format for min_ram attribute. thanks Paul Thornthwaite + Updated LoadBalancer format to include listeners in listing. thanks Paul Thornthwaite + Updated format for nested firewall policies. thanks Paul Thornthwaite + Merge in various spec corrections. thanks Paul Thornthwaite + Update format test to not fail on new attributes in JSON. thanks Paul Thornthwaite + Load balancer listener timeouts are now reported. thanks Paul Thornthwaite + Correct server snapshot test. thanks Paul Thornthwaite + +[Compute|OpenStack] + match auth response to stable/diablo branch of keystone. thanks Todd Willey + +[Rackspace|Storage] + set put_object to idempotent. thanks geemus + +[aws] + add sts helper. thanks geemus + +[aws|compute] + Fixed failing instance tests. thanks Christopher Oliver + Update API version and support new DescribeInstanceStatus format. thanks Dan Peterson + Fix allocate_address mocking. thanks Dan Peterson + Mock detach_volume should raise proper error if volume is not attached. thanks Dan Peterson + added group id to security group parser and model. thanks bdorry + added security group get by id method. thanks bdorry + +[aws|dns] + Record identity is 'Name'. thanks Aaron Suggs + Add Record#modify method. thanks Aaron Suggs + Add model tests. thanks Aaron Suggs + add test for Record#modify. thanks Aaron Suggs + Parse IsTruncated as boolean in list_resource_record_set. thanks Aaron Suggs + Add support for aliasing records to Elastic Load Balancers (API 2011-05-05). thanks James Miller + +[aws|elb] + start working on policies. :v:. thanks Dylan Egan + create policies, describe policies, fix old mocking and yup. :v:. thanks Dylan Egan + PolicyNotFound. :v:. thanks Dylan Egan + remove test debugging. :v:. thanks Dylan Egan + actually raise a PolicyNotFound. :v:. thanks Dylan Egan + InstanceProtocol support. :v:. thanks Dylan Egan + +[aws|fog] + crapiness and hacks. :v:. thanks Dylan Egan + +[aws|iam] + Mock upload_server_certificate errors if private key is not RSA. thanks Dan Peterson + P. :v:. thanks Dylan Egan + +[aws|rds] + Mock DB snapshot requests. thanks Aaron Suggs + Enabled model tests that pass when mocking. thanks Aaron Suggs + +[aws|storage] + Simple multipart uploads; supports files > 5GB. thanks Aaron Suggs + Automatically abort multipart uploads on exceptions. thanks Aaron Suggs + Add mock for Fog::Storage::AWS#put_bucket_website. thanks Garret Alfert + Handle S3 object deletions in the face of versioning. thanks Kevin Menard + Return the object version in the request header and set an attribute value in the model. thanks Kevin Menard + Allow options to be passed to the destroy method, facilitating passing of versionId. thanks Kevin Menard + Added ability to control bucket versioning from Directory model. thanks Kevin Menard + Added the ability to fetch a list of versions from a file. thanks Kevin Menard + Allow passing of options to fetching versions. thanks Kevin Menard + Added the pagination offset params to the get_object_bucket_versions parser. thanks Kevin Menard + Added the MfaDelete value to the get_bucket_versioning parser. thanks Kevin Menard + Fix put bucket website test, request returns not found when the bucket does not exist. thanks Peter Weldon + Add bucket lifecycle / object expiration requests. thanks Peter Weldon + make head_object idempotent. thanks geemus + direct https urls to subdomains even with dots this may result in ssl warnings, but that seems better than the alternative (redirects) see #611. thanks geemus + +[aws|storage|test] + use a random directory key; prevent collision. thanks Aaron Suggs + Mark multipart upload test as pending. thanks Aaron Suggs + Added mock support for setting and retrieving versioning on a bucket. thanks Kevin Menard + Added in versioning support for S3 objects, sans deletion markers. thanks Kevin Menard + Track if the version is the latest or not. thanks Kevin Menard + Basic handling of version-id-marker. thanks Kevin Menard + Added the ability to get_object by versionId. thanks Kevin Menard + Added S3 versioning support for delete_object. thanks Kevin Menard + Deal with suspended buckets properly. thanks Kevin Menard + Added request tests for put_bucket_versioning and get_bucket_versioning. thanks Kevin Menard + Added tests for get_bucket_object_versions. thanks Kevin Menard + Added request test for get_object with versioning. thanks Kevin Menard + Added request tests for delete_object with versioning. thanks Kevin Menard + Added failing request test for delete_object with versioning. thanks Kevin Menard + Added in some file and directory model tests. thanks Kevin Menard + Added model tests for versioning Directory and File models. thanks Kevin Menard + Added tests for the Version model. thanks Kevin Menard + Added versioning test for Files collection. thanks Kevin Menard + Added versioning tests for Versions collection. thanks Kevin Menard + Added versioning test for Files#head. thanks Kevin Menard + Removed a commented-out test. thanks Kevin Menard + Make sure tests pass with both mocking enabled and disabled. thanks Kevin Menard + Fixed a regression with mocked get_bucket requests, due to a change in the mock data ordering. thanks Kevin Menard + Fixed handling of options in mocked get_bucket_object_versions. thanks Kevin Menard + Replaced random ETag implementation with MD5, per S3 docs. thanks Kevin Menard + +[aws|sts] + make get_*_token requests idempotent. thanks geemus + +[beanstalk] + avoid one remaining error with mocked tests. thanks geemus + +[cloudstack] + Fix warning in ruby 1.8.7. thanks Aaron Suggs + added additional networking support and volume management commands. thanks Brian Dorry + added unit tests. thanks Brian Dorry + skip ssl verification. thanks geemus + +[cloudstack|compute] + merged in upstream. thanks bdorry + added ssh key support, snapshot policy support. thanks bdorry + added update resource count action. thanks bdorry + +[compute|aws] + fix for describe_images parser that accidently split records. thanks geemus + fix error in describe_security_groups parser closes #678. thanks geemus + +[compute|cloudstack] + added basic cloudstack list support. thanks bdorry + added user management support. thanks bdorry + added domain management support. thanks bdorry + added domain management support, added documentation links to existing cloudstack requests. thanks bdorry + +[core] + no need to expand the already exanded __LIB_DIR__. thanks geemus + update connection to use new excon response_block format. thanks geemus + +[docs] + Update GitHub repository references from geemus/fog to fog/fog. thanks Benjamin Manns + +[dynect|dns] + Pass zone.records.all options through to get_node_list. thanks Dan Peterson + +[glesys|compute] + fix for changes in api. thanks Anton Lindström + +[joyent|compute] + rename _test files to _tests for shindo. thanks geemus + make password required. thanks geemus + fix format of joyent to match real output and remove mock-only test. thanks geemus + +[local|storage] + Fix Local::File deletion for Ruby 1.8. thanks Benjamin Manns + Add copy_object method to Local::Storage. thanks Benjamin Manns + Add copy method to Local::File. thanks Benjamin Manns + +[misc] + whitespace. thanks Aaron Suggs + fix typo in comment. thanks Aaron Suggs + whitespace cleanup. thanks Aaron Suggs + Refactor to support ruby 1.8.7. thanks Aaron Suggs + Whoops, don't need to require digest/md5. thanks Aaron Suggs + whitespace. thanks Aaron Suggs + Adds Supprt for oVirt (http://ovirt.org). thanks Amos Benari + oVirt: Added tests to work on both real and mock. thanks Amos Benari + Removing duplicates from reservation's groupSet. thanks Artem + Remove coverage Rake task. thanks Benjamin Manns + Remove a step that referenced a private config file. thanks Bob Briski + updated cloudstack tests for user level permissions, added ssh key, disk offering, service offering, os type, security group tests. thanks Brian Dorry + Adding update_firewall_rule request. thanks Caius Durling + Correct an error with long keys where Base64.encode64 would add "\n" at 60 chars. thanks Chris Hasenpflug + Use gsub for Ruby 1.8.7 compatibility. thanks Chris Hasenpflug + Correct copy & paste error. thanks Chris Hasenpflug + implement #scp_download method to allow downloads in addition to uploads via scp. alias #scp method as #scp_upload. thanks Christoph Schiessl + tests for scp_download. thanks Christoph Schiessl + Removed various 'puts' statements... thanks Christopher Oliver + fix for free choice of region. thanks Daniel Schweighoefer + save the region in a instance variable. thanks Daniel Schweighoefer + rounding out API coverage in 'Virtual Machine section. thanks David Nalley + mock #create_user and #create_access_keys". thanks Edward Muller + fix typo. thanks Edward Muller + Enable Shindo tests for the mocked methods. thanks Edward Muller + Refactor mock data structure. thanks Edward Muller + mock #put_user_policy. thanks Edward Muller + Mock out #list_users. thanks Edward Muller + Mock #delete_user_policy. thanks Edward Muller + Move this is Mock.key_id and don't default the path. thanks Edward Muller + Add group mock data. thanks Edward Muller + Use #has_key? instead of #keys.include?. thanks Edward Muller + rework these to use #tap instead. Cleaner IMNSHO. thanks Edward Muller + Additional mocks. thanks Edward Muller + missing raise. thanks Edward Muller + DescribeVolumeStatus. thanks Edward Muller + Add code to support the creation and modification of security groups existing in a VPC. thanks Eric Stonfer + modified security group tests to accomodate the new security group data model. Also allowed permissions to be nil in the security tests for groups with no ACLs. thanks Eric Stonfer + Change default for vpc_id from '' to nil. thanks Eric Stonfer + fixed a conditional that was assigining = rather than evaluating == in vsphere clone routine. This resulted in cloning from folders always failing. thanks Eric Stonfer + Add the ability to create linked clones in vsphere. thanks Eric Stonfer + whitespace fix. thanks Eric Stonfer + whitespace fix. thanks Eric Stonfer + add a linked clone test scenario, set the vm_clone test to wait, and clean up old servers after the VM clone test. thanks Eric Stonfer + linked clone tests. thanks Eric Stonfer + This patch allows the ability to create 'blank' vms in vsphere. thanks Eric Stonfer + fix list_virtual_machines when using :folder. thanks Eric Stonfer + add vm reconfiguration functions for memory cpu / generic spec. thanks Eric Stonfer + add subnet and vpc info to instance gets. thanks Eric Stonfer + fixed a typo in vm_power_on_tests.rb. thanks Eric Stonfer + make eips useable in a VPC. thanks Eric Stonfer + associate EIPs in a vpc. thanks Eric Stonfer + update autoscaling groups to allow the use of recurrence, start and end times. thanks Eric Stonfer + realized that @activity was actually not used. thanks Eric Stonfer + fixed some whitespace issues in auto_scaling tests. Fixed auto_scaling tests formats. thanks Eric Stonfer + add host based vmotion. thanks Eric Stonfer + basic VPC creation. thanks Eric Stonfer + [aws]Add in subnets. thanks Eric Stonfer + enable_metrics_collection requires a granularity argument (1Minute is the only legal value). thanks Frederick Cheung + New file additions for AWS Elastic Beanstalk support. thanks George Scott + Added beanstalk service to AWS Provider. thanks George Scott + Unit tests for beanstalk. thanks George Scott + Now sets pending when mocking for all beanstalk model tests. thanks George Scott + environment now uses name as identity. thanks George Scott + Added additional convenience methods to application. thanks George Scott + remove rubygems require from core.rb. thanks Hemant Kumar + Reset the alias_target hash for good measure. thanks James Miller + Add a test for ALIAS records. thanks James Miller + Cleanups and crazy long sleep to ensure ALIAS zone is found. thanks James Miller + Fix linked clone mocked test unhandled exception. thanks Jeff McCune + (maint) Whitespace and format only clean up. thanks Jeff McCune + added support for server-side encryption on s3. thanks John Parker + Switch from NewServers to BareMetalCloud for #773. thanks John Wang + Add deprecation warning. thanks John Wang + Fixed bug in SQS :receive_message mock. thanks Joshua Krall + Fixed a typo in the warning. thanks Kashif Rasul + One more typo fix. thanks Kashif Rasul + GH-690 Joyent Cloud Provider. thanks Kevin Chan + Credentials: cloudapi_* -> joyent_* for consistency. thanks Kevin Chan + Revert "[joyent|compute] make password required" This reverts commit 6e93321e29e69cc863aa9d78cdcf1c83203a2fa7. thanks Kevin Chan + Fixes dataset tests. thanks Kevin Chan + - Fixes tests to run in both mock and non-mock mode - Clean ups and fixes. thanks Kevin Chan + Cleanups + Fixes #get_machine test breaking when there are no machines. thanks Kevin Chan + cleanups + refactorings + better error reporting per joyent cloudapi spec. thanks Kevin Chan + Fixed #673: Zerigo DNS - update_host fails with some options. thanks Kevin Menard + Fixed a filename. thanks Kevin Menard + implement respond_to? corresponding to method_missing for VirtualBox and libvirt. thanks Konstantin Haase + Swap aws_access_key_id and aws_secret_access_key positions in hash to match typical usage convention. thanks Kyle Drake + When Exists boolean is not specified, this request is not idempotent. thanks Lance Carlson + Scan sort of acts like a GET request, which are idempotent. thanks Lance Carlson + Only do a 'head' on the file that we've copied - no need to go download it now, that would defeat the purpose. thanks Lars Pind + Improved support for SecurityGroup IDs. thanks MaF + We must create the VPC before we can create a security group in it. thanks MaF + Changed verify_permission_options in mocked version of authorize_security_group_ingress to accept any ipProtocol for vpc groups. Also changed the security group test to use protocol 42 when testing vpc security_groups. thanks MaF + Check if exception has a #response method before calling it, otherwise call #message. thanks Manuel Meurer + Fix sync_clock method, only rescue Excon::Errors::HTTPStatusError that are known to have a #response method, let all other exceptions bubble up. thanks Manuel Meurer + Updated excon to version ~>0.10.0. Closes #781. thanks Marc Seeger + include fission gem. thanks Michael Brodhead & Shai Rosenfeld + Move fission from reg dependency to dev dependency per comments on pull request #736. thanks Michael Brodhead & Shai Rosenfeld + adding required gem to run the tests. thanks Ohad Levy + first cut of cleaning up libvirt server class. thanks Ohad Levy + minor cleanups. thanks Ohad Levy + fixes libvirt wrong state check. thanks Ohad Levy + libvirt - avoids exception if a uuid is not found. thanks Ohad Levy + libvirt: servers return nil, not an empty array... thanks Ohad Levy + Added basic tests to Ovirt compute provider. thanks Ohad Levy + Added check if Fog.mock! should be used in AWS tests. thanks Paul Thornthwaite + Nix hardcoded regions: DynamoDB. thanks Pavel Repin + Nix hardcoded regions: Autoscaling. thanks Pavel Repin + Nix hardcoded regions: CloudFormation. thanks Pavel Repin + Nix hardcoded regions: CloudWatch. thanks Pavel Repin + Nix hardcoded regions: EC2. thanks Pavel Repin + Nix hardcoded regions: ElastiCache. thanks Pavel Repin + Nix hardcoded regions: ELB. thanks Pavel Repin + Nix hardcoded regions: EMR. thanks Pavel Repin + Nix hardcoded regions: RDS. thanks Pavel Repin + Nix hardcoded regions: SES. thanks Pavel Repin + Nix hardcoded regions: SimpleDB. thanks Pavel Repin + Nix hardcoded regions: SNS. thanks Pavel Repin + Nix hardcoded regions: SQS (us-east-1 is special). thanks Pavel Repin + Nix hardcoded regions: S3 (us-east-1 is special). thanks Pavel Repin + Fixing typo "retreive" -> "retrieve". thanks Pedro Nascimento + Add the ":idempotent => true" property to create_tags to fix an issue when launching many instance from cluster_chef. thanks Peter C. Norton + Ran M-x align-regexp on the hashrockets. thanks Peter C. Norton + Passing half of rds/instance_tests.rb shindo tests. thanks Rodrigo Estebanez + making shindo tests for security groups in rds. thanks Rodrigo Estebanez + Better rds/security_group_test. Mocking rds security_groups. thanks Rodrigo Estebanez + Support for rds parameter groups mocking. thanks Rodrigo Estebanez + [aws][auto_scaling] Bug fixed: configurations.get(launch-configuration) always shows the first element. thanks Rodrigo Estebanez + it doesn't throw an error when the launch configuration doesnt exist. thanks Rodrigo Estebanez + [aws][auto_scaling]. Support delete_launch_configuration mocking. thanks Rodrigo Estebanez + Added PrivateIpAddress to the list of valid parameters for instance creation. thanks Rusty Geldmacher + Add Ecloud version 2.8 as supported. thanks Shai Rosenfeld + support alias records in the route53 models. thanks Thom May + Remove unused comment / commented code. thanks Todd Willey + Fix intial public_url when saving using rackspace_cdn_ssl = true. thanks Zachary Danger Campbell + added virtual machine support and security group support. thanks bdorry + merged in 0.11.0 release. thanks bdorry + merged 1.0.0. thanks bdorry + remove latest MVP from future possibilities. thanks geemus + examples should use providers.values. thanks geemus + fix Fog::Nullable::Boolean to include true/false. thanks geemus + update fog.io copyright year. thanks geemus + use path style access for https public_urls that include . to avoid certificate issues closes #743. thanks geemus + fix AWS get_object_http(s)_url methods to properly use subdomain vs path urls as appropriate closes #611. thanks geemus + loosen multi-json dependency closes #757. thanks geemus + remove examples as they are not that helpful or well supported. thanks geemus + bump excon dep closes #799. thanks geemus + bump excon dep. thanks geemus + strip ARNs - AWS is sensitive to leading and trailing whitespace/cr/lf. thanks hedgehog + allow for bundler+rbenv best practice. thanks hedgehog + Rackspace create_image request - pass all options. thanks kbockmanrs + Add Blue Box location support. thanks leehuffman + Update location UUID. thanks leehuffman + Add passing tests. thanks leehuffman + Fix location_id typo. thanks leehuffman + Add Blue Box location support. thanks leehuffman + Update location UUID. thanks leehuffman + Add passing tests. thanks leehuffman + Fix location_id typo. thanks leehuffman + +[ninefold|storage] + Add copy method to Ninefold::File. thanks Benjamin Manns + +[oVirt] + Fixed syntax error in ovirt parser. thanks Amos Benari + added option to block on start. Start action will block instead of fail. It can be useful in case of start after stop or create. thanks Amos Benari + added support for update vm on ovirt. thanks Amos Benari + Added VM and Template network-interfaces crud. thanks Amos Benari + +[ovirt|compute] + #instance_variables returns Symbols in 1.9.2+. thanks Dan Peterson + +[rackspace/compute] + Add 30GB (30720) compute size. thanks Phil Kates + +[rackspace|storage] + Add copy_object request. thanks Benjamin Manns + Add copy method to Rackspace::File. thanks Benjamin Manns + +[slicehost] + add deprecation warnings. thanks geemus + +[storage] + fixes for deprecated implicit block usage to excon requests. thanks geemus + update get_object requests to use excon response_blocks. thanks geemus + +[storage|test] + Run storage tests on a file in a subdirectory. thanks Benjamin Manns + +[storage|tests] + Add copy method to storage tests. thanks Benjamin Manns + Check that the copied file body matches the original file. thanks Benjamin Manns + +[vcloud] + mark mock tests pending. thanks geemus + +[vcloud|compute] + rather mock Fog::Vcloud::Connection as this is the right place to mock things. thanks Peter Meier + improve models + additional tests. thanks Peter Meier + add API version 1.5 compability. thanks Peter Meier + +[vmfusion|compute] + Sync fission v0.4.0 plus more. thanks Cody Herriges + +[voxel] + update ssl_verify_peer = false setting. thanks geemus + +[vsphere] + add to test skip list when lacking credentials. thanks geemus + +[zerigo|dns] + Fixed an issue with updating a record since the response body is an empty string, not nil. thanks Kevin Menard + Fixed the parser. TTL and priority values can be nil and should not be coerced into integers in that case. thanks Kevin Menard + + +1.1.2 12/18/2011 c1873e37e76af83e9de3f3308f3baa0664dd8dc2 +========================================================= + +Stats! { 'collaborators' => 20, 'downloads' => 351821, 'forks' => 332, 'open_issues' => 21, 'watchers' => 1731 } + +MVP! Stepan G. Fedorov + +[Brightbox] + Fix zone_id/flavour_id getter/setter for Server. thanks Hemant Kumar + Add zone/server_type attribute for Server. thanks Hemant Kumar + Add username to Image. thanks Hemant Kumar + Add request for remove_firewall_policy. thanks Hemant Kumar + Add model method for remove. thanks Hemant Kumar + Change logic of fetching zone and flavour_id. thanks Hemant Kumar + Remove name as mandatory parameter for creating server group. thanks Hemant Kumar + Add created_at attribute for server_group,policy and firewall rule. thanks Hemant Kumar + Updated Image format tests for username. thanks Paul Thornthwaite + Updated ServerGroup format for created_at time. thanks Paul Thornthwaite + +[aws|autoscaling] + allow sa-east-1 region in mocks. thanks Nick Osborn + +[aws|compute] + fix security_group format for mock tests. thanks geemus + +[aws|dns] + fix capitilization for records#all options. thanks geemus + +[aws|elb] + update SSL certificates on listeners. :christmas_tree:. thanks Dylan Egan + +[aws|storage] + Support ACL on copy_object. :v:. thanks Dylan Egan + +[brightbox] + Adding *_server actions to ServerGroup model. thanks Caius Durling + Pass along server_groups when creating a server. thanks Caius Durling + Make update_cloud_ip request work. thanks Caius Durling + Firewall models. thanks Paul Thornthwaite + Added missing requirement and request arg. thanks Paul Thornthwaite + Corrected deprecated argument. thanks Paul Thornthwaite + Dynamically select testing image. thanks Paul Thornthwaite + Helper to get a test server ready. thanks Paul Thornthwaite + Revised tests structure. thanks Paul Thornthwaite + Test and fix for API client secret reset. thanks Paul Thornthwaite + Test update of reverse DNS for CIP. thanks Paul Thornthwaite + Updated default Ubuntu image. thanks Paul Thornthwaite + Make Cloud IP model's map nicer to use. thanks Paul Thornthwaite + Correctly get Server's IP addresses as strings. thanks Paul Thornthwaite + ServerGroup association to Servers. thanks Paul Thornthwaite + Replace duplicate remove with move test. thanks Paul Thornthwaite + Load balancer request tests expanded. thanks Paul Thornthwaite + Request test for snapshotting a server. thanks Paul Thornthwaite + fix mock tests. thanks geemus + +[clodo] + : Added missing field. thanks NomadRain + Some cleanup before pool request. thanks NomadRain + add fake credentials for mock tests. thanks geemus + +[clodo|compute] + Bug fixes. thanks NomadRain + I don't know what is ignore_awful_caching, so i removed it. thanks Stepan G Fedorov + server.ssh with password. Not only with key. thanks Stepan G Fedorov + Fix Mocks. thanks Stepan G Fedorov + Enable get_image_details. thanks Stepan G Fedorov + Actualize Mocks. thanks Stepan G. Fedorov + Enable :get_image_details. thanks Stepan G. Fedorov + Add tests. thanks Stepan G. Fedorov + Remove ddosprotect field from Mock. thanks Stepan G. Fedorov + Add ip-address management. thanks Stepan G. Fedorov + Rename moveip to move_ip_address. thanks Stepan G. Fedorov + Enable ip-management. thanks Stepan G. Fedorov + Fix delete_server mock. thanks Stepan G. Fedorov + Fix move_ip_address behaviour. thanks Stepan G. Fedorov + Add ip-address management. thanks Stepan G. Fedorov + Rename moveip to move_ip_address. thanks Stepan G. Fedorov + Enable ip-management. thanks Stepan G. Fedorov + Fix delete_server mock. thanks Stepan G. Fedorov + Fix move_ip_address behaviour. thanks Stepan G. Fedorov + Added missing field (server.type). thanks Обоев Рулон ибн Хаттаб + +[core] + Cast Fog.wait_for interval to float. thanks Aaron Suggs + fix exceptions from nil credential value. thanks Blake Gentry + `@credential` should always be a symbol. thanks Hunter Haugen + +[docs] + note in title that multiple keys is an EC2 thing. thanks geemus + +[glesys|compute] + fixed tests due to changes in the api. thanks Anton Lindström + fix test formats and whitespaces. thanks Anton Lindström + +[misc] + parse SQS timestamps as milliseconds. thanks Andrew Bruce + Allow use of sa-east-1 in the ec2 mock as well. thanks Andy Delcambre + Enabled tests for setting S3 ACL by id and uri on buckets and objects when mocking. thanks Arvid Andersson + Added acl_to_hash helper method to Fog::Storage::AWS. thanks Arvid Andersson + Ensuring that get_object_acl and get_bucket_acl mock methods returns a hash representation of the ACL. thanks Arvid Andersson + Created Rackspace LB models folder. thanks Brian Hartsock + This patch adds the ability to specify security groups by security group id, rather than group name. This is a required feature to use security groups within a VPC. thanks Eric Stonfer + indentation change. thanks Eric Stonfer + Add the ability to return the security group ID when requesting a SecurityGroupData object. thanks Eric Stonfer + fix tests to accomodate the new SecurityGroupId. thanks Eric Stonfer + Revert "fix tests to accomodate the new SecurityGroupId". thanks Eric Stonfer + fix tests to accomodate the addition of security_group_id. thanks Eric Stonfer + indentation fix. thanks Eric Stonfer + indentation fix. thanks Eric Stonfer + [Brightbox]Add remove_firewall_policy to computer.rb. thanks Hemant Kumar + [Brightbox]Protocol is no longer required parameter for firewall. thanks Hemant Kumar + Add implementation of DescribeInstanceStatus. thanks JD Huntington & Jason Hansen + fixed type-o in rdoc on Fog::DNS:DNSMadeEasy. thanks John Dyer + add query options to Fog::Storage::AWS#get_object_https_url. thanks Mateusz Juraszek + add options hash to Fog::Storage::AWS::File#url and Fog::Storage::AWS::Files#get_https_url which use get_object_https_url method. thanks Mateusz Juraszek + add query param to get_object_http_url for consistency. thanks Mateusz Juraszek + Fix regression in Rakefile introduced in 70e7ea13. thanks Michael Brodhead + add são paulo/brasil region. thanks Raphael Costa + mock create_db_instance. thanks Rodrigo Estebanez + mocking describe_db_instance. Fix hash structure in create_db_instance. thanks Rodrigo Estebanez + mocking delete_db_instance. thanks Rodrigo Estebanez + mocking wait_for through describe_db_instances. thanks Rodrigo Estebanez + mocking modify_db_instance and reboot_db_instance. thanks Rodrigo Estebanez + raise exception instead of excon response. thanks Rodrigo Estebanez + Fixing bug: It always showed the first instance when using get. thanks Rodrigo Estebanez + Fixes for issues 616 and 617. thanks Sergio Rubio + * remove unnecessary debugging. thanks Sergio Rubio + * Add missing recognized :libvirt_ip_command. thanks Sergio Rubio + * Add server_name environment variable to ip_command. thanks Sergio Rubio + * implement :destroy_volumes in Server.destroy (libvirt provider). thanks Sergio Rubio + Add documentation for using multiple ssh keys on AWS. thanks Sven Pfleiderer + Update bootstrap description. thanks Sven Pfleiderer + Escape underscore charakters. thanks Sven Pfleiderer + implement STS support. thanks Thom May + Allow use of session tokens in AWS Compute. thanks Thom May + handle session tokens for SQS and SimpleDB. thanks Thom May + Split [AWS|STS] tests into separate files per #609. thanks Thom May + Bug fix, metric_statistic#save would always fail. thanks bmiller + bump excon dep. thanks geemus + bump excon dep. thanks geemus + Fixing Rackspace's lack of integer-as-string support as per https://github.com/fog/fog/pull/657#issuecomment-3145337. thanks jimworm + add current set of elasticache endpoints. thanks lostboy + added sa-east-1 region. thanks thattommyhall + Add clodo support. thanks Обоев Рулон ибн Хаттаб + Enable clodo support. thanks Обоев Рулон ибн Хаттаб + +[rackspace|dns] + error state callbacks now return an error. thanks Brian Hartsock + fixed broken test. thanks Brian Hartsock + should recognize rackspace_dns_endpoint argument. thanks geemus + record should pass priority. thanks geemus + mark tests for models pending in mocked mode. thanks geemus + +[rackspace|lb] + Fixed bug #644 with HTTP health monitors. thanks Brian Hartsock + fix for #650 - Connection logging now loads appropriately. thanks Brian Hartsock + added error page requests. thanks Brian Hartsock + Added error pages to the model. thanks Brian Hartsock + Added list parameter for nodeddress. thanks Brian Hartsock + fixed broken test; cleaned up some tests. thanks Brian Hartsock + +[rackspace|load balancers] + fixed broken tests. thanks Brian Hartsock + +[rackspace|loadbalancers] + Fixed bug in deleting multiple nodes. thanks Brian Hartsock + +[slicehost|compute] + update image id in tests. thanks geemus + +[storm_on_demand] + fixes for formats in tests. thanks geemus + +[tests | clodo] + Added ip-management tests. thanks Stepan G. Fedorov + Added ip-management tests. thanks Stepan G. Fedorov + +[tests | clodo ] + ddosprotect field must not exist. thanks Stepan G. Fedorov + +[tests | clodo | compute] + Add most tests. thanks Stepan G Fedorov + Add image tests. thanks Stepan G Fedorov + +[tests | clodo | compute ] + create_server - First try. thanks Stepan G Fedorov + +[vcloud] + mark tests pending in mocked mode. thanks geemus + +[vcloud|compute] + introduce organizations. thanks Peter Meier + make networks working also in organizations. thanks Peter Meier + remove server from organizations as they are within vApps of vDC. thanks Peter Meier + add catalogs to an organization. thanks Peter Meier + a vdc does not have a tasklist. thanks Peter Meier + introduce vapps. thanks Peter Meier + More work on getting server in a useable shape. thanks Peter Meier + fix network to the minimum. thanks Peter Meier + a vapp might not have any childrens attached. thanks Peter Meier + improve models add tests. thanks Peter Meier + improve disk info access. thanks Peter Meier + improve network. thanks Peter Meier + introduce link on a network to parent network. thanks Peter Meier + fix an issue if this is not parsed as an array. thanks Peter Meier + stopgap fix for test data files. thanks geemus + properly namespace vcloud test to prevent breaking others. thanks geemus + +[vsphere] + (#10644) Add servers filter to improve clone performance. thanks Jeff McCune + fix whitespace issue in yaml for mocks. thanks geemus + + +1.1.1 11/11/2011 a468aa9a3445aae4f496b1a51e26572b8379c3da +========================================================= + +Stats! { 'collaborators' => 19, 'downloads' => 300403, 'forks' => 300, 'open_issues' => 14, 'watchers' => 1667 } + +[core] + loosen net-ssh dependency to avoid chef conflict. thanks geemus + +[misc] + 1.1.0 changelog. thanks geemus + + +1.1.0 11/11/2011 b706c7ed66c2e760fdd6222e38c68768575483b2 +========================================================= + +Stats! { 'collaborators' => 19, 'downloads' => 300383, 'forks' => 300, 'open_issues' => 16, 'watchers' => 1667 } + +MVP! Michael Zeng + +[Compute|Libvirt] + Take into account a query string can be empty, different on some rubies it gives nil, on some empty string. thanks Patrick Debois + +[OpenStack|compute] + fix v2.0 auth endpoints. thanks Todd Willey + default metadata to empy hash. thanks Todd Willey + add zone awareness. thanks Todd Willey + +[aws] + add us-west-2 region. thanks geemus + +[aws|cloud_watch] + mark tests pending when mocked. thanks geemus + +[aws|cloudwatch] + Add support for put-metric-alarm call. thanks Jens Braeuer + Remove duplicate RequestId from response. thanks Jens Braeuer + Add mocked implementation of put_metric_alarm. thanks Jens Braeuer + Fix whitespace. thanks Jens Braeuer + Fix merge error. thanks Jens Braeuer + Add mocked version of put_metric_alarm. thanks Jens Braeuer + +[aws|compute] + Mock modify_image_attribute add/remove users. thanks Dan Peterson + Allow mock tagging to work across accounts. thanks Dan Peterson + Fix new instance eventual consistency for the non-filtered case. thanks Dan Peterson + Update security group operations. thanks Dan Peterson + Test for more invalid security group request input when mocking. thanks Dan Peterson + Fix a bug in delete_tags, but come up against a bug in AWS where tags aren't deleted if the resource still exists. thanks Dylan Egan + tags are reset when reloading. #570. thanks Dylan Egan + fixed sopt_instance_request reply parsing when the original request contained a device mapping. thanks MaF + wait_for reload then add server tags. thanks geemus + spot request fixes. thanks geemus + tweaks for spot request bootstrap. thanks geemus + save tags for spot_requests#bootstrap. thanks geemus + update ami for windows. thanks geemus + +[aws|elb] + Missed a change as part of #545. thanks Dan Peterson + use a set union to register new instances. thanks Dylan Egan + return only the instance IDs on describe. Use only available availability zones. :v:. thanks Dylan Egan + attribute aliases for CanonicalHostedZoneName(ID). :v:. thanks Dylan Egan + eventually consistent, like me getting a haircut. :v:. thanks Dylan Egan + +[aws|emr] + mark tests pending when mocked. thanks geemus + +[aws|iam] + slight cleanup and test with a certificate chain. :cake:. thanks Dylan Egan + +[aws|mock] + Dig into mock data instead of instantiating new service objects. thanks Dan Peterson + +[aws|storage] + ensure path isn't empty when specifying endpoint. thanks geemus + +[brightbox] + Fixed incorrect call to reset_ftp_password. thanks Paul Thornthwaite + +[brightbox|compute] + format fixes for tests. thanks geemus + +[core] + treat boolean values as a boolean. thanks Peter Meier + fix attribute squashing with : in key. thanks Peter Meier + all services should recognize :connection_options. thanks geemus + separate loggers for deprecations/warnings. thanks geemus + avoid duplicates in Fog.providers. thanks geemus + more useful structure for Fog.providers. thanks geemus + add newlines to logger messages. thanks geemus + update stats raketask to point to org. thanks geemus + toss out nil-value keys when checking required credentials. thanks geemus + +[dns] + Made model tests use uniq domain names. thanks Brian Hartsock + +[dnsmadeeasy|dns] + Fix Fog::DNS::DNSMadeEasy::Record#save to handle updating a record correctly. thanks Peter Weldon + +[docs] + update links to point to http://github.com/fog/fog. thanks geemus + +[dynect|dns] + Automatically poll jobs if we get them. Closes #575. thanks Dan Peterson + +[misc] + Change response parameter. thanks Alan Ivey + Missing HEAD method. thanks Andrew Newman + Missing HEAD method. thanks Andrew Newman + Putting version back. thanks Andrew Newman + Reformatting and making consistent with other classes. thanks Andrew Newman + Missed renam to head_namespace. thanks Andrew Newman + Reverting version and date in gemspec. thanks Andrew Newman + Formatting. thanks Andrew Newman + Removed puts of element name. thanks Arvid Andersson + Changes to allow EMR control through fog. thanks Bob Briski + Added EMR functions for AWS. thanks Bob Briski + Adding tests. thanks Bob Briski + merge EMR changes with upstream repo. thanks Bob Briski + (#10055) Search vmFolder inventory vs children. thanks Carl Caum + Adding a path attribute to the vm_mob_ref hash. thanks Carl Caum + Cleanup Attributes#merge_attributes. thanks Hemant Kumar + Update S3 doc example to show current API. thanks Jason Roelofs + Restructure main website's navigation. thanks Jason Roelofs + Add CloudFormation UpdateStack call. thanks Jason Roelofs + Minor whitespace change. thanks Jens Braeuer + Trailing whitespace cleanup. thanks Jens Braeuer + Whitespace cleanup. thanks Jens Braeuer + Fix merge error. thanks Jens Braeuer + Removed statement about @geemus being only member of collaborators list since it's not true anymore. thanks John Wang + Fixes Fog::AWS::Storage#put_(bucket|object)_acl. thanks Jonas Pfenniger + Randomize bucket names in tests. thanks Jonas Pfenniger + Fix AWS S3 bucket and object tests. thanks Jonas Pfenniger + (#10570) Use nil in-place of missing attributes. thanks Kelsey Hightower + (#10570) Update `Fog::Compute::Vsphere` tests. thanks Kelsey Hightower + We use 'Key' for all S3 objects now. thanks Kevin Menard + Implemented mocks for Zerigo. thanks Kevin Menard + Updated docs to use newer arg, rather than the old deprecated one. thanks Kevin Menard + Added the ability to search Zerigo records for a particular zone. thanks Kevin Menard + Return the only element of the array, not the array itself. thanks Kevin Menard + Fixed an issue whereby saving an existing record in Zerigo would nil out its value. thanks Kevin Menard + added DeleteAlarms, DescribeAlarms and PutMetricAlarms. thanks Michael Zeng + re-adding files. thanks Michael Zeng + adding describe_alarm_history. thanks Michael Zeng + adding diable/enable alarm actions. thanks Michael Zeng + added DescribeAlarmHistory request and parser. thanks Michael Zeng + fixing describe_alarms and describe_alarms_for_metric requests. thanks Michael Zeng + cleaned up requesters and parsers. thanks Michael Zeng + added SetAlarmState. thanks Michael Zeng + included more response elements, request parameters should now be complete. Included model and collection classes. thanks Michael Zeng + bug fixes. thanks Michael Zeng + fixed models and added tests. thanks Michael Zeng + no need to add rake dep. thanks Michael Zeng + revert gempspec date change. thanks Michael Zeng + reverting cloud_watch.rb. thanks Michael Zeng + reverting cloud_watch.rb. thanks Michael Zeng + reverting cloud_watch.rb. thanks Michael Zeng + reverting cloud_watch.rb. thanks Michael Zeng + reverting cloud_watch.rb. thanks Michael Zeng + added newline to the end of file. thanks Michael Zeng + removed all tabs. thanks Michael Zeng + added alarm_data_tests. thanks Michael Zeng + spacing change. thanks Michael Zeng + AWS#hash_to_acl - add support for EmailAddress and URI grantee types. thanks Nathan Sutton + Test and improve Fog::Storage::AWS.hash_to_acl. thanks Nathan Sutton + Adding a method to unmock Fog. Addresses issue #594. thanks Nathan Sutton + Adding documentation for Fog.unmock! and Fog::Mock.reset. thanks Nathan Sutton + added linode ssh support. thanks Nicholas Ricketts + added linode ssh support with proper public ip address. thanks Nicholas Ricketts + cleaned up code to use att_XX methods. thanks Nicholas Ricketts + clean up public_ip_address code for linode. thanks Nicholas Ricketts + Seems like rackspace might have changed this. thanks Nik Wakelin + Sends power parameter in GoGrid's grid_server_power request. thanks Pablo Baños López + Slicehost uses record-type and zone-id for their API, which messes with Fog internals, so changing these to record_type and zone_id in the parser. thanks Patrick McKenzie + Did this do anything?. thanks Patrick McKenzie + Revert "Slicehost uses record-type and zone-id for their API, which messes with Fog internals, so changing these to record_type and zone_id in the parser.". thanks Patrick McKenzie + Not having the best of days with git. Revert the reversion of the commit that I really do want to make. thanks Patrick McKenzie + Slicehost uses record-type and zone-id for their API, which messes with Fog internals, so changing these to record_type and zone_id in the parser. thanks Patrick McKenzie + Do not touch .gitignore. thanks Patrick McKenzie + Fixing Slicehost DNS so that a) tests pass b) token names map to what Fog expects -- record_type not record-type, value not data, etc c) creation of new DNS records possible. thanks Patrick McKenzie + 1) Fix so that getting a single record actually works. 2) zone.records currently returns all records in account, not just records for that zone. Add failing test (temporarily, assumes test account has existing zones for this to actually fail) + fix. 3) Add in data alias for record.value, just in case someone needs it, as Slicehost calls this data. thanks Patrick McKenzie + Allow updates of DNS records. Updates on zones not supported yet. thanks Patrick McKenzie + Fixing parsing of zone.records.get(id) so that it parses a single record properly rather than attempting to parse a list of records improperly. Fixing tests to match this (expected) behavior rather than work-around the broken way. thanks Patrick McKenzie + Getting it so zone.records works as expected (loads all records, for that zone only). thanks Patrick McKenzie + simplification. thanks Peter Meier + Optimize vSphere convert_vm_mob_ref_to_attr_hash. thanks Rich Lane + Compact the way options are mapped to request. thanks Todd Willey + Allow setting userdata as plain ascii or b64. thanks Todd Willey + bump excon dep. thanks geemus + [rackspace][dns] fixes for job request format. thanks geemus + bump net-ssh dependency. thanks geemus + tshirt offer should be implicit, rather than explicit. thanks geemus + add region option to aws sns service recognizes method. thanks lostboy + add capabilities support to cloudformation createstack request. thanks lostboy + +[ninefold|storage] + omit signature in stringtosign. thanks geemus + check objectid for existence. thanks geemus + allow overwriting files for consistency. thanks geemus + +[rackspace|dns] + Fixed request tests that need unique domain name. thanks Brian Hartsock + Adapted to changes in callback mechanism. thanks Brian Hartsock + +[rackspace|load_balancers] + made lb endpoint configurable. thanks Brian Hartsock + +[release] + omit Patrick Debois from future MVP status. thanks geemus + +[vsphere|compute] + test fixes. thanks geemus + + 1.0.0 09/29/2011 a81be08ef2473af91f16f4926e5b3dfa962a34ae ========================================================= @@ -176,8 +2414,8 @@ MVP! Patrick Debois [compute|linode] move linode compute to its own shared area (namespacing should probably be corrected). thanks geemus -[compute|new_servers] - move new_servers compute to its own shared area (namespacing should probably be corrected). thanks geemus +[compute|bare_metal_cloud] + move bare_metal_cloud compute to its own shared area (namespacing should probably be corrected). thanks geemus [compute|ninefold] move ninefold compute to its own shared area (namespacing should probably be corrected). thanks geemus diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index e986d2092..000000000 --- a/docs/_config.yml +++ /dev/null @@ -1,39 +0,0 @@ -safe: false -auto: false -server: false -server_port: 4000 - -source: . -destination: ./_site -plugins: ./_plugins - -future: true -lsi: false -pygments: false -markdown: maruku -permalink: none - -maruku: - use_tex: false - use_divs: false - png_engine: blahtex - png_dir: images/latex - png_url: /images/latex - -rdiscount: - extensions: [] - -kramdown: - auto_ids: true, - footnote_nr: 1 - entity_output: as_char - toc_levels: 1..6 - use_coderay: false - - coderay: - coderay_wrap: div - coderay_line_numbers: inline - coderay_line_numbers_start: 1 - coderay_tab_width: 4 - coderay_bold_every: 10 - coderay_css: style diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100755 index effe88a63..000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - fog - {{ page.title }} - - - - - - - - - - - - - - - -
-
- -

{{ page.title }}

-
-
version
vX.Y.Z
-
install
gem install fog
-
source
geemus/fog
-
-
- -
- - {{ content }} - -

Services

- - -

About

- - -
- -
- sponsored by - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/about/contributing.markdown b/docs/about/contributing.markdown deleted file mode 100644 index 79803ea38..000000000 --- a/docs/about/contributing.markdown +++ /dev/null @@ -1,228 +0,0 @@ ---- -layout: default -title: Contributing ---- - -First off, high five for coming to visit this page. You are my new hero. - -## Overview - -* Organize your patches by keeping all related changes together in a topic branch. -* Rebase your branch against master before submitting a pull request (and squish any 'oops' or work in progress commits). -* Submit changes as pull requests describing what the changes should cover and referencing issues (if any). -* Use 'tags' in your commits to indicate the scope, so things like '\[aws|compute\] fixed something'. -* Write and run tests. Tests should follow through usage workflows and ought to pass both with mocking on and off. - -## Deep dive - -Now then, some of the what makes it tick and why. For simplicity let's pretend you want to implement a new service, from scratch. I will walk through the requisite pieces and important things to keep in mind as you go. - -But, before I dive too deep, I'll leave you with an out. Other great ways to contribute are fixing bugs, writing documentation or helping port other projects to use fog. That way everybody wins! - -## The Service - -First and foremost you'll need to create a service, which should start from something like: - - module Fog - class TheService < Fog::Service - - requires :necessary_credential - - model_path 'path/to/models' - collection 'name_of_collection' - model 'name_of_model' - - request_path 'path/to/requests' - request 'name_of_request' - - class Mock - include Collections - end - - class Real - include Collections - end - - end - end - -### Highlights: -* we segregate between real and mock so it is easier to add stuff to one or the other later. -* this is where any shared stuff will go, like making/signing requests - -## Requests - -The next thing to bite off are the requests. fog is all about making cloud services easier to use and move between, but requests are not where this happens. Requests should map closely to the actual api requests (you should be able to directly reference the api docs and vice versa). In particular, try to keep the output of any data parsing as close to the actual format as possible. This makes implementation and maintenance much easier and provides a solid foundation for models to build nice things on top of. I generally end up working on stuff to get/list details first and then filling in create/destroy pairs and other requests. -You start with something like this: - -
-module Fog
-  class TheService
-
-    class Real
-
-      def request(*args)
-      end
-
-    end
-
-    class Mock
-
-      def request(*args)
-        Fog::Mock.not_implemented
-      end
-
-    end
-
-  end
-end
-
- -### Highlights: -* You should define the method twice, once for the real implementation and once for mocked (they should take the same arguments). -* The mock versions should just start out by raising a not implemented error, you can come back and fill this in later. -* The real version should make a request, probably by a method defined on the real class in the service you defined earlier. -* Each request should either return an Excon::Response (with a parsed body where appropriate) or raise an error. - -## Tests - -Now would be a good time to write some tests to make sure what you have written works (and will continue to). I've tried a couple variations on testing in the past, but have settled on consolidated lifetime testing. These vary enough that its hard to give a single simple example, but you can see many examples in "tests/compute/requests/aws":https://github.com/geemus/fog/tree/master/tests/compute/requests/aws/. - -### Highlights: -* Reuse the same objects and take them through their whole life cycle (this is much faster, and most of the time if one portion fails the others would anyway). -* Test the format of the output to ensure parsers match expectations (check the provider's api docs) and that mocks return matching data. -* Test common failure cases and their behavior, you'll need to know how the service acts in these cases to make better mocks. - -## Models - -You could also skip to the mocks here if you wanted, but I usually find the more time I spend working with the service the easier it is to build mocks. The models are the real pay dirt, you have slogged through low level requests that map to the provider api and now you want a nice interface. This is where models and collections come in. Collections provide access to lists of data on the provider and for creating new objects. Models represent the individual objects. - -If you know which object you'd like to represent you should start with the collection. When naming, please refer to the names that have been chosen for other services. I haven't standardized all nouns yet, but a few are already shared (Flavor, Image, Server) -An example servers collection: - - require 'fog/collection' - require 'fog/theservice/models/server' - module Fog - class TheService - - class Servers < Fog::Collection - - model Fog::TheService::Server - - def all - # get list of servers - load(data) # data is an array of attribute hashes - end - - def get(identity) - # get server matching id - new(data) # data is an attribute hash - rescue Excon::Errors::NotFound - nil - end - - end - - end - end - -### Highlights -* First make an accessor in the Collections model so it will be included in Real and Mock. -* `#model` will take a reference to the class that will be instantiated to represent individual objects. -* `#all` should get a list of servers from the provider and pass an array of attribute hashes, one per server, to load. -* `#get` should take an identity reference and instantiate a new model object with an attribute hash returned from the remote server, or return nil of no such object exists. - -Models handle remapping attributes into friendlier names and providing the rest of the interface. -An example model: - - require 'fog/model' - module Fog - module TheService - - class Server << Fog::Model - - identity :id - - attribute :state, 'StatusValue' - - def destroy - requires :identity - connection.destroy_server(identity) - true - end - - def ready? - state == 'running' - end - - def save - requires ... - connection.create_server(options) - true - end - - end - - end - end - -### Highlights -* `#identity` captures the id/name that the objects are identified by and takes the same arguments as attribute. -* `#attribute` takes the name to make a variable available as and one or more aliases that parsers/requests will return this value as. -* `#destroy` will require the identity of the model and should destroy it and return true. -* `#ready?` should return whether the object has finished being initialized (where appropriate). -* `#save` should take any required objects and instantiate the object on the provider's service. -* These models just rely on underlying collections and requests, so it should not be necessary at this level to distinguish between Real and Mock methods. - -## Mocks - -Mocks provide a powerful tool for users of fog to experiment with their implementations much more quickly and without incurring costs. I usually save these for last, as implementing the requests and models provide some necessary context to finally put the mocks together. Your services mock class should have a data method that will return mocked data like so: - - module Fog - module TheService - - class Mock - def self.data - @data ||= Hash.new do |hash, key| - hash[key] = {} - end - end - end - - end - end - -The keys in this hash should represent a unique identifier of the user accessing the data and the value assigned should contain any default data that a new user might have. Any implemented mock requests should then return data retrieved from here or raise an error. -For instance: - - module Fog - module TheService - - class Mock - - def destroy_server(server_identity) - if data = self.data[:servers].delete(server_identity) - response = Excon::Response.new - response.status = 202 - response.body = data - response - else - raise Fog::TheService::NotFound - end - end - - end - - end - end - -### Highlights -* Mock requests should return the same type of data as an already parsed real response or should return the same error as a real problem. -* By mocking at this low level, higher level functions are automatically mocked out for you. -* The extra rigorous tests related to output formatting and error messages should help keep you honest, and each should pass in both mocked and unmocked modes. - -## Summary - -That provides a lot more detail than you will probably need right away, but hopefully you can refer back to different sections as you need them. If you have any questions send me a github message or email me (address is on my profile). You should always start development by creating your own fork. When you feel confident about your fork, send me a pull request. Be forewarned that I may edit some things before it gets to master, but I'll do my best to take care of this in a timely manner. - -Thanks again for your interest and let me know if there is anything else I can do to help. diff --git a/docs/about/getting_started.markdown b/docs/about/getting_started.markdown deleted file mode 100644 index 0e0b769cb..000000000 --- a/docs/about/getting_started.markdown +++ /dev/null @@ -1,83 +0,0 @@ ---- -layout: default -title: Getting Started ---- - -First off, install the gem: - - $ gem install fog - -## Setting Up Local Storage - -We will be using Local storage in the example. Local storage provides the same api that cloud storage services in fog do, but without the bother of needing to signup for stuff or pay extra money. - -First, make a local directory to hold your data. - - $ mkdir ~/fog - -Now we can start writing our script, first off we should require fog. - - require 'rubygems' - require 'fog' - -Now in order to play with our data we need to setup a storage connection. - - storage = Fog::Storage.new({ - :local_root => '~/fog', - :provider => 'Local' - }) - -`storage` will now contain our storage object, configured to use the Local provider from our specified directory. - -## Storing Data - -Now that you have cleared the preliminaries you are ready to start storing data. Storage providers in fog segregate files into `directories` to make it easier to organize things. So lets create a directory so we can see that in action. - - directory = storage.directories.create( - :key => 'data' - ) - -To make sure it was created you can always check in your filesystem, but we can also check from inside fog. - - storage.directories - -Progress! Now it is time to actually create a file inside our new directory. - - file = directory.files.create( - :body => 'Hello World!', - :key => 'hello_world.txt' - ) - -We should now have our file, first we can open it up and make sure we are on the right track. - - $ open ~/fog/hello_world.txt - -It is much more likely that you will want to see what files you have from inside fog though. - - directory.files - -Now that we have run through all the basics, lets clean up our mess. - - file.destroy - directory.destroy - -After that you should be able to check your directory list in fog or your filesystem and see you are safely back to square one. - -## Next Steps - -Using the same interface you can also practice working against a real provider (such as Amazon S3). Rather than worrying about signing up for an account right away though, we can use mocks to simulate S3 while we practice. - -This time we will turn on mocking and then, just like before, we will need to make a connection. - - Fog.mock! - storage = Fog::Storage.new({ - :aws_access_key_id => 'fake_access_key_id', - :aws_secret_access_key => 'fake_secret_access_key', - :provider => 'AWS' - }) - -You may notice that we used bogus credentials, this is fine since we are just simulating things. To use real S3 you can simply omit `Fog.mock!` and swap in your real credentials. - -Once you have your connection you can go through all the steps you did before, only now you will be working against a real cloud service (or at least a simulated one). - -Congratulations and welcome to the cloud! Continue your journey at [fog.io](http://fog.io) diff --git a/docs/about/press.markdown b/docs/about/press.markdown deleted file mode 100644 index b26275b62..000000000 --- a/docs/about/press.markdown +++ /dev/null @@ -1,52 +0,0 @@ ---- -layout: default -title: Press ---- - -Mentions and blog posts from elsewhere in reverse chronological order by day (and alphasorted for same days). - -**September 13th, 2011** - -* [Libvirt support for fog](http://jedi.be/blog/2011/09/13/libvirt-fog-provider/) - -**August 1st, 2011** - -* [Using EBS Snapshots with Fog](http://www.mediamolecule.com/lab/article/using_ebs_snapshots_with_fog/) - -**June 21st, 2011** - -* [Mocking fog When Using It With Carrierwave](http://www.engineyard.com/blog/2011/mocking-fog-when-using-it-with-carrierwave/) - -**June 14th, 2011** - -* [Backing Up Your Data With Fog](http://larrywright.me/blog/articles/221-backing-up-your-data-with-fog) - -**April 7th, 2011** - -* [Testing multipart Uploads to S3 with Threads](http://blog.vicecity.co.uk/post/4425574978/multipart-uploads-fog-threads-win) - -**March 9th, 2011** - -* [Offsite Backups with fog](http://www.engineyard.com/blog/2011/offsite-backups-with-fog/) - -**March 2nd, 2011** - -* [Better AWS Access Control with IAM and Fog](http://blog.zerosum.org/2011/03/02/better-aws-access-control-with-iam-and-fog.html) -* [Using Amazon's CloudFormation, cloud-init, chef and fog to automate infrastructure](http://allanfeid.com/content/using-amazons-cloudformation-cloud-init-chef-and-fog-automate-infrastructure) - -**January 6th, 2011** - -* [Happy New Year (and 0.4.0) from fog!](http://www.engineyard.com/blog/2011/happy-new-year-and-0-4-0-from-fog/) - -**November 30th, 2010** - -* [Getting Hired: fog Edition](http://www.engineyard.com/blog/2010/getting-hired-fog-edition/) - -**October 13, 2010** - -* [Engine Yard Announces Formal Support for ‘fog’ to Ensure Application Portability in the Cloud](http://www.engineyard.com/company/press/2010-10-13-engine-yard-announces-formal-support-for-%E2%80%98fog%E2%80%99-to-ensure-application-portability-in-the-cloud) -* [Wesley Beary and fog Promoted to the Engine Yard Open Source Program](http://www.engineyard.com/blog/2010/wesley-beary-and-fog-promoted-to-the-engine-yard-open-source-program/) - -**September 28, 2010** - -* [The Curious Tale of the Humble Micro](http://www.engineyard.com/blog/2010/the-curious-tale-of-the-humble-micro/) diff --git a/docs/about/structure.markdown b/docs/about/structure.markdown deleted file mode 100644 index c129ad47f..000000000 --- a/docs/about/structure.markdown +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: default -title: Structure ---- - -fog is the Ruby cloud computing library, top to bottom: - -* Collections provide a simplified interface, making clouds easier to work with and switch between. -* Requests allow power users to get the most out of the features of each individual cloud. -* Mocks make testing and integrating a breeze. - -## Collections - -A high level interface to each cloud is provided through collections, such as `images` and `servers`. -You can see a list of available collections by calling `collections` on the connection object. You can try it out using the `fog` command: - - >> AWS.collections - [:addresses, :directories, ..., :volumes, :zones] - -Some collections are available across multiple providers: - -* compute providers have `flavors`, `images` and `servers` -* dns providers have `zones` and `records` -* storage providers have `directories` and `files` - -Collections share basic CRUD type operations, such as: -* `all` - fetch every object of that type from the provider. -* `create` - initialize a new record locally and a remote resource with the provider. -* `get` - fetch a single object by it's identity from the provider. -* `new` - initialize a new record locally, but do not create a remote resource with the provider. - -As an example, we'll try initializing and persisting a Rackspace Cloud server: - - require 'fog' - - compute = Fog::Compute.new({ - :provider => 'Rackspace', - :rackspace_api_key => key, - :rackspace_username => username - }) - - # boot a gentoo server (flavor 1 = 256, image 3 = gentoo 2008.0) - server = compute.servers.create(:flavor_id => 1, :image_id => 3, :name => 'my_server') - server.wait_for { ready? } # give server time to boot - - # DO STUFF - - server.destroy # cleanup after yourself or regret it, trust me - -## Models - -Many of the collection methods return individual objects, which also provide common methods: -* `destroy` - will destroy the persisted object from the provider -* `save` - persist the object to the provider -* `wait_for` - takes a block and waits for either the block to return true for the object or for a timeout (defaults to 10 minutes) - -## Requests - -Requests allow you to dive deeper when the models just can't cut it. -You can see a list of available requests by calling #requests on the connection object. - -For instance, ec2 provides methods related to reserved instances that don't have any models (yet). Here is how you can lookup your reserved instances: - - $ fog - >> AWS[:ec2].describe_reserved_instances - # - -It will return an [excon](http://github.com/geemus/excon) response, which has `body`, `headers` and `status`. Both return nice hashes. - -## Mocks - -As you might imagine, testing code using Fog can be slow and expensive, constantly turning on and and shutting down instances. -Mocking allows skipping this overhead by providing an in memory representation resources as you make requests. -Enabling mocking easy to use, before you run other commands, simply run: - - Fog.mock! - -Then proceed as usual, if you run into unimplemented mocks fog will raise an error and as always contributions are welcome! diff --git a/docs/about/users.markdown b/docs/about/users.markdown deleted file mode 100644 index d57bd5f98..000000000 --- a/docs/about/users.markdown +++ /dev/null @@ -1,33 +0,0 @@ ---- -layout: default -title: Users ---- - -Here lies a listing of projects and products that are using fog. - -Please feel free to add your own, just please follow these rules for consistency and readability. - -1. Listings should be in alphabetical order and should have a link and list of services used. -2. Projects that are open source should link to where the source code can be found. -3. Products that are not open source should link to where more information about the product can be found. - -Thanks for following these rules to keep the quality high and and the content useful! - -## Projects - -* [carrierwave](http://github.com/jnicklas/carrierwave) = AWS => Storage -* [chef](http://github.com/opscode/chef) = AWS => Compute, Slicehost => Compute, Terremark => vCloud, Rackspace => Compute -* [deckard](http://github.com/joewilliams/deckard) = AWS => Compute -* [gaff](http://github.com/joewilliams/gaff) = AWS => Compute, Slicehost => Compute -* [gemcutter](http://github.com/rubygems/gemcutter) = AWS => Storage -* [plover](http://github.com/railsmachine/plover) = AWS => Compute - -## Products - -* [DevStructure](http://devstructure.com/) = AWS => Compute, Rackspace => Compute, Slicehost => Compute -* [Engine Yard AppCloud](http://www.engineyard.com/cloud) = AWS => \[Compute, Storage\] -* [iSwifter](http://iswifter.youwebinc.com/) = BlueBox => Compute -* [OpenFeint](http://openfeint.com) = BlueBox => Compute -* [PHPFog](https://phpfog.com) = AWS => Compute -* [RowFeeder](https://rowfeeder.com) = Blue Box Group => Compute -* [Viximo](http://viximo.com) = AWS => Compute \ No newline at end of file diff --git a/docs/cdn/index.markdown b/docs/cdn/index.markdown deleted file mode 100644 index 1475aaca4..000000000 --- a/docs/cdn/index.markdown +++ /dev/null @@ -1,82 +0,0 @@ ---- -layout: default -title: CDN ---- - -Faster websites are better. Better experience, better sales, you name it. Unfortunately, making a website faster can be tough. Thankfully a content distribution network, or CDN, can give you great performance bang for your buck. A CDN helps speed things up by putting copies of your files closer to your users. It's like the difference between pizza delivery from across the street and pizza delivery from the next town over. - -The ease and deliciousness are the good news, but until recently CDN's were only available in the big leagues via 'my business guys will talk to your business guys' deals. Fortunately for us, Amazon recently updated CloudFront, their CDN service, to allow us to get these benefits with just a credit card and an API call. So now we'll see how you can spend a few minutes to save your users countless hours of load time. - -## Preliminaries - -First, make sure you have fog installed: - - gem install fog - -Now you'll need to sign up for Cloudfront. Gather up the credentials your new credentials to initialize a connection to the service: - - require 'fog' - - # create a connection to the service - cdn = Fog::CDN.new({ - :provider => 'AWS', - :aws_access_key_id => AWS_ACCESS_KEY_ID, - :aws_secret_access_key => AWS_SECRET_ACCESS_KEY - } - -## Setting Up Your CDN - -Now you'll need to create a 'distribution' which represents a mapping from the CDN to your domain. For the examples we'll pretend we are working on 'http://www.example.com', but you can just switch it to your actual domain. Some other options are available, but the only other one we need to fill in is OriginProtocolPolicy. This sets what to do about http vs https. We will use 'match-viewer' which returns the same protocol as the request, but you can also choose 'http-only' which always returns http responses. - - data = cdn.post_distribution({ - 'CustomOrigin' => { - 'DNSName' => 'www.example.com', - 'OriginProtocolPolicy' => 'match-viewer' - } - }) - - # parse the response for stuff you'll need later - distribution_id = data.body['Id'] - caller_reference = data.body['CallerReference'] - etag = data.headers['ETag'] - cdn_domain_name = data.body['DomainName'] - - # wait for the updates to propogate - Fog.wait_for { - cdn.get_distribution(distribution_id).body['Status'] ## 'Deployed' - } - -## Getting Served - -With the domain name from the distribution in hand you should now be ready to serve content from the edge. All you need to do is start replacing urls like `http://www.example.com/stylesheets/foo.css` with `#{cdn_domain_name}/stylesheets/foo.css`. Just because you can do something doesn't always mean you should though. Dynamic pages are not really well suited to CDN storage, since CDN content will be the same for every user. Fortunately some of your most used content is a great fit. By just switching over your images, javascripts and stylesheets you can have an impact for each and every one of your users. - -Congrats, your site is faster! By default the urls aren't very pretty, something like `http://d1xdx2sah5udd0.cloudfront.net/stylesheets/foo.css`. Thankfully you can use CNAME config options to utilize something like `http://assets.example.com/stylesheets/foo.css`, if you are interested in learning more about this let me know in the comments. - -## Cleaning Up - -But, just in case you need to update things I'll run through how you can make changes. In my case I just want to clean up after myself, so I'll use the distribution_id and ETag from before to disable the distribution. We need to use the ETag as well because it provides a way to refer to different versions of the same distribution and ensures we are updating the version that we think we are. - - data = cdn.put_distribution_config( - distribution_id, - etag, - { - 'CustomOrigin' => { - 'DNSName' => 'www.example.com', - 'OriginProtocolPolicy' => 'match-viewer' - }, - 'CallerReference' => caller_reference, - 'Enabled' => 'false' - } - ) - - # parse the updated etag - etag = data.headers['ETag'] - -Now you just need to wait for the update to happen like before and once its disabled we can delete it: - - Fog.wait_for { - cdn.get_distribution(distribution_id).body['Status'] ## 'Deployed' - } - cdn.delete_distribution(distribution_id, etag) - -Thats it, now go forth and speed up some load times! diff --git a/docs/compute/index.markdown b/docs/compute/index.markdown deleted file mode 100644 index 34cffc388..000000000 --- a/docs/compute/index.markdown +++ /dev/null @@ -1,108 +0,0 @@ ---- -layout: default -title: Compute ---- - -Compute is the lifeblood of the cloud, but with great power comes great complication. Compute opens up huge swaths of potential, but it varies greatly in both capabilities and usage from provider to provider. Thankfully fog helps to abstract these idiosyncrasies to provide a more seamless experience. - -## Installing fog - -fog is distributed as a RubyGem: - - gem install fog - -Or for bundler users, you can add it in your Gemfile: - - gem "fog" - -## Using Amazon EC2 and fog - -Sign up for an account here and copy down your secret access key and access key id from here. We are about to get into the code samples, so be sure to fill in anything in ALL_CAPS with your own values! - -First, create a connection with your new account: - - require 'rubygems' - require 'fog' - - # create a connection - connection = Fog::Compute.new({ - :provider => 'AWS', - :aws_secret_access_key => YOUR_SECRET_ACCESS_KEY, - :aws_access_key_id => YOUR_SECRET_ACCESS_KEY_ID - }) - -With that in hand we are ready to start making EC2 calls! - -## Servers the EC2 way - -Creating a server on EC2 is very easy if you are willing to accept the defaults (the smallest server size, using Ubuntu 10.04 LTS). NOTE: the default EC2 image uses the 'ubuntu' username, rather than 'root' like other services. - - server = connection.servers.create - -You can then list your servers to see that it now appears: - - connection.servers - -Rather than worrying about the whole list, we can also just get the latest data for just our server: - - server.reload - -That can get tedious quickly however, especially when servers can take several minutes to boot. Fog has `wait_for` for cases like this and `ready?` for checking to see when a server has completed its start up. - - server.wait_for { ready? } - -Once we are done with that we can shut it down. - - server.destroy - -## Bootstrap: Servers the fog Way - -Cycling servers is great, but in order to actually ssh in we need to setup ssh keys and open ports. But rather than worrying about the nitty gritty, we will utilize `bootstrap`. NOTE: normally we could leave out username and use the default (root), but the default Ubuntu from Canonical uses the ubuntu username instead. - - server = connection.servers.bootstrap(:private_key_path => '~/.ssh/id_rsa', :public_key_path => '~/.ssh/id_rsa.pub', :username => 'ubuntu') - -Bootstrap will create the server, but it will also make sure that port 22 is open for traffic and has ssh keys setup. In order to hook everything up it will need the server to be running, so by the time it finishes it will be ready. You can then make commands to it directly: - - server.ssh('pwd') - server.ssh(['pwd', 'whoami']) - -These return an array of results, where each has stdout, stderr and status values so you can check out what your commands accomplished. Now just shut it down to make sure you don't continue getting charged. - - server.destroy - -## Rackspace Cloud Servers - -Rackspace has Cloud Servers and you can sign up here and get your credentials here. - - # create a connection - connection = Fog::Compute.new({ - :provider => 'Rackspace', - :rackspace_username => RACKSPACE_USERNAME, - :rackspace_api_key => RACKSPACE_API_KEY - }) - -If you work with the European cloud from Rackspace you have to add the following: - - :rackspace_auth_url => "lon.auth.api.rackspacecloud.com" - -We will skip over learning how to do this the 'Rackspace Way' and instead jump right to using bootstrap to get their smallest Ubuntu 10.04 LTS server. - - server = connection.servers.bootstrap - -You can run all the same ssh commands and do what you need to, then once again shutdown to ensure you are not charged once you are done. - - server.destroy - -## Mocking out Compute - -You can also start any of these scripts with `Fog.mock!` or start the fog interactive tool from the command line with `FOG_MOCK=true fog` to run in mock mode. In this mode commands are run as local simulation, so no cloud resources are ever consumed and things operate much faster. - -## Cleaning up - -To cover your tracks its a good idea to check for running servers and shut them down, here is one way you might do that. - - connection.servers.select {|server| server.ready? && server.destroy} - -## Summary - -Compute can be tricky, but the abstractions in fog make it much easier to get started. With your servers up and running you can then focus on the task at hand and get some work done. Congratulations on adding a new tool to your arsenal and let us know what we can do better. diff --git a/docs/dns/index.markdown b/docs/dns/index.markdown deleted file mode 100644 index f136682f5..000000000 --- a/docs/dns/index.markdown +++ /dev/null @@ -1,79 +0,0 @@ ---- -layout: default -title: DNS ---- - -The power and flexibility of the cloud are amazing. But sometimes it can be a pain to chase your resources around and keep everything up to date. This is especially true of keeping track of addresses for DNS, but thankfully more and more API driven options are available, allowing you to automate your DNS to keep up with your hardware changes. - -## Setup - -First, make sure you have fog installed: - - gem install fog - -For this first example we will use Zerigo (see below for how to use other providers). You can signup for Zerigo DNS here. Gather up your new credentials to initialize a connection to the service: - - require 'rubygems' - require 'fog' - - # create a connection to the service - dns = Fog::DNS.new({ - :provider => 'Zerigo', - :zerigo_email => ZERIGO_EMAIL, - :zerigo_token => ZERIGO_TOKEN - }) - -## Getting in the Zone - -The first thing you need to do to prepare for your DNS excursion is create a zone for your domain. The zone will contain all of the more specific records that you will create later. You will just need to specify the domain, which should be your url without the 'http' or 'www' parts, and an email address. Then you can create the zone with your DNS connection: - - zone = @dns.zones.create( - :domain => 'example.com', - :email => 'admin@example.com' - ) - -Now that you have a zone you will need to update your registrar to let them know what DNS servers are responsible for your domain. You can ask the zone what values to use: - - zone.nameservers - -## Spinning Records - -With your new zone in hand you can add records as needed. First and foremost you will probably want the 'www' version of your site to point to whatever your ip might be: - - record = @zone.records.create( - :ip => '1.2.3.4', - :name => 'example.com', - :type => 'A' - ) - -Adding other records is similarly easy, for instance if we want 'www.example.com' to go to the same place, we can use a cname record: - - record = @zone.records.create( - :ip => 'example.com', - :name => 'www', - :type => 'CNAME' - ) - -Or, similarly you might want to have your blog elsewhere: - - record = @zone.records.create( - :ip => '4.3.2.1', - :name => 'blog.example.com', - :type => 'A' - ) - -You can add more specifics if you need to, but reasonable defaults make it just that easy. You can also add any other kind of DNS record you might need for mail or other purposes, you can find a nice overview of record options and types on Wikipedia. - -## No Zerigo? No Problem - -If you already have an account with another service you can just as easily use this same code with different credentials. fog currently supports AWS Route 53, Blue Box, DNSimple, Linode, Rackspace, Slicehost and Zerigo; so you can have your pick. As an example you can connect to AWS instead of Zerigo: - - dns = Fog::DNS.new({ - :provider => 'AWS', - :aws_access_key_id => AWS_ACCESS_KEY_ID, - :aws_secret_access_key => AWS_SECRET_ACCESS_KEY - }) - -## Go Forth and Resolve - -You can see an example of reusing code like this in the examples folder. Using this makes it easier to give yourself shortcuts to your cloud servers and manage how clients and users access them as well. It is great to have this flexibility so that you can modify your cloud infrastructure as needed while keeping everything ship shape. It also provides a nice way to create custom subdomains for users and just generally round out your cloud solution. diff --git a/docs/index.markdown b/docs/index.markdown deleted file mode 100644 index 727bd6a6a..000000000 --- a/docs/index.markdown +++ /dev/null @@ -1,96 +0,0 @@ ---- -layout: default -title: The Ruby cloud services library ---- - -Whether you need compute, dns, storage, or a multitude of other services, fog provides an accessible entry point and facilitates cross service compatibility. - -Just getting started working with cloud resources? You are not alone, and having so many complicated options makes it hard to know where to start. fog delivers the knowledge of cloud experts to you, helping you to bootstrap your cloud usage and guiding you as your own expertise develops. - -By coding with fog from the start you avoid vendor lock-in and give yourself more flexibility to provide value. Whether you are writing a library, designing a software as a service product or just hacking on the weekend this flexibility is a huge boon. - -With a rapidly expanding community and codebase the advantages of fog just keep coming. Join us and together we will realize the future of cloud computing. - -## Getting Started - - sudo gem install fog - -Now type 'fog' to try stuff, confident that fog will let you know what to do. Here is an example of wading through server creation for Amazon Elastic Compute Cloud: - - >> server = Compute[:aws].servers.create - ArgumentError: image_id is required for this operation - - >> server = Compute[:aws].servers.create(:image_id => 'ami-5ee70037') - - - >> server.destroy # cleanup after yourself or regret it, trust me - true - -## Go forth and conquer - -Play around and use the console to explore or check out the [getting started guide](/about/getting_started.html) for more details. Once you are reading to start scripting fog, here is a quick hint on how to make connections without the command line thing to help you. - - # create a compute connection - compute = Fog::Compute.new({:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY}) - # compute operations go here - - # create a storage connection - storage = Fog::Storage.new({:provider => 'AWS', :aws_access_key_id => ACCESS_KEY_ID, :aws_secret_access_key => SECRET_ACCESS_KEY}) - # storage operations go here - -geemus says: "That should give you everything you need to get started, but let me know if there is anything I can do to help!" - -## Contributing - -* Find something you would like to work on. For suggestions look for the `easy`, `medium` and `hard` tags in the [issues](http://github.com/geemus/fog/issues) -* Fork the project and do your work in a topic branch. -* Add shindo tests to prove your code works and run all the tests using `bundle exec rake`. -* Rebase your branch against geemus/fog to make sure everything is up to date. -* Commit your changes and send a pull request. - -## T-Shirts - -Wonder how you can get a lovely fog shirt? Look no further! - -* Blue shirts go to people who have contributed indirectly, great examples are writing blog posts or giving lightning talks. -* Grey shirts and a follow from @fog go to people who have made it on to the [contributors list](https://github.com/geemus/fog/contributors) by submitting code. -* Black shirts go to people who have made it on to the [collaborators list](https://github.com/api/v2/json/repos/show/geemus/fog/collaborators) by coercing geemus into adding them (geemus is currently the only member of this list). - -## Resources - -Enjoy, and let me know what I can do to continue improving fog! - -* Work through the [fog tutorial](https://github.com/downloads/geemus/learn_fog/learn_fog.tar.gz) -* Read fog's [API documentation](/rdoc) -* Stay up to date by following [@fog](http://twitter.com/fog) and/or [@geemus](http://twitter.com/geemus) on Twitter. -* Get and give help on the [#ruby-fog](irc://irc.freenode.net/ruby-fog) irc channel on Freenode -* Follow release notes and discussions on the [mailing list](http://groups.google.com/group/ruby-fog) -* Report bugs or find tasks to help with in the [issues](http://github.com/geemus/fog/issues) -* Learn about [contributing](/about/contributing.html) -* See where fog is used and let the world know how you use it [in the wild](/about/users.html) -* Check out blog posts and other mentions in the [press](/about/press.html) - -## Copyright - -(The MIT License) - -Copyright (c) 2010 [geemus (Wesley Beary)](http://github.com/geemus) - -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. diff --git a/docs/public/crossdomain.xml b/docs/public/crossdomain.xml deleted file mode 100755 index 0d429292c..000000000 --- a/docs/public/crossdomain.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/public/css/fog.css b/docs/public/css/fog.css deleted file mode 100644 index 3aed11143..000000000 --- a/docs/public/css/fog.css +++ /dev/null @@ -1,129 +0,0 @@ -/* layout */ -body { - background-color: #EBF2F9; - line-height: 1.5em; - text-align: center; -} - -#container { - margin: auto; - text-align: left; - width: 800px; -} - -header { - background-color: #A0C0E1; - border-color: #70A1D2; - -moz-border-radius: 0 0 0.5em 0.5em; - border-radius: 0 0 0.5em 0.5em; - border-style: solid; - border-width: 0 1px 1px 1px; - color: #FFF; - height: 154px; - margin-bottom: 2em; - position: relative; - text-align: center; -} - -header a, header a:active, header a:visited { - color: #FFF; -} - -header img { - position: absolute; - left: 0; - top: 0; -} - -header h1 { - font-size: 2em; - line-height: 154px; -} - -header dl { - background-color: #70A1D2; - border-color: #70A1D2; - -moz-border-radius: 0 0 0.5em 0.5em; - border-radius: 0 0 0.5em 0.5em; - height: 140px; /* 154 - padding-top */ - position: absolute; - padding: 14px 1.5em 0 1.5em; - right: 0; - top: 0; -} - -header dl dt { - font-weight: bold; -} - -#main { - background-color: #FFF; - -moz-border-radius: 0.5em; - border-radius: 0.5em; - color: #666; - border: 1px solid #70A1D2; - padding: 0 1em; - margin-bottom: 2em; -} - -footer { - background-color: #A0C0E1; - border-color: #70A1D2; - -moz-border-radius: 0.5em 0.5em 0 0; - border-radius: 0.5em 0.5em 0 0; - border-style: solid; - border-width: 1px 1px 0 1px; - color: #FFF; - text-align: center; -} - -footer img { - padding: 5px; - vertical-align: middle; -} - -/* misc */ - -h2 { - border-bottom: 2px solid #A0C0E1; - color: #70A1D2; - font-size: 1.5em; - margin-top: 1.33333333333333em; - padding: 0 0.75em 0.75em 0; -} - -code, pre { - background-color: #EBF2F9; - border: 1px solid #70A1D2; - color: #666; -} - -code { - padding: 0 0.2em; -} - -p, ul { - margin-bottom: 1em; - margin-top: 1em; -} - -pre { - -moz-border-radius: 0.5em; - border-radius: 0.5em; - margin: 1em; - white-space: pre; -} - -pre code { - border: none; -} - -@media all and (orientation:portrait) { -} - -@media all and (orientation:landscape) { -} - -@media screen and (max-device-width: 480px) { - /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ -} diff --git a/docs/public/css/handheld.css b/docs/public/css/handheld.css deleted file mode 100755 index 0b8202e9e..000000000 --- a/docs/public/css/handheld.css +++ /dev/null @@ -1,8 +0,0 @@ -* { - float: none; - background: #fff; - color: #000; -} - - -body { font-size: 80%; } \ No newline at end of file diff --git a/docs/public/css/style.css b/docs/public/css/style.css deleted file mode 100755 index 2690ad814..000000000 --- a/docs/public/css/style.css +++ /dev/null @@ -1,129 +0,0 @@ -/* HTML5 ✰ Boilerplate */ - -html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, -abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, -small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, figcaption, figure, footer, header, hgroup, -menu, nav, section, summary, time, mark, audio, video { - margin:0; - padding:0; - border:0; - outline:0; - font-size:100%; - vertical-align:baseline; - background:transparent; -} -article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { - display:block; -} -nav ul { list-style:none; } -blockquote, q { quotes:none; } -blockquote:before, blockquote:after, -q:before, q:after { content:''; content:none; } -a { margin:0; padding:0; font-size:100%; vertical-align:baseline; background:transparent; } -ins { background-color:#ff9; color:#000; text-decoration:none; } -mark { background-color:#ff9; color:#000; font-style:italic; font-weight:bold; } -del { text-decoration: line-through; } -abbr[title], dfn[title] { border-bottom:1px dotted; cursor:help; } -table { border-collapse:collapse; border-spacing:0; } -hr { display:block; height:1px; border:0; border-top:1px solid #ccc; margin:1em 0; padding:0; } -input, select { vertical-align:middle; } - - -body { font:13px/1.231 sans-serif; *font-size:small; } -select, input, textarea, button { font:99% sans-serif; } -pre, code, kbd, samp { font-family: monospace, sans-serif; } - -body, select, input, textarea { color: #444; } -h1,h2,h3,h4,h5,h6 { font-weight: bold; } -html { overflow-y: scroll; } - -a:hover, a:active { outline: none; } -a, a:active, a:visited { color: #607890; } -a:hover { color: #036; } - -ul, ol { margin-left: 1.8em; } -ol { list-style-type: decimal; } - -nav ul, nav li { margin: 0; } -small { font-size: 85%; } -strong, th { font-weight: bold; } -td, td img { vertical-align: top; } -sub { vertical-align: sub; font-size: smaller; } -sup { vertical-align: super; font-size: smaller; } -pre { padding: 15px; white-space: pre; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; } -textarea { overflow: auto; } -.ie6 legend, .ie7 legend { margin-left: -7px; } -input[type="radio"] { vertical-align: text-bottom; } -input[type="checkbox"] { vertical-align: bottom; } -.ie7 input[type="checkbox"] { vertical-align: baseline; } -.ie6 input { vertical-align: text-bottom; } -label, input[type=button], input[type=submit], button { cursor: pointer; } -button, input, select, textarea { margin: 0; } -input:valid, textarea:valid { } -input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; } -.no-boxshadow input:invalid, -.no-boxshadow textarea:invalid { background-color: #f0dddd; } - -::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; } -::selection { background:#FF5E99; color:#fff; text-shadow: none; } -a:link { -webkit-tap-highlight-color: #FF5E99; } - -button { width: auto; overflow: visible; } -.ie7 img { -ms-interpolation-mode: bicubic; } - -.ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; } -.hidden { display: none; visibility: hidden; } -.visuallyhidden { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px, 1px, 1px, 1px); } -.invisible { visibility: hidden; } -.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; visibility: hidden; } -.clearfix:after { clear: both; } -.clearfix { zoom: 1; } - - - /* Primary Styles - Author: - */ - - - - - - - - - - - - - - -@media all and (orientation:portrait) { - -} - -@media all and (orientation:landscape) { - -} - -@media screen and (max-device-width: 480px) { - - - /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ -} - -@media print { - * { background: transparent !important; color: #444 !important; text-shadow: none !important; } - a, a:visited { color: #444 !important; text-decoration: underline; } - a:after { content: " (" attr(href) ")"; } - abbr:after { content: " (" attr(title) ")"; } - .ir a:after { content: ""; } - pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } - thead { display: table-header-group; } - tr, img { page-break-inside: avoid; } - @page { margin: 0.5cm; } - p, h2, h3 { orphans: 3; widows: 3; } - h2, h3{ page-break-after: avoid; } -} - diff --git a/docs/public/images/.gitignore b/docs/public/images/.gitignore deleted file mode 100755 index a5baada18..000000000 --- a/docs/public/images/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore - diff --git a/docs/public/images/engineyard.png b/docs/public/images/engineyard.png deleted file mode 100644 index 2d204430c..000000000 Binary files a/docs/public/images/engineyard.png and /dev/null differ diff --git a/docs/public/images/fog.png b/docs/public/images/fog.png deleted file mode 100644 index 4fffe4854..000000000 Binary files a/docs/public/images/fog.png and /dev/null differ diff --git a/docs/public/js/libs/dd_belatedpng.js b/docs/public/js/libs/dd_belatedpng.js deleted file mode 100755 index 6062fb3c1..000000000 --- a/docs/public/js/libs/dd_belatedpng.js +++ /dev/null @@ -1,13 +0,0 @@ -/** -* DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML . -* Author: Drew Diller -* Email: drew.diller@gmail.com -* URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/ -* Version: 0.0.8a -* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license -* -* Example usage: -* DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector -* DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement -**/ -var DD_belatedPNG={ns:"DD_belatedPNG",imgSize:{},delay:10,nodesFixed:0,createVmlNameSpace:function(){if(document.namespaces&&!document.namespaces[this.ns]){document.namespaces.add(this.ns,"urn:schemas-microsoft-com:vml")}},createVmlStyleSheet:function(){var b,a;b=document.createElement("style");b.setAttribute("media","screen");document.documentElement.firstChild.insertBefore(b,document.documentElement.firstChild.firstChild);if(b.styleSheet){b=b.styleSheet;b.addRule(this.ns+"\\:*","{behavior:url(#default#VML)}");b.addRule(this.ns+"\\:shape","position:absolute;");b.addRule("img."+this.ns+"_sizeFinder","behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;");this.screenStyleSheet=b;a=document.createElement("style");a.setAttribute("media","print");document.documentElement.firstChild.insertBefore(a,document.documentElement.firstChild.firstChild);a=a.styleSheet;a.addRule(this.ns+"\\:*","{display: none !important;}");a.addRule("img."+this.ns+"_sizeFinder","{display: none !important;}")}},readPropertyChange:function(){var b,c,a;b=event.srcElement;if(!b.vmlInitiated){return}if(event.propertyName.search("background")!=-1||event.propertyName.search("border")!=-1){DD_belatedPNG.applyVML(b)}if(event.propertyName=="style.display"){c=(b.currentStyle.display=="none")?"none":"block";for(a in b.vml){if(b.vml.hasOwnProperty(a)){b.vml[a].shape.style.display=c}}}if(event.propertyName.search("filter")!=-1){DD_belatedPNG.vmlOpacity(b)}},vmlOpacity:function(b){if(b.currentStyle.filter.search("lpha")!=-1){var a=b.currentStyle.filter;a=parseInt(a.substring(a.lastIndexOf("=")+1,a.lastIndexOf(")")),10)/100;b.vml.color.shape.style.filter=b.currentStyle.filter;b.vml.image.fill.opacity=a}},handlePseudoHover:function(a){setTimeout(function(){DD_belatedPNG.applyVML(a)},1)},fix:function(a){if(this.screenStyleSheet){var c,b;c=a.split(",");for(b=0;bn.H){i.B=n.H}d.vml.image.shape.style.clip="rect("+i.T+"px "+(i.R+a)+"px "+i.B+"px "+(i.L+a)+"px)"}else{d.vml.image.shape.style.clip="rect("+f.T+"px "+f.R+"px "+f.B+"px "+f.L+"px)"}},figurePercentage:function(d,c,f,a){var b,e;e=true;b=(f=="X");switch(a){case"left":case"top":d[f]=0;break;case"center":d[f]=0.5;break;case"right":case"bottom":d[f]=1;break;default:if(a.search("%")!=-1){d[f]=parseInt(a,10)/100}else{e=false}}d[f]=Math.ceil(e?((c[b?"W":"H"]*d[f])-(c[b?"w":"h"]*d[f])):parseInt(a,10));if(d[f]%2===0){d[f]++}return d[f]},fixPng:function(c){c.style.behavior="none";var g,b,f,a,d;if(c.nodeName=="BODY"||c.nodeName=="TD"||c.nodeName=="TR"){return}c.isImg=false;if(c.nodeName=="IMG"){if(c.src.toLowerCase().search(/\.png$/)!=-1){c.isImg=true;c.style.visibility="hidden"}else{return}}else{if(c.currentStyle.backgroundImage.toLowerCase().search(".png")==-1){return}}g=DD_belatedPNG;c.vml={color:{},image:{}};b={shape:{},fill:{}};for(a in c.vml){if(c.vml.hasOwnProperty(a)){for(d in b){if(b.hasOwnProperty(d)){f=g.ns+":"+d;c.vml[a][d]=document.createElement(f)}}c.vml[a].shape.stroked=false;c.vml[a].shape.appendChild(c.vml[a].fill);c.parentNode.insertBefore(c.vml[a].shape,c)}}c.vml.image.shape.fillcolor="none";c.vml.image.fill.type="tile";c.vml.color.fill.on=false;g.attachHandlers(c);g.giveLayout(c);g.giveLayout(c.offsetParent);c.vmlInitiated=true;g.applyVML(c)}};try{document.execCommand("BackgroundImageCache",false,true)}catch(r){}DD_belatedPNG.createVmlNameSpace();DD_belatedPNG.createVmlStyleSheet(); \ No newline at end of file diff --git a/docs/public/js/libs/jquery-1.4.2.js b/docs/public/js/libs/jquery-1.4.2.js deleted file mode 100755 index fff677643..000000000 --- a/docs/public/js/libs/jquery-1.4.2.js +++ /dev/null @@ -1,6240 +0,0 @@ -/*! - * jQuery JavaScript Library v1.4.2 - * http://jquery.com/ - * - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Sat Feb 13 22:33:48 2010 -0500 - */ -(function( window, undefined ) { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, - - // Is it a simple selector - isSimple = /^.[^:#\[\.,]*$/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // Has the ready events already been bound? - readyBound = false, - - // The functions to execute on DOM ready - readyList = [], - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwnProperty = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - indexOf = Array.prototype.indexOf; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context ) { - this.context = document; - this[0] = document.body; - this.selector = "body"; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - doc = (context ? context.ownerDocument || context : document); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = buildFragment( [ match[1] ], [ doc ] ); - selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - if ( elem ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $("TAG") - } else if ( !context && /^\w+$/.test( selector ) ) { - this.selector = selector; - this.context = document; - selector = document.getElementsByTagName( selector ); - return jQuery.merge( this, selector ); - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return (context || rootjQuery).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return jQuery( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if (selector.selector !== undefined) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.4.2", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = jQuery(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + (this.selector ? " " : "") + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // If the DOM is already ready - if ( jQuery.isReady ) { - // Execute the function immediately - fn.call( document, jQuery ); - - // Otherwise, remember the function for later - } else if ( readyList ) { - // Add the function to the wait list - readyList.push( fn ); - } - - return this; - }, - - eq: function( i ) { - return i === -1 ? - this.slice( i ) : - this.slice( i, +i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || jQuery(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging object literal values or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) { - var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src - : jQuery.isArray(copy) ? [] : {}; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // Handle when the DOM is ready - ready: function() { - // Make sure that the DOM is not already loaded - if ( !jQuery.isReady ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 13 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If there are functions bound, to execute - if ( readyList ) { - // Execute all of them - var fn, i = 0; - while ( (fn = readyList[ i++ ]) ) { - fn.call( document, jQuery ); - } - - // Reset the list of functions - readyList = null; - } - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyBound ) { - return; - } - - readyBound = true; - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - return jQuery.ready(); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent("onreadystatechange", DOMContentLoaded); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return toString.call(obj) === "[object Function]"; - }, - - isArray: function( obj ) { - return toString.call(obj) === "[object Array]"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) { - return false; - } - - // Not own constructor property must be Object - if ( obj.constructor - && !hasOwnProperty.call(obj, "constructor") - && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwnProperty.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw msg; - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") - .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") - .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) { - - // Try to use the native JSON parser first - return window.JSON && window.JSON.parse ? - window.JSON.parse( data ) : - (new Function("return " + data))(); - - } else { - jQuery.error( "Invalid JSON: " + data ); - } - }, - - noop: function() {}, - - // Evalulates a script in a global context - globalEval: function( data ) { - if ( data && rnotwhite.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - - if ( jQuery.support.scriptEval ) { - script.appendChild( document.createTextNode( data ) ); - } else { - script.text = data; - } - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction(object); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} - } - } - - return object; - }, - - trim: function( text ) { - return (text || "").replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // The extra typeof function check is to prevent crashes - // in Safari 2 (See: #3039) - if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = []; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - if ( !inv !== !callback( elems[ i ], i ) ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var ret = [], value; - - // Go through the array, translating each of the items to their - // new value (or values). - for ( var i = 0, length = elems.length; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - proxy: function( fn, proxy, thisObject ) { - if ( arguments.length === 2 ) { - if ( typeof proxy === "string" ) { - thisObject = fn; - fn = thisObject[ proxy ]; - proxy = undefined; - - } else if ( proxy && !jQuery.isFunction( proxy ) ) { - thisObject = proxy; - proxy = undefined; - } - } - - if ( !proxy && fn ) { - proxy = function() { - return fn.apply( thisObject || this, arguments ); - }; - } - - // Set the guid of unique handler to the same of original handler, so it can be removed - if ( fn ) { - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - } - - // So proxy can be declared as an argument - return proxy; - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) || - /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || - /(msie) ([\w.]+)/.exec( ua ) || - !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - browser: {} -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -if ( indexOf ) { - jQuery.inArray = function( elem, array ) { - return indexOf.call( array, elem ); - }; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch( error ) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -function evalScript( i, elem ) { - if ( elem.src ) { - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - } else { - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - } - - if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); - } -} - -// Mutifunctional method to get and set values to a collection -// The value/s can be optionally by executed if its a function -function access( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; -} - -function now() { - return (new Date).getTime(); -} -(function() { - - jQuery.support = {}; - - var root = document.documentElement, - script = document.createElement("script"), - div = document.createElement("div"), - id = "script" + now(); - - div.style.display = "none"; - div.innerHTML = "
a"; - - var all = div.getElementsByTagName("*"), - a = div.getElementsByTagName("a")[0]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return; - } - - jQuery.support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: div.firstChild.nodeType === 3, - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText insted) - style: /red/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: a.getAttribute("href") === "/a", - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55$/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: div.getElementsByTagName("input")[0].value === "on", - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected, - - parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null, - - // Will be defined later - deleteExpando: true, - checkClone: false, - scriptEval: false, - noCloneEvent: true, - boxModel: null - }; - - script.type = "text/javascript"; - try { - script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); - } catch(e) {} - - root.insertBefore( script, root.firstChild ); - - // Make sure that the execution of code works by injecting a script - // tag with appendChild/createTextNode - // (IE doesn't support this, fails, and uses .text instead) - if ( window[ id ] ) { - jQuery.support.scriptEval = true; - delete window[ id ]; - } - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete script.test; - - } catch(e) { - jQuery.support.deleteExpando = false; - } - - root.removeChild( script ); - - if ( div.attachEvent && div.fireEvent ) { - div.attachEvent("onclick", function click() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - jQuery.support.noCloneEvent = false; - div.detachEvent("onclick", click); - }); - div.cloneNode(true).fireEvent("onclick"); - } - - div = document.createElement("div"); - div.innerHTML = ""; - - var fragment = document.createDocumentFragment(); - fragment.appendChild( div.firstChild ); - - // WebKit doesn't clone checked state correctly in fragments - jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; - - // Figure out if the W3C box model works as expected - // document.body must exist before we can do this - jQuery(function() { - var div = document.createElement("div"); - div.style.width = div.style.paddingLeft = "1px"; - - document.body.appendChild( div ); - jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; - document.body.removeChild( div ).style.display = 'none'; - - div = null; - }); - - // Technique from Juriy Zaytsev - // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - var eventSupported = function( eventName ) { - var el = document.createElement("div"); - eventName = "on" + eventName; - - var isSupported = (eventName in el); - if ( !isSupported ) { - el.setAttribute(eventName, "return;"); - isSupported = typeof el[eventName] === "function"; - } - el = null; - - return isSupported; - }; - - jQuery.support.submitBubbles = eventSupported("submit"); - jQuery.support.changeBubbles = eventSupported("change"); - - // release memory in IE - root = script = div = all = a = null; -})(); - -jQuery.props = { - "for": "htmlFor", - "class": "className", - readonly: "readOnly", - maxlength: "maxLength", - cellspacing: "cellSpacing", - rowspan: "rowSpan", - colspan: "colSpan", - tabindex: "tabIndex", - usemap: "useMap", - frameborder: "frameBorder" -}; -var expando = "jQuery" + now(), uuid = 0, windowData = {}; - -jQuery.extend({ - cache: {}, - - expando:expando, - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - "object": true, - "applet": true - }, - - data: function( elem, name, data ) { - if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { - return; - } - - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ], cache = jQuery.cache, thisCache; - - if ( !id && typeof name === "string" && data === undefined ) { - return null; - } - - // Compute a unique ID for the element - if ( !id ) { - id = ++uuid; - } - - // Avoid generating a new cache unless none exists and we - // want to manipulate it. - if ( typeof name === "object" ) { - elem[ expando ] = id; - thisCache = cache[ id ] = jQuery.extend(true, {}, name); - - } else if ( !cache[ id ] ) { - elem[ expando ] = id; - cache[ id ] = {}; - } - - thisCache = cache[ id ]; - - // Prevent overriding the named cache with undefined values - if ( data !== undefined ) { - thisCache[ name ] = data; - } - - return typeof name === "string" ? thisCache[ name ] : thisCache; - }, - - removeData: function( elem, name ) { - if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { - return; - } - - elem = elem == window ? - windowData : - elem; - - var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ]; - - // If we want to remove a specific section of the element's data - if ( name ) { - if ( thisCache ) { - // Remove the section of cache data - delete thisCache[ name ]; - - // If we've removed all the data, remove the element's cache - if ( jQuery.isEmptyObject(thisCache) ) { - jQuery.removeData( elem ); - } - } - - // Otherwise, we want to remove all of the element's data - } else { - if ( jQuery.support.deleteExpando ) { - delete elem[ jQuery.expando ]; - - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); - } - - // Completely remove the data cache - delete cache[ id ]; - } - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - if ( typeof key === "undefined" && this.length ) { - return jQuery.data( this[0] ); - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - } - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - } else { - return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() { - jQuery.data( this, key, value ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); -jQuery.extend({ - queue: function( elem, type, data ) { - if ( !elem ) { - return; - } - - type = (type || "fx") + "queue"; - var q = jQuery.data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( !data ) { - return q || []; - } - - if ( !q || jQuery.isArray(data) ) { - q = jQuery.data( elem, type, jQuery.makeArray(data) ); - - } else { - q.push( data ); - } - - return q; - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), fn = queue.shift(); - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift("inprogress"); - } - - fn.call(elem, function() { - jQuery.dequeue(elem, type); - }); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function( i, elem ) { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue( type, function() { - var elem = this; - setTimeout(function() { - jQuery.dequeue( elem, type ); - }, time ); - }); - }, - - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - } -}); -var rclass = /[\n\t]/g, - rspace = /\s+/, - rreturn = /\r/g, - rspecialurl = /href|src|style/, - rtype = /(button|input)/i, - rfocusable = /(button|input|object|select|textarea)/i, - rclickable = /^(a|area)$/i, - rradiocheck = /radio|checkbox/; - -jQuery.fn.extend({ - attr: function( name, value ) { - return access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name, fn ) { - return this.each(function(){ - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } - }); - }, - - addClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.addClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( value && typeof value === "string" ) { - var classNames = (value || "").split( rspace ); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className ) { - elem.className = value; - - } else { - var className = " " + elem.className + " ", setClass = elem.className; - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { - setClass += " " + classNames[c]; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - var classNames = (value || "").split(rspace); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - var className = (" " + elem.className + " ").replace(rclass, " "); - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[c] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, i = 0, self = jQuery(this), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery.data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " "; - for ( var i = 0, l = this.length; i < l; i++ ) { - if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - if ( value === undefined ) { - var elem = this[0]; - - if ( elem ) { - if ( jQuery.nodeName( elem, "option" ) ) { - return (elem.attributes.value || {}).specified ? elem.value : elem.text; - } - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - } - - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { - return elem.getAttribute("value") === null ? "on" : elem.value; - } - - - // Everything else, we just grab the value - return (elem.value || "").replace(rreturn, ""); - - } - - return undefined; - } - - var isFunction = jQuery.isFunction(value); - - return this.each(function(i) { - var self = jQuery(this), val = value; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call(this, i, self.val()); - } - - // Typecast each time if the value is a Function and the appended - // value is therefore different each time. - if ( typeof val === "number" ) { - val += ""; - } - - if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( self.val(), val ) >= 0; - - } else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(val); - - jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - this.selectedIndex = -1; - } - - } else { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - // don't set attributes on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery(elem)[name](value); - } - - var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; - - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; - - // Only do all the following if this is a node (faster for style) - if ( elem.nodeType === 1 ) { - // These attributes require special treatment - var special = rspecialurl.test( name ); - - // Safari mis-reports the default selected property of an option - // Accessing the parent's selectedIndex property fixes it - if ( name === "selected" && !jQuery.support.optSelected ) { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - - // If applicable, access the attribute via the DOM 0 way - if ( name in elem && notxml && !special ) { - if ( set ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } - - elem[ name ] = value; - } - - // browsers index elements by id/name on forms, give priority to attributes. - if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { - return elem.getAttributeNode( name ).nodeValue; - } - - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - if ( name === "tabIndex" ) { - var attributeNode = elem.getAttributeNode( "tabIndex" ); - - return attributeNode && attributeNode.specified ? - attributeNode.value : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name === "style" ) { - if ( set ) { - elem.style.cssText = "" + value; - } - - return elem.style.cssText; - } - - if ( set ) { - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - } - - var attr = !jQuery.support.hrefNormalized && notxml && special ? - // Some attributes require a special call on IE - elem.getAttribute( name, 2 ) : - elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return attr === null ? undefined : attr; - } - - // elem is actually elem.style ... set the style - // Using attr for specific style information is now deprecated. Use style instead. - return jQuery.style( elem, name, value ); - } -}); -var rnamespaces = /\.(.*)$/, - fcleanup = function( nm ) { - return nm.replace(/[^\w\s\.\|`]/g, function( ch ) { - return "\\" + ch; - }); - }; - -/* - * A number of helper functions used for managing events. - * Many of the ideas behind this code originated from - * Dean Edwards' addEvent library. - */ -jQuery.event = { - - // Bind an event to an element - // Original by Dean Edwards - add: function( elem, types, handler, data ) { - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) { - elem = window; - } - - var handleObjIn, handleObj; - - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the function being executed has a unique ID - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure - var elemData = jQuery.data( elem ); - - // If no elemData is found then we must be trying to bind to one of the - // banned noData elements - if ( !elemData ) { - return; - } - - var events = elemData.events = elemData.events || {}, - eventHandle = elemData.handle, eventHandle; - - if ( !eventHandle ) { - elemData.handle = eventHandle = function() { - // Handle the second event of a trigger and when - // an event is called after a page has unloaded - return typeof jQuery !== "undefined" && !jQuery.event.triggered ? - jQuery.event.handle.apply( eventHandle.elem, arguments ) : - undefined; - }; - } - - // Add elem as a property of the handle function - // This is to prevent a memory leak with non-native events in IE. - eventHandle.elem = elem; - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = types.split(" "); - - var type, i = 0, namespaces; - - while ( (type = types[ i++ ]) ) { - handleObj = handleObjIn ? - jQuery.extend({}, handleObjIn) : - { handler: handler, data: data }; - - // Namespaced event handlers - if ( type.indexOf(".") > -1 ) { - namespaces = type.split("."); - type = namespaces.shift(); - handleObj.namespace = namespaces.slice(0).sort().join("."); - - } else { - namespaces = []; - handleObj.namespace = ""; - } - - handleObj.type = type; - handleObj.guid = handler.guid; - - // Get the current list of functions bound to this event - var handlers = events[ type ], - special = jQuery.event.special[ type ] || {}; - - // Init the event handler queue - if ( !handlers ) { - handlers = events[ type ] = []; - - // Check for a special event handler - // Only use addEventListener/attachEvent if the special - // events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add the function to the element's handler list - handlers.push( handleObj ); - - // Keep track of which events have been used, for global triggering - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, pos ) { - // don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, - elemData = jQuery.data( elem ), - events = elemData && elemData.events; - - if ( !elemData || !events ) { - return; - } - - // types is actually an event object here - if ( types && types.type ) { - handler = types.handler; - types = types.type; - } - - // Unbind all events for the element - if ( !types || typeof types === "string" && types.charAt(0) === "." ) { - types = types || ""; - - for ( type in events ) { - jQuery.event.remove( elem, type + types ); - } - - return; - } - - // Handle multiple events separated by a space - // jQuery(...).unbind("mouseover mouseout", fn); - types = types.split(" "); - - while ( (type = types[ i++ ]) ) { - origType = type; - handleObj = null; - all = type.indexOf(".") < 0; - namespaces = []; - - if ( !all ) { - // Namespaced event handlers - namespaces = type.split("."); - type = namespaces.shift(); - - namespace = new RegExp("(^|\\.)" + - jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)") - } - - eventType = events[ type ]; - - if ( !eventType ) { - continue; - } - - if ( !handler ) { - for ( var j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( all || namespace.test( handleObj.namespace ) ) { - jQuery.event.remove( elem, origType, handleObj.handler, j ); - eventType.splice( j--, 1 ); - } - } - - continue; - } - - special = jQuery.event.special[ type ] || {}; - - for ( var j = pos || 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( handler.guid === handleObj.guid ) { - // remove the given handler for the given type - if ( all || namespace.test( handleObj.namespace ) ) { - if ( pos == null ) { - eventType.splice( j--, 1 ); - } - - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - - if ( pos != null ) { - break; - } - } - } - - // remove generic event handler if no more handlers exist - if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - removeEvent( elem, type, elemData.handle ); - } - - ret = null; - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - var handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - delete elemData.events; - delete elemData.handle; - - if ( jQuery.isEmptyObject( elemData ) ) { - jQuery.removeData( elem ); - } - } - }, - - // bubbling is internal - trigger: function( event, data, elem /*, bubbling */ ) { - // Event object or event type - var type = event.type || event, - bubbling = arguments[3]; - - if ( !bubbling ) { - event = typeof event === "object" ? - // jQuery.Event object - event[expando] ? event : - // Object literal - jQuery.extend( jQuery.Event(type), event ) : - // Just the event type (string) - jQuery.Event(type); - - if ( type.indexOf("!") >= 0 ) { - event.type = type = type.slice(0, -1); - event.exclusive = true; - } - - // Handle a global trigger - if ( !elem ) { - // Don't bubble custom events when global (to avoid too much overhead) - event.stopPropagation(); - - // Only trigger if we've ever bound an event for it - if ( jQuery.event.global[ type ] ) { - jQuery.each( jQuery.cache, function() { - if ( this.events && this.events[type] ) { - jQuery.event.trigger( event, data, this.handle.elem ); - } - }); - } - } - - // Handle triggering a single element - - // don't do events on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - // Clean up in case it is reused - event.result = undefined; - event.target = elem; - - // Clone the incoming data, if any - data = jQuery.makeArray( data ); - data.unshift( event ); - } - - event.currentTarget = elem; - - // Trigger the event, it is assumed that "handle" is a function - var handle = jQuery.data( elem, "handle" ); - if ( handle ) { - handle.apply( elem, data ); - } - - var parent = elem.parentNode || elem.ownerDocument; - - // Trigger an inline bound script - try { - if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - } - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (e) {} - - if ( !event.isPropagationStopped() && parent ) { - jQuery.event.trigger( event, data, parent, true ); - - } else if ( !event.isDefaultPrevented() ) { - var target = event.target, old, - isClick = jQuery.nodeName(target, "a") && type === "click", - special = jQuery.event.special[ type ] || {}; - - if ( (!special._default || special._default.call( elem, event ) === false) && - !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { - - try { - if ( target[ type ] ) { - // Make sure that we don't accidentally re-trigger the onFOO events - old = target[ "on" + type ]; - - if ( old ) { - target[ "on" + type ] = null; - } - - jQuery.event.triggered = true; - target[ type ](); - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (e) {} - - if ( old ) { - target[ "on" + type ] = old; - } - - jQuery.event.triggered = false; - } - } - }, - - handle: function( event ) { - var all, handlers, namespaces, namespace, events; - - event = arguments[0] = jQuery.event.fix( event || window.event ); - event.currentTarget = this; - - // Namespaced event handlers - all = event.type.indexOf(".") < 0 && !event.exclusive; - - if ( !all ) { - namespaces = event.type.split("."); - event.type = namespaces.shift(); - namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - var events = jQuery.data(this, "events"), handlers = events[ event.type ]; - - if ( events && handlers ) { - // Clone the handlers to prevent manipulation - handlers = handlers.slice(0); - - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; - - // Filter the functions by class - if ( all || namespace.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; - - var ret = handleObj.handler.apply( this, arguments ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - - if ( event.isImmediatePropagationStopped() ) { - break; - } - } - } - } - - return event.result; - }, - - props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), - - fix: function( event ) { - if ( event[ expando ] ) { - return event; - } - - // store a copy of the original event object - // and "clone" to set read-only properties - var originalEvent = event; - event = jQuery.Event( originalEvent ); - - for ( var i = this.props.length, prop; i; ) { - prop = this.props[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary - if ( !event.target ) { - event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either - } - - // check if target is a textnode (safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && event.fromElement ) { - event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; - } - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && event.clientX != null ) { - var doc = document.documentElement, body = document.body; - event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); - event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); - } - - // Add which for key events - if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { - event.which = event.charCode || event.keyCode; - } - - // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) - if ( !event.metaKey && event.ctrlKey ) { - event.metaKey = event.ctrlKey; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && event.button !== undefined ) { - event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); - } - - return event; - }, - - // Deprecated, use jQuery.guid instead - guid: 1E8, - - // Deprecated, use jQuery.proxy instead - proxy: jQuery.proxy, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady, - teardown: jQuery.noop - }, - - live: { - add: function( handleObj ) { - jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); - }, - - remove: function( handleObj ) { - var remove = true, - type = handleObj.origType.replace(rnamespaces, ""); - - jQuery.each( jQuery.data(this, "events").live || [], function() { - if ( type === this.origType.replace(rnamespaces, "") ) { - remove = false; - return false; - } - }); - - if ( remove ) { - jQuery.event.remove( this, handleObj.origType, liveHandler ); - } - } - - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( this.setInterval ) { - this.onbeforeunload = eventHandle; - } - - return false; - }, - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - } -}; - -var removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - elem.removeEventListener( type, handle, false ); - } : - function( elem, type, handle ) { - elem.detachEvent( "on" + type, handle ); - }; - -jQuery.Event = function( src ) { - // Allow instantiation without the 'new' keyword - if ( !this.preventDefault ) { - return new jQuery.Event( src ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - // Event type - } else { - this.type = src; - } - - // timeStamp is buggy for some events on Firefox(#3843) - // So we won't rely on the native value - this.timeStamp = now(); - - // Mark it as fixed - this[ expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - } - // otherwise set the returnValue property of the original event to false (IE) - e.returnValue = false; - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Checks if an event happened on an element within another element -// Used in jQuery.event.special.mouseenter and mouseleave handlers -var withinElement = function( event ) { - // Check if mouse(over|out) are still within the same parent element - var parent = event.relatedTarget; - - // Firefox sometimes assigns relatedTarget a XUL element - // which we cannot access the parentNode property of - try { - // Traverse up the tree - while ( parent && parent !== this ) { - parent = parent.parentNode; - } - - if ( parent !== this ) { - // set the correct event type - event.type = event.data; - - // handle event if we actually just moused on to a non sub-element - jQuery.event.handle.apply( this, arguments ); - } - - // assuming we've left the element since we most likely mousedover a xul element - } catch(e) { } -}, - -// In case of event delegation, we only need to rename the event.type, -// liveHandler will take care of the rest. -delegate = function( event ) { - event.type = event.data; - jQuery.event.handle.apply( this, arguments ); -}; - -// Create mouseenter and mouseleave events -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - setup: function( data ) { - jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); - }, - teardown: function( data ) { - jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); - } - }; -}); - -// submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function( data, namespaces ) { - if ( this.nodeName.toLowerCase() !== "form" ) { - jQuery.event.add(this, "click.specialSubmit", function( e ) { - var elem = e.target, type = elem.type; - - if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - return trigger( "submit", this, arguments ); - } - }); - - jQuery.event.add(this, "keypress.specialSubmit", function( e ) { - var elem = e.target, type = elem.type; - - if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - return trigger( "submit", this, arguments ); - } - }); - - } else { - return false; - } - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialSubmit" ); - } - }; - -} - -// change delegation, happens here so we have bind. -if ( !jQuery.support.changeBubbles ) { - - var formElems = /textarea|input|select/i, - - changeFilters, - - getVal = function( elem ) { - var type = elem.type, val = elem.value; - - if ( type === "radio" || type === "checkbox" ) { - val = elem.checked; - - } else if ( type === "select-multiple" ) { - val = elem.selectedIndex > -1 ? - jQuery.map( elem.options, function( elem ) { - return elem.selected; - }).join("-") : - ""; - - } else if ( elem.nodeName.toLowerCase() === "select" ) { - val = elem.selectedIndex; - } - - return val; - }, - - testChange = function testChange( e ) { - var elem = e.target, data, val; - - if ( !formElems.test( elem.nodeName ) || elem.readOnly ) { - return; - } - - data = jQuery.data( elem, "_change_data" ); - val = getVal(elem); - - // the current data will be also retrieved by beforeactivate - if ( e.type !== "focusout" || elem.type !== "radio" ) { - jQuery.data( elem, "_change_data", val ); - } - - if ( data === undefined || val === data ) { - return; - } - - if ( data != null || val ) { - e.type = "change"; - return jQuery.event.trigger( e, arguments[1], elem ); - } - }; - - jQuery.event.special.change = { - filters: { - focusout: testChange, - - click: function( e ) { - var elem = e.target, type = elem.type; - - if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { - return testChange.call( this, e ); - } - }, - - // Change has to be called before submit - // Keydown will be called before keypress, which is used in submit-event delegation - keydown: function( e ) { - var elem = e.target, type = elem.type; - - if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || - (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || - type === "select-multiple" ) { - return testChange.call( this, e ); - } - }, - - // Beforeactivate happens also before the previous element is blurred - // with this event you can't trigger a change event, but you can store - // information/focus[in] is not needed anymore - beforeactivate: function( e ) { - var elem = e.target; - jQuery.data( elem, "_change_data", getVal(elem) ); - } - }, - - setup: function( data, namespaces ) { - if ( this.type === "file" ) { - return false; - } - - for ( var type in changeFilters ) { - jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); - } - - return formElems.test( this.nodeName ); - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialChange" ); - - return formElems.test( this.nodeName ); - } - }; - - changeFilters = jQuery.event.special.change.filters; -} - -function trigger( type, elem, args ) { - args[0].type = type; - return jQuery.event.handle.apply( elem, args ); -} - -// Create "bubbling" focus and blur events -if ( document.addEventListener ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - jQuery.event.special[ fix ] = { - setup: function() { - this.addEventListener( orig, handler, true ); - }, - teardown: function() { - this.removeEventListener( orig, handler, true ); - } - }; - - function handler( e ) { - e = jQuery.event.fix( e ); - e.type = fix; - return jQuery.event.handle.call( this, e ); - } - }); -} - -jQuery.each(["bind", "one"], function( i, name ) { - jQuery.fn[ name ] = function( type, data, fn ) { - // Handle object literals - if ( typeof type === "object" ) { - for ( var key in type ) { - this[ name ](key, data, type[key], fn); - } - return this; - } - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - var handler = name === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; - - if ( type === "unload" && name !== "one" ) { - this.one( type, data, fn ); - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.add( this[i], type, handler, data ); - } - } - - return this; - }; -}); - -jQuery.fn.extend({ - unbind: function( type, fn ) { - // Handle object literals - if ( typeof type === "object" && !type.preventDefault ) { - for ( var key in type ) { - this.unbind(key, type[key]); - } - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.remove( this[i], type, fn ); - } - } - - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.live( types, data, fn, selector ); - }, - - undelegate: function( selector, types, fn ) { - if ( arguments.length === 0 ) { - return this.unbind( "live" ); - - } else { - return this.die( types, null, fn, selector ); - } - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - - triggerHandler: function( type, data ) { - if ( this[0] ) { - var event = jQuery.Event( type ); - event.preventDefault(); - event.stopPropagation(); - jQuery.event.trigger( event, data, this[0] ); - return event.result; - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, i = 1; - - // link all the functions, so any of them can unbind this click handler - while ( i < args.length ) { - jQuery.proxy( fn, args[ i++ ] ); - } - - return this.click( jQuery.proxy( fn, function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - })); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -var liveMap = { - focus: "focusin", - blur: "focusout", - mouseenter: "mouseover", - mouseleave: "mouseout" -}; - -jQuery.each(["live", "die"], function( i, name ) { - jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { - var type, i = 0, match, namespaces, preType, - selector = origSelector || this.selector, - context = origSelector ? this : jQuery( this.context ); - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split(" "); - - while ( (type = types[ i++ ]) != null ) { - match = rnamespaces.exec( type ); - namespaces = ""; - - if ( match ) { - namespaces = match[0]; - type = type.replace( rnamespaces, "" ); - } - - if ( type === "hover" ) { - types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); - continue; - } - - preType = type; - - if ( type === "focus" || type === "blur" ) { - types.push( liveMap[ type ] + namespaces ); - type = type + namespaces; - - } else { - type = (liveMap[ type ] || type) + namespaces; - } - - if ( name === "live" ) { - // bind live handler - context.each(function(){ - jQuery.event.add( this, liveConvert( type, selector ), - { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); - }); - - } else { - // unbind live handler - context.unbind( liveConvert( type, selector ), fn ); - } - } - - return this; - } -}); - -function liveHandler( event ) { - var stop, elems = [], selectors = [], args = arguments, - related, match, handleObj, elem, j, i, l, data, - events = jQuery.data( this, "events" ); - - // Make sure we avoid non-left-click bubbling in Firefox (#3861) - if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) { - return; - } - - event.liveFired = this; - - var live = events.live.slice(0); - - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { - selectors.push( handleObj.selector ); - - } else { - live.splice( j--, 1 ); - } - } - - match = jQuery( event.target ).closest( selectors, event.currentTarget ); - - for ( i = 0, l = match.length; i < l; i++ ) { - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( match[i].selector === handleObj.selector ) { - elem = match[i].elem; - related = null; - - // Those two events require additional checking - if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { - related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; - } - - if ( !related || related !== elem ) { - elems.push({ elem: elem, handleObj: handleObj }); - } - } - } - } - - for ( i = 0, l = elems.length; i < l; i++ ) { - match = elems[i]; - event.currentTarget = match.elem; - event.data = match.handleObj.data; - event.handleObj = match.handleObj; - - if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) { - stop = false; - break; - } - } - - return stop; -} - -function liveConvert( type, selector ) { - return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&"); -} - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( fn ) { - return fn ? this.bind( name, fn ) : this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } -}); - -// Prevent memory leaks in IE -// Window isn't included so as not to unbind existing unload events -// More info: -// - http://isaacschlueter.com/2006/10/msie-memory-leaks/ -if ( window.attachEvent && !window.addEventListener ) { - window.attachEvent("onunload", function() { - for ( var id in jQuery.cache ) { - if ( jQuery.cache[ id ].handle ) { - // Try/Catch is to handle iframes being unloaded, see #4280 - try { - jQuery.event.remove( jQuery.cache[ id ].handle.elem ); - } catch(e) {} - } - } - }); -} -/*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function(){ - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function(selector, context, results, seed) { - results = results || []; - var origContext = context = context || document; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context), - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set ); - } - } - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; - } - - if ( context ) { - var ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; - } - - while ( parts.length ) { - var cur = parts.pop(), pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - } else { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function(results){ - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } - } - } - } - - return results; -}; - -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; - -Sizzle.find = function(expr, context, isXML){ - var set, match; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = context.getElementsByTagName("*"); - } - - return {set: set, expr: expr}; -}; - -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var filter = Expr.filter[ type ], found, item, left = match[1]; - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - leftMatch: {}, - attrMap: { - "class": "className", - "for": "htmlFor" - }, - attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); - } - }, - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part){ - var isPartStr = typeof part === "string"; - - if ( isPartStr && !/\W/.test(part) ) { - part = part.toLowerCase(); - - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = part.toLowerCase(); - checkFn = dirNodeCheck; - } - - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - return match[1].toLowerCase(); - }, - CHILD: function(match){ - if ( match[1] === "nth" ) { - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - PSEUDO: function(match, curLoop, inplace, result, not){ - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - if ( !inplace ) { - result.push.apply( result, ret ); - } - return false; - } - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - POS: function(match){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - // Accessing this property makes selected-by-default - // options in Safari work properly - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; - }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 === i; - }, - eq: function(elem, i, match){ - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { - return false; - } - } - - return true; - } else { - Sizzle.error( "Syntax error, unrecognized expression: " + name ); - } - }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - if ( type === "first" ) { - return true; - } - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - return true; - case 'nth': - var first = match[2], last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first === 0 ) { - return diff === 0; - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - ID: function(elem, match){ - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){ - return "\\" + (num - 0 + 1); - })); -} - -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - } else { - if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - } else { - for ( var i = 0; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.compareDocumentPosition ? -1 : 1; - } - - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.sourceIndex ? -1 : 1; - } - - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.ownerDocument ? -1 : 1; - } - - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} - -// Utility function for retreiving the text value of an array of DOM nodes -function getText( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += getText( elem.childNodes ); - } - } - - return ret; -} - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date).getTime(); - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - var root = document.documentElement; - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; - } - }; - - Expr.filter.ID = function(elem, match){ - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - root = form = null; // release memory in IE -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); - }; - } - - div = null; // release memory in IE -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE - })(); -} - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - div = null; // release memory in IE -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -var contains = document.compareDocumentPosition ? function(a, b){ - return !!(a.compareDocumentPosition(b) & 16); -} : function(a, b){ - return a !== b && (a.contains ? a.contains(b) : true); -}; - -var isXML = function(elem){ - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = getText; -jQuery.isXMLDoc = isXML; -jQuery.contains = contains; - -return; - -window.Sizzle = Sizzle; - -})(); -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - slice = Array.prototype.slice; - -// Implement the identical functionality for filter and not -var winnow = function( elements, qualifier, keep ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return (elem === qualifier) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return (jQuery.inArray( elem, qualifier ) >= 0) === keep; - }); -}; - -jQuery.fn.extend({ - find: function( selector ) { - var ret = this.pushStack( "", "find", selector ), length = 0; - - for ( var i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && jQuery.filter( selector, this ).length > 0; - }, - - closest: function( selectors, context ) { - if ( jQuery.isArray( selectors ) ) { - var ret = [], cur = this[0], match, matches = {}, selector; - - if ( cur && selectors.length ) { - for ( var i = 0, l = selectors.length; i < l; i++ ) { - selector = selectors[i]; - - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? - jQuery( selector, context || this.context ) : - selector; - } - } - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( selector in matches ) { - match = matches[selector]; - - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { - ret.push({ selector: selector, elem: cur }); - delete matches[selector]; - } - } - cur = cur.parentNode; - } - } - - return ret; - } - - var pos = jQuery.expr.match.POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; - - return this.map(function( i, cur ) { - while ( cur && cur.ownerDocument && cur !== context ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { - return cur; - } - cur = cur.parentNode; - } - return null; - }); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - if ( !elem || typeof elem === "string" ) { - return jQuery.inArray( this[0], - // If it receives a string, the selector is used - // If it receives nothing, the siblings are used - elem ? jQuery( elem ) : this.parent().children() ); - } - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context || this.context ) : - jQuery.makeArray( selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, slice.call(arguments).join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], cur = elem[dir]; - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); -var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g, - rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i, - rtagName = /<([\w:]+)/, - rtbody = /"; - }, - wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and