├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README ├── README.textile ├── Rakefile ├── app ├── controllers │ ├── application_controller.rb │ ├── home_controller.rb │ ├── sessions_controller.rb │ └── users_controller.rb ├── helpers │ ├── application_helper.rb │ ├── home_helper.rb │ └── users_helper.rb ├── models │ └── user.rb └── views │ ├── home │ └── index.html.erb │ ├── layouts │ └── application.html.erb │ ├── shared │ └── _navigation.html.erb │ └── users │ ├── edit.html.erb │ └── show.html.erb ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cucumber.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── backtrace_silencers.rb │ ├── generators.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── omniauth.rb │ ├── secret_token.rb │ └── session_store.rb ├── locales │ └── en.yml ├── mongoid.yml └── routes.rb ├── db └── seeds.rb ├── features ├── step_definitions │ └── web_steps.rb └── support │ ├── env.rb │ ├── paths.rb │ └── selectors.rb ├── lib └── tasks │ ├── .gitkeep │ └── cucumber.rake ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── javascripts │ ├── .gitkeep │ ├── application.js │ ├── jquery.js │ └── rails.js ├── robots.txt └── stylesheets │ ├── .gitkeep │ └── application.css ├── script ├── cucumber └── rails ├── spec ├── controllers │ ├── home_controller_spec.rb │ └── users_controller_spec.rb ├── models │ └── user_spec.rb ├── spec_helper.rb └── support │ └── mongoid.rb └── vendor └── plugins └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------------------------- 2 | # Ignore these files when commiting to a git repository 3 | # 4 | # The original version of this file is found here: 5 | # https://github.com/fortuity/rails3-gitignore/raw/master/gitignore.txt 6 | # 7 | # Corrections? Improvements? Create a GitHub issue: 8 | # https://github.com/fortuity/rails3-gitignore/issues 9 | #---------------------------------------------------------------------------- 10 | 11 | # bundler state 12 | /.bundle 13 | /vendor/bundle/ 14 | 15 | # minimal Rails specific artifacts 16 | db/*.sqlite3 17 | /log/* 18 | tmp/* 19 | 20 | # various artifacts 21 | **.war 22 | *.rbc 23 | *.sassc 24 | .rspec 25 | .sass-cache 26 | /config/config.yml 27 | /config/database.yml 28 | /coverage.data 29 | /coverage/ 30 | /db/*.javadb/ 31 | /db/*.sqlite3-journal 32 | /doc/api/ 33 | /doc/app/ 34 | /doc/features.html 35 | /doc/specs.html 36 | /public/cache 37 | /public/stylesheets/compiled 38 | /public/system 39 | /spec/tmp/* 40 | /cache 41 | /capybara* 42 | /capybara-*.html 43 | /gems 44 | /rerun.txt 45 | /spec/requests 46 | /spec/routing 47 | /spec/views 48 | /specifications 49 | 50 | # scm revert files 51 | **.orig 52 | 53 | # Mac finder artifacts 54 | .DS_Store 55 | 56 | # Netbeans project directory 57 | /nbproject/ 58 | 59 | # Textmate project files 60 | /*.tmpproj 61 | 62 | # vim artifacts 63 | **.swp 64 | 65 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | gem 'rails', '3.0.7' 3 | gem "rspec-rails", ">= 2.5.0", :group => [:development, :test] 4 | gem "database_cleaner", ">= 0.6.7", :group => :test 5 | gem "mongoid-rspec", ">= 1.4.2", :group => :test 6 | gem "factory_girl_rails", ">= 1.1.beta1", :group => :test 7 | gem "cucumber-rails", ">= 0.4.1", :group => :test 8 | gem "capybara", ">= 0.4.1.2", :group => :test 9 | gem "launchy", ">= 0.4.0", :group => :test 10 | gem "bson_ext", ">= 1.3.0" 11 | gem "mongoid", ">= 2.0.1" 12 | gem "omniauth", ">= 0.2.4" 13 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | abstract (1.0.0) 5 | actionmailer (3.0.7) 6 | actionpack (= 3.0.7) 7 | mail (~> 2.2.15) 8 | actionpack (3.0.7) 9 | activemodel (= 3.0.7) 10 | activesupport (= 3.0.7) 11 | builder (~> 2.1.2) 12 | erubis (~> 2.6.6) 13 | i18n (~> 0.5.0) 14 | rack (~> 1.2.1) 15 | rack-mount (~> 0.6.14) 16 | rack-test (~> 0.5.7) 17 | tzinfo (~> 0.3.23) 18 | activemodel (3.0.7) 19 | activesupport (= 3.0.7) 20 | builder (~> 2.1.2) 21 | i18n (~> 0.5.0) 22 | activerecord (3.0.7) 23 | activemodel (= 3.0.7) 24 | activesupport (= 3.0.7) 25 | arel (~> 2.0.2) 26 | tzinfo (~> 0.3.23) 27 | activeresource (3.0.7) 28 | activemodel (= 3.0.7) 29 | activesupport (= 3.0.7) 30 | activesupport (3.0.7) 31 | addressable (2.2.4) 32 | arel (2.0.9) 33 | bson (1.3.0) 34 | bson_ext (1.3.0) 35 | builder (2.1.2) 36 | capybara (0.4.1.2) 37 | celerity (>= 0.7.9) 38 | culerity (>= 0.2.4) 39 | mime-types (>= 1.16) 40 | nokogiri (>= 1.3.3) 41 | rack (>= 1.0.0) 42 | rack-test (>= 0.5.4) 43 | selenium-webdriver (>= 0.0.27) 44 | xpath (~> 0.1.3) 45 | celerity (0.8.9) 46 | childprocess (0.1.8) 47 | ffi (~> 1.0.6) 48 | configuration (1.2.0) 49 | cucumber (0.10.2) 50 | builder (>= 2.1.2) 51 | diff-lcs (>= 1.1.2) 52 | gherkin (>= 2.3.5) 53 | json (>= 1.4.6) 54 | term-ansicolor (>= 1.0.5) 55 | cucumber-rails (0.4.1) 56 | cucumber (>= 0.10.1) 57 | nokogiri (>= 1.4.4) 58 | rack-test (>= 0.5.7) 59 | culerity (0.2.15) 60 | database_cleaner (0.6.7) 61 | diff-lcs (1.1.2) 62 | erubis (2.6.6) 63 | abstract (>= 1.0.0) 64 | factory_girl (2.0.0.beta2) 65 | factory_girl_rails (1.1.beta1) 66 | factory_girl (~> 2.0.0.beta) 67 | rails (>= 3.0.0) 68 | faraday (0.6.1) 69 | addressable (~> 2.2.4) 70 | multipart-post (~> 1.1.0) 71 | rack (< 2, >= 1.1.0) 72 | ffi (1.0.7) 73 | rake (>= 0.8.7) 74 | gherkin (2.3.7) 75 | json (>= 1.4.6) 76 | i18n (0.5.0) 77 | json (1.5.1) 78 | json_pure (1.5.1) 79 | launchy (0.4.0) 80 | configuration (>= 0.0.5) 81 | rake (>= 0.8.1) 82 | mail (2.2.19) 83 | activesupport (>= 2.3.6) 84 | i18n (>= 0.4.0) 85 | mime-types (~> 1.16) 86 | treetop (~> 1.4.8) 87 | mime-types (1.16) 88 | mongo (1.3.0) 89 | bson (>= 1.3.0) 90 | mongoid (2.0.1) 91 | activemodel (~> 3.0) 92 | mongo (~> 1.3) 93 | tzinfo (~> 0.3.22) 94 | will_paginate (~> 3.0.pre) 95 | mongoid-rspec (1.4.2) 96 | mongoid (~> 2.0) 97 | rspec (~> 2) 98 | multi_json (1.0.1) 99 | multi_xml (0.2.2) 100 | multipart-post (1.1.0) 101 | net-ldap (0.2.2) 102 | nokogiri (1.4.4) 103 | oa-basic (0.2.5) 104 | oa-core (= 0.2.5) 105 | rest-client (~> 1.6.0) 106 | oa-core (0.2.5) 107 | oa-enterprise (0.2.5) 108 | addressable (= 2.2.4) 109 | net-ldap (~> 0.2.2) 110 | nokogiri (~> 1.4.2) 111 | oa-core (= 0.2.5) 112 | pyu-ruby-sasl (~> 0.0.3.1) 113 | rubyntlm (~> 0.1.1) 114 | oa-more (0.2.5) 115 | multi_json (~> 1.0.0) 116 | oa-core (= 0.2.5) 117 | rest-client (~> 1.6.0) 118 | oa-oauth (0.2.5) 119 | faraday (~> 0.6.1) 120 | multi_json (~> 1.0.0) 121 | multi_xml (~> 0.2.2) 122 | oa-core (= 0.2.5) 123 | oauth (~> 0.4.0) 124 | oauth2 (~> 0.4.1) 125 | oa-openid (0.2.5) 126 | oa-core (= 0.2.5) 127 | rack-openid (~> 1.3.1) 128 | ruby-openid-apps-discovery (~> 1.2.0) 129 | oauth (0.4.4) 130 | oauth2 (0.4.1) 131 | faraday (~> 0.6.1) 132 | multi_json (>= 0.0.5) 133 | omniauth (0.2.5) 134 | oa-basic (= 0.2.5) 135 | oa-core (= 0.2.5) 136 | oa-enterprise (= 0.2.5) 137 | oa-more (= 0.2.5) 138 | oa-oauth (= 0.2.5) 139 | oa-openid (= 0.2.5) 140 | polyglot (0.3.1) 141 | pyu-ruby-sasl (0.0.3.2) 142 | rack (1.2.2) 143 | rack-mount (0.6.14) 144 | rack (>= 1.0.0) 145 | rack-openid (1.3.1) 146 | rack (>= 1.1.0) 147 | ruby-openid (>= 2.1.8) 148 | rack-test (0.5.7) 149 | rack (>= 1.0) 150 | rails (3.0.7) 151 | actionmailer (= 3.0.7) 152 | actionpack (= 3.0.7) 153 | activerecord (= 3.0.7) 154 | activeresource (= 3.0.7) 155 | activesupport (= 3.0.7) 156 | bundler (~> 1.0) 157 | railties (= 3.0.7) 158 | railties (3.0.7) 159 | actionpack (= 3.0.7) 160 | activesupport (= 3.0.7) 161 | rake (>= 0.8.7) 162 | thor (~> 0.14.4) 163 | rake (0.8.7) 164 | rest-client (1.6.1) 165 | mime-types (>= 1.16) 166 | rspec (2.5.0) 167 | rspec-core (~> 2.5.0) 168 | rspec-expectations (~> 2.5.0) 169 | rspec-mocks (~> 2.5.0) 170 | rspec-core (2.5.2) 171 | rspec-expectations (2.5.0) 172 | diff-lcs (~> 1.1.2) 173 | rspec-mocks (2.5.0) 174 | rspec-rails (2.5.0) 175 | actionpack (~> 3.0) 176 | activesupport (~> 3.0) 177 | railties (~> 3.0) 178 | rspec (~> 2.5.0) 179 | ruby-openid (2.1.8) 180 | ruby-openid-apps-discovery (1.2.0) 181 | ruby-openid (>= 2.1.7) 182 | rubyntlm (0.1.1) 183 | rubyzip (0.9.4) 184 | selenium-webdriver (0.2.0) 185 | childprocess (>= 0.1.7) 186 | ffi (>= 1.0.7) 187 | json_pure 188 | rubyzip 189 | term-ansicolor (1.0.5) 190 | thor (0.14.6) 191 | treetop (1.4.9) 192 | polyglot (>= 0.3.1) 193 | tzinfo (0.3.27) 194 | will_paginate (3.0.pre2) 195 | xpath (0.1.4) 196 | nokogiri (~> 1.3) 197 | 198 | PLATFORMS 199 | ruby 200 | 201 | DEPENDENCIES 202 | bson_ext (>= 1.3.0) 203 | capybara (>= 0.4.1.2) 204 | cucumber-rails (>= 0.4.1) 205 | database_cleaner (>= 0.6.7) 206 | factory_girl_rails (>= 1.1.beta1) 207 | launchy (>= 0.4.0) 208 | mongoid (>= 2.0.1) 209 | mongoid-rspec (>= 1.4.2) 210 | omniauth (>= 0.2.4) 211 | rails (= 3.0.7) 212 | rspec-rails (>= 2.5.0) 213 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Rails3 Mongoid Omniauth 2 | ======================== 3 | 4 | 5 | ________________________ 6 | 7 | License 8 | 9 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. Rails 3 + Mongoid + Omniauth 2 | 3 | This is an example *Rails 3 application* that combines *OmniAuth* with *Mongoid*. It uses the "OmniAuth":https://github.com/intridea/omniauth gem to manage authentication using a service provider such as Twitter or Facebook. MongoDB is used as a datastore with the "Mongoid":http://mongoid.org/ gem for quick development without schemas or migrations. 4 | 5 | h2. The Project Has Moved! 6 | 7 | Please visit the project at its "new home":https://github.com/railsapps/rails3-mongoid-omniauth: 8 | 9 | h4. "Rails 3 + Mongoid + OmniAuth":https://github.com/railsapps/rails3-mongoid-omniauth 10 | 11 | h2. !http://twitter-badges.s3.amazonaws.com/t_logo-a.png(Follow on Twitter)!:http://www.twitter.com/rails_apps Follow on Twitter 12 | 13 | To keep up to date, follow the project on Twitter: 14 | "http://twitter.com/rails_apps":http://twitter.com/rails_apps 15 | 16 | Please tweet some praise if you like what you've found. 17 | 18 | h2. Credits 19 | 20 | Daniel Kehoe ("http://danielkehoe.com/":http://danielkehoe.com/) implemented the application and wrote the tutorial. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | require 'rake' 6 | 7 | Rails3MongoidOmniauth::Application.load_tasks 8 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | helper_method :current_user 4 | helper_method :user_signed_in? 5 | helper_method :correct_user? 6 | 7 | private 8 | def current_user 9 | begin 10 | @current_user ||= User.find(session[:user_id]) if session[:user_id] 11 | rescue Mongoid::Errors::DocumentNotFound 12 | nil 13 | end 14 | end 15 | 16 | def user_signed_in? 17 | return true if current_user 18 | end 19 | 20 | def correct_user? 21 | @user = User.find(params[:id]) 22 | unless current_user == @user 23 | redirect_to root_url, :alert => "Access denied." 24 | end 25 | end 26 | 27 | def authenticate_user! 28 | if !current_user 29 | redirect_to root_url, :alert => 'You need to sign in for access to this page.' 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def index 3 | @users = User.all 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class SessionsController < ApplicationController 2 | 3 | def new 4 | redirect_to '/auth/twitter' 5 | end 6 | 7 | 8 | def create 9 | auth = request.env["omniauth.auth"] 10 | user = User.where(:provider => auth['provider'], 11 | :uid => auth['uid']).first || User.create_with_omniauth(auth) 12 | session[:user_id] = user.id 13 | if !user.email 14 | redirect_to edit_user_path(user), :alert => "Please enter your email address." 15 | else 16 | redirect_to root_url, :notice => 'Signed in!' 17 | end 18 | 19 | end 20 | 21 | def destroy 22 | session[:user_id] = nil 23 | redirect_to root_url, :notice => 'Signed out!' 24 | end 25 | 26 | def failure 27 | redirect_to root_url, :alert => "Authentication error: #{params[:message].humanize}" 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | before_filter :authenticate_user! 3 | before_filter :correct_user? 4 | 5 | def edit 6 | @user = User.find(params[:id]) 7 | end 8 | 9 | def update 10 | @user = User.find(params[:id]) 11 | if @user.update_attributes(params[:user]) 12 | redirect_to @user 13 | else 14 | render :edit 15 | end 16 | end 17 | 18 | 19 | def show 20 | @user = User.find(params[:id]) 21 | 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User 2 | include Mongoid::Document 3 | field :provider, :type => String 4 | field :uid, :type => String 5 | field :name, :type => String 6 | field :email, :type => String 7 | attr_accessible :provider, :uid, :name, :email 8 | 9 | def self.create_with_omniauth(auth) 10 | begin 11 | create! do |user| 12 | user.provider = auth['provider'] 13 | user.uid = auth['uid'] 14 | if auth['user_info'] 15 | user.name = auth['user_info']['name'] if auth['user_info']['name'] # Twitter, Google, Yahoo, GitHub 16 | user.email = auth['user_info']['email'] if auth['user_info']['email'] # Google, Yahoo, GitHub 17 | end 18 | if auth['extra']['user_hash'] 19 | user.name = auth['extra']['user_hash']['name'] if auth['extra']['user_hash']['name'] # Facebook 20 | user.email = auth['extra']['user_hash']['email'] if auth['extra']['user_hash']['email'] # Facebook 21 | end 22 | end 23 | rescue Exception 24 | raise Exception, "cannot create user record" 25 | end 26 | end 27 | 28 | end 29 | 30 | -------------------------------------------------------------------------------- /app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 |

Home

2 | <% @users.each do |user| %> 3 |

User: <%=link_to user.name, user %>

4 | <% end %> 5 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Rails3MongoidOmniauth 5 | <%= stylesheet_link_tag :all %> 6 | <%= javascript_include_tag :defaults %> 7 | <%= csrf_meta_tag %> 8 | 9 | 10 | 13 | <%- flash.each do |name, msg| -%> 14 | <%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %> 15 | <%- end -%> 16 | 17 | <%= yield %> 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/views/shared/_navigation.html.erb: -------------------------------------------------------------------------------- 1 | <% if user_signed_in? %> 2 |
  • 3 | Logged in as <%= current_user.name %> 4 |
  • 5 |
  • 6 | <%= link_to('Logout', signout_path) %> 7 |
  • 8 | <% else %> 9 |
  • 10 | <%= link_to('Login', signin_path) %> 11 |
  • 12 | <% end %> 13 | -------------------------------------------------------------------------------- /app/views/users/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for(@user) do |f| %> 2 | <%= f.label :email %> 3 | <%= f.text_field :email %> 4 |
    5 | <%= f.submit "Sign in" %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /app/views/users/show.html.erb: -------------------------------------------------------------------------------- 1 |

    Users#show

    2 |

    Find me in app/views/users/show.html.erb

    3 |

    User: <%= @user.name %>

    4 |

    Email: <%= @user.email if @user.email %>

    5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails3MongoidOmniauth::Application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | # require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "active_resource/railtie" 8 | # require "rails/test_unit/railtie" 9 | 10 | # If you have a Gemfile, require the gems listed there, including any gems 11 | # you've limited to :test, :development, or :production. 12 | Bundler.require(:default, Rails.env) if defined?(Bundler) 13 | 14 | module Rails3MongoidOmniauth 15 | class Application < Rails::Application 16 | 17 | config.generators do |g| 18 | g.view_specs false 19 | g.helper_specs false 20 | end 21 | 22 | # Settings in config/environments/* take precedence over those specified here. 23 | # Application configuration should go into files in config/initializers 24 | # -- all .rb files in that directory are automatically loaded. 25 | 26 | # Custom directories with classes and modules you want to be autoloadable. 27 | # config.autoload_paths += %W(#{config.root}/extras) 28 | 29 | # Only load the plugins named here, in the order given (default is alphabetical). 30 | # :all can be used as a placeholder for all plugins not explicitly named. 31 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 32 | 33 | # Activate observers that should always be running. 34 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 35 | 36 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 37 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 38 | # config.time_zone = 'Central Time (US & Canada)' 39 | 40 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 41 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 42 | # config.i18n.default_locale = :de 43 | 44 | # JavaScript files you want as :defaults (application.js is always included). 45 | config.action_view.javascript_expansions[:defaults] = %w(jquery rails) 46 | 47 | # Configure the default encoding used in templates for Ruby 1.9. 48 | config.encoding = "utf-8" 49 | 50 | # Configure sensitive parameters which will be filtered from the log file. 51 | config.filter_parameters += [:password] 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /config/cucumber.yml: -------------------------------------------------------------------------------- 1 | <% 2 | rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" 3 | rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" 4 | std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" 5 | %> 6 | default: <%= std_opts %> features 7 | wip: --tags @wip:3 --wip features 8 | rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip 9 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Rails3MongoidOmniauth::Application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails3MongoidOmniauth::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the webserver when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_view.debug_rjs = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Don't care if the mailer can't send 18 | config.action_mailer.raise_delivery_errors = false 19 | 20 | # Print deprecation notices to the Rails logger 21 | config.active_support.deprecation = :log 22 | 23 | # Only use best-standards-support built into browsers 24 | config.action_dispatch.best_standards_support = :builtin 25 | end 26 | 27 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails3MongoidOmniauth::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The production environment is meant for finished, "live" apps. 5 | # Code is not reloaded between requests 6 | config.cache_classes = true 7 | 8 | # Full error reports are disabled and caching is turned on 9 | config.consider_all_requests_local = false 10 | config.action_controller.perform_caching = true 11 | 12 | # Specifies the header that your server uses for sending files 13 | config.action_dispatch.x_sendfile_header = "X-Sendfile" 14 | 15 | # For nginx: 16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' 17 | 18 | # If you have no front-end server that supports something like X-Sendfile, 19 | # just comment this out and Rails will serve the files 20 | 21 | # See everything in the log (default is :info) 22 | # config.log_level = :debug 23 | 24 | # Use a different logger for distributed setups 25 | # config.logger = SyslogLogger.new 26 | 27 | # Use a different cache store in production 28 | # config.cache_store = :mem_cache_store 29 | 30 | # Disable Rails's static asset server 31 | # In production, Apache or nginx will already do this 32 | config.serve_static_assets = false 33 | 34 | # Enable serving of images, stylesheets, and javascripts from an asset server 35 | # config.action_controller.asset_host = "http://assets.example.com" 36 | 37 | # Disable delivery errors, bad email addresses will be ignored 38 | # config.action_mailer.raise_delivery_errors = false 39 | 40 | # Enable threaded mode 41 | # config.threadsafe! 42 | 43 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 44 | # the I18n.default_locale when a translation can not be found) 45 | config.i18n.fallbacks = true 46 | 47 | # Send deprecation notices to registered listeners 48 | config.active_support.deprecation = :notify 49 | end 50 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails3MongoidOmniauth::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Log error messages when you accidentally call methods on nil. 11 | config.whiny_nils = true 12 | 13 | # Show full error reports and disable caching 14 | config.consider_all_requests_local = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Raise exceptions instead of rendering exception templates 18 | config.action_dispatch.show_exceptions = false 19 | 20 | # Disable request forgery protection in test environment 21 | config.action_controller.allow_forgery_protection = false 22 | 23 | # Tell Action Mailer not to deliver emails to the real world. 24 | # The :test delivery method accumulates sent emails in the 25 | # ActionMailer::Base.deliveries array. 26 | config.action_mailer.delivery_method = :test 27 | 28 | # Use SQL instead of Active Record's schema dumper when creating the test database. 29 | # This is necessary if your schema can't be completely dumped by the schema dumper, 30 | # like if you have constraints or database-specific column types 31 | # config.active_record.schema_format = :sql 32 | 33 | # Print deprecation notices to the stderr 34 | config.active_support.deprecation = :stderr 35 | end 36 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.generators do |g| 2 | end 3 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /config/initializers/omniauth.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.middleware.use OmniAuth::Builder do 2 | provider :twitter, 'KEY', 'SECRET' 3 | end 4 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | Rails3MongoidOmniauth::Application.config.secret_token = 'ce0c9e90903f6dea6f661a8ee8edbd5f4bee4428a4c9ba10e255efd63846b23908537c1a07903cb11ac8cd1fadaa639141450ae7880b22b9bffbbfeffb514d80' 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails3MongoidOmniauth::Application.config.session_store :cookie_store, :key => '_rails3-mongoid-omniauth_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # Rails3MongoidOmniauth::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /config/mongoid.yml: -------------------------------------------------------------------------------- 1 | defaults: &defaults 2 | host: localhost 3 | # slaves: 4 | # - host: slave1.local 5 | # port: 27018 6 | # - host: slave2.local 7 | # port: 27019 8 | 9 | development: 10 | <<: *defaults 11 | database: rails3_mongoid_omniauth_development 12 | 13 | test: 14 | <<: *defaults 15 | database: rails3_mongoid_omniauth_test 16 | 17 | # set these environment variables on your prod server 18 | production: 19 | host: <%= ENV['MONGOID_HOST'] %> 20 | port: <%= ENV['MONGOID_PORT'] %> 21 | username: <%= ENV['MONGOID_USERNAME'] %> 22 | password: <%= ENV['MONGOID_PASSWORD'] %> 23 | database: <%= ENV['MONGOID_DATABASE'] %> -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails3MongoidOmniauth::Application.routes.draw do 2 | #get \"users\/show\" 3 | 4 | root :to => "home#index" 5 | 6 | resources :users, :only => [ :show, :edit, :update ] 7 | 8 | match '/auth/:provider/callback' => 'sessions#create' 9 | 10 | match '/signin' => 'sessions#new', :as => :signin 11 | 12 | match '/signout' => 'sessions#destroy', :as => :signout 13 | 14 | match '/auth/failure' => 'sessions#failure' 15 | 16 | # The priority is based upon order of creation: 17 | # first created -> highest priority. 18 | 19 | # Sample of regular route: 20 | # match 'products/:id' => 'catalog#view' 21 | # Keep in mind you can assign values other than :controller and :action 22 | 23 | # Sample of named route: 24 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 25 | # This route can be invoked with purchase_url(:id => product.id) 26 | 27 | # Sample resource route (maps HTTP verbs to controller actions automatically): 28 | # resources :products 29 | 30 | # Sample resource route with options: 31 | # resources :products do 32 | # member do 33 | # get 'short' 34 | # post 'toggle' 35 | # end 36 | # 37 | # collection do 38 | # get 'sold' 39 | # end 40 | # end 41 | 42 | # Sample resource route with sub-resources: 43 | # resources :products do 44 | # resources :comments, :sales 45 | # resource :seller 46 | # end 47 | 48 | # Sample resource route with more complex sub-resources 49 | # resources :products do 50 | # resources :comments 51 | # resources :sales do 52 | # get 'recent', :on => :collection 53 | # end 54 | # end 55 | 56 | # Sample resource route within a namespace: 57 | # namespace :admin do 58 | # # Directs /admin/products/* to Admin::ProductsController 59 | # # (app/controllers/admin/products_controller.rb) 60 | # resources :products 61 | # end 62 | 63 | # You can have the root of your site routed with "root" 64 | # just remember to delete public/index.html. 65 | # root :to => "welcome#index" 66 | 67 | # See how all your routes lay out with "rake routes" 68 | 69 | # This is a legacy wild controller route that's not recommended for RESTful applications. 70 | # Note: This route will make all actions in every controller accessible via GET requests. 71 | # match ':controller(/:action(/:id(.:format)))' 72 | end 73 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) 7 | # Mayor.create(:name => 'Daley', :city => cities.first) 8 | puts 'EMPTY THE MONGODB DATABASE' 9 | Mongoid.master.collections.reject { |c| c.name =~ /^system/}.each(&:drop) 10 | -------------------------------------------------------------------------------- /features/step_definitions/web_steps.rb: -------------------------------------------------------------------------------- 1 | # TL;DR: YOU SHOULD DELETE THIS FILE 2 | # 3 | # This file was generated by Cucumber-Rails and is only here to get you a head start 4 | # These step definitions are thin wrappers around the Capybara/Webrat API that lets you 5 | # visit pages, interact with widgets and make assertions about page content. 6 | # 7 | # If you use these step definitions as basis for your features you will quickly end up 8 | # with features that are: 9 | # 10 | # * Hard to maintain 11 | # * Verbose to read 12 | # 13 | # A much better approach is to write your own higher level step definitions, following 14 | # the advice in the following blog posts: 15 | # 16 | # * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html 17 | # * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/ 18 | # * http://elabs.se/blog/15-you-re-cuking-it-wrong 19 | # 20 | 21 | 22 | require 'uri' 23 | require 'cgi' 24 | require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) 25 | require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors")) 26 | 27 | module WithinHelpers 28 | def with_scope(locator) 29 | locator ? within(*selector_for(locator)) { yield } : yield 30 | end 31 | end 32 | World(WithinHelpers) 33 | 34 | # Single-line step scoper 35 | When /^(.*) within ([^:]+)$/ do |step, parent| 36 | with_scope(parent) { When step } 37 | end 38 | 39 | # Multi-line step scoper 40 | When /^(.*) within ([^:]+):$/ do |step, parent, table_or_string| 41 | with_scope(parent) { When "#{step}:", table_or_string } 42 | end 43 | 44 | Given /^(?:|I )am on (.+)$/ do |page_name| 45 | visit path_to(page_name) 46 | end 47 | 48 | When /^(?:|I )go to (.+)$/ do |page_name| 49 | visit path_to(page_name) 50 | end 51 | 52 | When /^(?:|I )press "([^"]*)"$/ do |button| 53 | click_button(button) 54 | end 55 | 56 | When /^(?:|I )follow "([^"]*)"$/ do |link| 57 | click_link(link) 58 | end 59 | 60 | When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value| 61 | fill_in(field, :with => value) 62 | end 63 | 64 | When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field| 65 | fill_in(field, :with => value) 66 | end 67 | 68 | # Use this to fill in an entire form with data from a table. Example: 69 | # 70 | # When I fill in the following: 71 | # | Account Number | 5002 | 72 | # | Expiry date | 2009-11-01 | 73 | # | Note | Nice guy | 74 | # | Wants Email? | | 75 | # 76 | # TODO: Add support for checkbox, select og option 77 | # based on naming conventions. 78 | # 79 | When /^(?:|I )fill in the following:$/ do |fields| 80 | fields.rows_hash.each do |name, value| 81 | When %{I fill in "#{name}" with "#{value}"} 82 | end 83 | end 84 | 85 | When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field| 86 | select(value, :from => field) 87 | end 88 | 89 | When /^(?:|I )check "([^"]*)"$/ do |field| 90 | check(field) 91 | end 92 | 93 | When /^(?:|I )uncheck "([^"]*)"$/ do |field| 94 | uncheck(field) 95 | end 96 | 97 | When /^(?:|I )choose "([^"]*)"$/ do |field| 98 | choose(field) 99 | end 100 | 101 | When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field| 102 | attach_file(field, File.expand_path(path)) 103 | end 104 | 105 | Then /^(?:|I )should see "([^"]*)"$/ do |text| 106 | if page.respond_to? :should 107 | page.should have_content(text) 108 | else 109 | assert page.has_content?(text) 110 | end 111 | end 112 | 113 | Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp| 114 | regexp = Regexp.new(regexp) 115 | 116 | if page.respond_to? :should 117 | page.should have_xpath('//*', :text => regexp) 118 | else 119 | assert page.has_xpath?('//*', :text => regexp) 120 | end 121 | end 122 | 123 | Then /^(?:|I )should not see "([^"]*)"$/ do |text| 124 | if page.respond_to? :should 125 | page.should have_no_content(text) 126 | else 127 | assert page.has_no_content?(text) 128 | end 129 | end 130 | 131 | Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp| 132 | regexp = Regexp.new(regexp) 133 | 134 | if page.respond_to? :should 135 | page.should have_no_xpath('//*', :text => regexp) 136 | else 137 | assert page.has_no_xpath?('//*', :text => regexp) 138 | end 139 | end 140 | 141 | Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value| 142 | with_scope(parent) do 143 | field = find_field(field) 144 | field_value = (field.tag_name == 'textarea') ? field.text : field.value 145 | if field_value.respond_to? :should 146 | field_value.should =~ /#{value}/ 147 | else 148 | assert_match(/#{value}/, field_value) 149 | end 150 | end 151 | end 152 | 153 | Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value| 154 | with_scope(parent) do 155 | field = find_field(field) 156 | field_value = (field.tag_name == 'textarea') ? field.text : field.value 157 | if field_value.respond_to? :should_not 158 | field_value.should_not =~ /#{value}/ 159 | else 160 | assert_no_match(/#{value}/, field_value) 161 | end 162 | end 163 | end 164 | 165 | Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent| 166 | with_scope(parent) do 167 | field_checked = find_field(label)['checked'] 168 | if field_checked.respond_to? :should 169 | field_checked.should be_true 170 | else 171 | assert field_checked 172 | end 173 | end 174 | end 175 | 176 | Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent| 177 | with_scope(parent) do 178 | field_checked = find_field(label)['checked'] 179 | if field_checked.respond_to? :should 180 | field_checked.should be_false 181 | else 182 | assert !field_checked 183 | end 184 | end 185 | end 186 | 187 | Then /^(?:|I )should be on (.+)$/ do |page_name| 188 | current_path = URI.parse(current_url).path 189 | if current_path.respond_to? :should 190 | current_path.should == path_to(page_name) 191 | else 192 | assert_equal path_to(page_name), current_path 193 | end 194 | end 195 | 196 | Then /^(?:|I )should have the following query string:$/ do |expected_pairs| 197 | query = URI.parse(current_url).query 198 | actual_params = query ? CGI.parse(query) : {} 199 | expected_params = {} 200 | expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} 201 | 202 | if actual_params.respond_to? :should 203 | actual_params.should == expected_params 204 | else 205 | assert_equal expected_params, actual_params 206 | end 207 | end 208 | 209 | Then /^show me the page$/ do 210 | save_and_open_page 211 | end 212 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. 2 | # It is recommended to regenerate this file in the future when you upgrade to a 3 | # newer version of cucumber-rails. Consider adding your own code to a new file 4 | # instead of editing this one. Cucumber will automatically load all features/**/*.rb 5 | # files. 6 | 7 | require 'cucumber/rails' 8 | 9 | # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In 10 | # order to ease the transition to Capybara we set the default here. If you'd 11 | # prefer to use XPath just remove this line and adjust any selectors in your 12 | # steps to use the XPath syntax. 13 | Capybara.default_selector = :css 14 | 15 | # By default, any exception happening in your Rails application will bubble up 16 | # to Cucumber so that your scenario will fail. This is a different from how 17 | # your application behaves in the production environment, where an error page will 18 | # be rendered instead. 19 | # 20 | # Sometimes we want to override this default behaviour and allow Rails to rescue 21 | # exceptions and display an error page (just like when the app is running in production). 22 | # Typical scenarios where you want to do this is when you test your error pages. 23 | # There are two ways to allow Rails to rescue exceptions: 24 | # 25 | # 1) Tag your scenario (or feature) with @allow-rescue 26 | # 27 | # 2) Set the value below to true. Beware that doing this globally is not 28 | # recommended as it will mask a lot of errors for you! 29 | # 30 | ActionController::Base.allow_rescue = false 31 | 32 | # Remove/comment out the lines below if your app doesn't have a database. 33 | # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. 34 | begin 35 | DatabaseCleaner.orm = 'mongoid' 36 | DatabaseCleaner.strategy = :truncation 37 | rescue NameError 38 | raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." 39 | end 40 | 41 | -------------------------------------------------------------------------------- /features/support/paths.rb: -------------------------------------------------------------------------------- 1 | module NavigationHelpers 2 | # Maps a name to a path. Used by the 3 | # 4 | # When /^I go to (.+)$/ do |page_name| 5 | # 6 | # step definition in web_steps.rb 7 | # 8 | def path_to(page_name) 9 | case page_name 10 | 11 | when /the home\s?page/ 12 | '/' 13 | 14 | # Add more mappings here. 15 | # Here is an example that pulls values out of the Regexp: 16 | # 17 | # when /^(.*)'s profile page$/i 18 | # user_profile_path(User.find_by_login($1)) 19 | 20 | else 21 | begin 22 | page_name =~ /the (.*) page/ 23 | path_components = $1.split(/\s+/) 24 | self.send(path_components.push('path').join('_').to_sym) 25 | rescue Object => e 26 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" + 27 | "Now, go and add a mapping in #{__FILE__}" 28 | end 29 | end 30 | end 31 | end 32 | 33 | World(NavigationHelpers) 34 | -------------------------------------------------------------------------------- /features/support/selectors.rb: -------------------------------------------------------------------------------- 1 | module HtmlSelectorsHelpers 2 | # Maps a name to a selector. Used primarily by the 3 | # 4 | # When /^(.+) within (.+)$/ do |step, scope| 5 | # 6 | # step definitions in web_steps.rb 7 | # 8 | def selector_for(locator) 9 | case locator 10 | 11 | when /the page/ 12 | "html > body" 13 | 14 | # Add more mappings here. 15 | # Here is an example that pulls values out of the Regexp: 16 | # 17 | # when /the (notice|error|info) flash/ 18 | # ".flash.#{$1}" 19 | 20 | # You can also return an array to use a different selector 21 | # type, like: 22 | # 23 | # when /the header/ 24 | # [:xpath, "//header"] 25 | 26 | # This allows you to provide a quoted selector as the scope 27 | # for "within" steps as was previously the default for the 28 | # web steps: 29 | when /"(.+)"/ 30 | $1 31 | 32 | else 33 | raise "Can't find mapping from \"#{locator}\" to a selector.\n" + 34 | "Now, go and add a mapping in #{__FILE__}" 35 | end 36 | end 37 | end 38 | 39 | World(HtmlSelectorsHelpers) 40 | -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/cucumber.rake: -------------------------------------------------------------------------------- 1 | # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. 2 | # It is recommended to regenerate this file in the future when you upgrade to a 3 | # newer version of cucumber-rails. Consider adding your own code to a new file 4 | # instead of editing this one. Cucumber will automatically load all features/**/*.rb 5 | # files. 6 | 7 | 8 | unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks 9 | 10 | vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first 11 | $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? 12 | 13 | begin 14 | require 'cucumber/rake/task' 15 | 16 | namespace :cucumber do 17 | Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t| 18 | t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. 19 | t.fork = true # You may get faster startup if you set this to false 20 | t.profile = 'default' 21 | end 22 | 23 | Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t| 24 | t.binary = vendored_cucumber_bin 25 | t.fork = true # You may get faster startup if you set this to false 26 | t.profile = 'wip' 27 | end 28 | 29 | Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t| 30 | t.binary = vendored_cucumber_bin 31 | t.fork = true # You may get faster startup if you set this to false 32 | t.profile = 'rerun' 33 | end 34 | 35 | desc 'Run all features' 36 | task :all => [:ok, :wip] 37 | end 38 | desc 'Alias for cucumber:ok' 39 | task :cucumber => 'cucumber:ok' 40 | 41 | task :default => :cucumber 42 | 43 | task :features => :cucumber do 44 | STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" 45 | end 46 | 47 | # In case we don't have ActiveRecord, append a no-op task that we can depend upon. 48 | task 'db:test:prepare' do 49 | end 50 | rescue LoadError 51 | desc 'cucumber rake task not available (cucumber not installed)' 52 | task :cucumber do 53 | abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' 54 | end 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The page you were looking for doesn't exist.

    23 |

    You may have mistyped the address or the page may have moved.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    The change you wanted was rejected.

    23 |

    Maybe you tried to change something you didn't have access to.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
    22 |

    We're sorry, but something went wrong.

    23 |

    We've been notified about this issue and we'll take a look at it shortly.

    24 |
    25 | 26 | 27 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/public/favicon.ico -------------------------------------------------------------------------------- /public/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/public/javascripts/.gitkeep -------------------------------------------------------------------------------- /public/javascripts/application.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/public/javascripts/application.js -------------------------------------------------------------------------------- /public/javascripts/jquery.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery JavaScript Library v1.6 3 | * http://jquery.com/ 4 | * 5 | * Copyright 2011, John Resig 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | * 9 | * Includes Sizzle.js 10 | * http://sizzlejs.com/ 11 | * Copyright 2011, The Dojo Foundation 12 | * Released under the MIT, BSD, and GPL Licenses. 13 | * 14 | * Date: Mon May 2 13:50:00 2011 -0400 15 | */ 16 | (function(a,b){function cw(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function ct(a){if(!ch[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ci||(ci=c.createElement("iframe"),ci.frameBorder=ci.width=ci.height=0),c.body.appendChild(ci);if(!cj||!ci.createElement)cj=(ci.contentWindow||ci.contentDocument).document,cj.write("");b=cj.createElement(a),cj.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ci)}ch[a]=d}return ch[a]}function cs(a,b){var c={};f.each(cn.concat.apply([],cn.slice(0,b)),function(){c[this]=a});return c}function cr(){co=b}function cq(){setTimeout(cr,0);return co=f.now()}function cg(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cf(){try{return new a.XMLHttpRequest}catch(b){}}function b_(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){name="data-"+c.replace(j,"$1-$2").toLowerCase(),d=a.getAttribute(name);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(e){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?g=[null,a,null]:g=i.exec(a);if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
    a",b=a.getElementsByTagName("*"),d=a.getElementsByTagName("a")[0];if(!b||!b.length||!d)return{};e=c.createElement("select"),f=e.appendChild(c.createElement("option")),g=a.getElementsByTagName("input")[0],i={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.55$/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:g.value==="on",optSelected:f.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},g.checked=!0,i.noCloneChecked=g.cloneNode(!0).checked,e.disabled=!0,i.optDisabled=!f.disabled;try{delete a.test}catch(r){i.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function click(){i.noCloneEvent=!1,a.detachEvent("onclick",click)}),a.cloneNode(!0).fireEvent("onclick")),g=c.createElement("input"),g.value="t",g.setAttribute("type","radio"),i.radioValue=g.value==="t",g.setAttribute("checked","checked"),a.appendChild(g),j=c.createDocumentFragment(),j.appendChild(a.firstChild),i.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",k=c.createElement("body"),l={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(p in l)k.style[p]=l[p];k.appendChild(a),c.documentElement.appendChild(k),i.appendChecked=g.checked,i.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,i.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
    ",i.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
    t
    ",m=a.getElementsByTagName("td"),q=m[0].offsetHeight===0,m[0].style.display="",m[1].style.display="none",i.reliableHiddenOffsets=q&&m[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(h=c.createElement("div"),h.style.width="0",h.style.marginRight="0",a.appendChild(h),i.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(h,null).marginRight,10)||0)===0),k.innerHTML="",c.documentElement.removeChild(k);if(a.attachEvent)for(p in{submit:1,change:1,focusin:1})o="on"+p,q=o in a,q||(a.setAttribute(o,"return;"),q=typeof a[o]=="function"),i[p+"Bubbles"]=q;return i}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[c]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||"set"in c&&c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b=a.selectedIndex,c=[],d=a.options,e=a.type==="select-one";if(b<0)return null;for(var g=e?b:0,h=e?b+1:d.length;g=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex",readonly:"readOnly"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c]||(v&&(f.nodeName(a,"form")||u.test(c))?v:b);if(d!==b){if(d===null||d===!1&&!t.test(c)){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;d===!0&&!t.test(c)&&(d=c),a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.getAttribute("value");a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),f.support.getSetAttribute||(f.attrFix=f.extend(f.attrFix,{"for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder"}),v=f.attrHooks.name=f.attrHooks.value=f.valHooks.button={get:function(a,c){var d;if(c==="value"&&!f.nodeName(a,"button"))return a.getAttribute(c);d=a.getAttributeNode(c);return d&&d.specified?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=Object.prototype.hasOwnProperty,x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function J(a){var c=a.target,d,e;if(!!y.test(c.nodeName)&&!c.readOnly){d=f._data(c,"_change_data"),e=I(c),(a.type!=="focusout"||c.type!=="radio")&&f._data(c,"_change_data",e);if(d===b||e===d)return;if(d!=null||e)a.type="change",a.liveFired=b,f.event.trigger(a,arguments[1],c)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){return a.nodeName.toLowerCase()==="input"&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!be[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[];for(var i=0,j;(j=a[i])!=null;i++){typeof j=="number"&&(j+="");if(!j)continue;if(typeof j=="string")if(!ba.test(j))j=b.createTextNode(j);else{j=j.replace(Z,"<$1>");var k=($.exec(j)||["",""])[1].toLowerCase(),l=be[k]||be._default,m=l[0],n=b.createElement("div");n.innerHTML=l[1]+j+l[2];while(m--)n=n.lastChild;if(!f.support.tbody){var o=_.test(j),p=k==="table"&&!o?n.firstChild&&n.firstChild.childNodes:l[1]===""&&!o?n.childNodes:[];for(var q=p.length-1;q>=0;--q)f.nodeName(p[q],"tbody")&&!p[q].childNodes.length&&p[q].parentNode.removeChild(p[q])}!f.support.leadingWhitespace&&Y.test(j)&&n.insertBefore(b.createTextNode(Y.exec(j)[0]),n.firstChild),j=n.childNodes}var r;if(!f.support.appendChecked)if(j[0]&&typeof (r=j.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV;try{bU=e.href}catch(bW){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bX(bS),ajaxTransport:bX(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?b$(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b_(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bY(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bY(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bZ(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var ca=f.now(),cb=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+ca++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cb.test(b.url)||e&&cb.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cb,l),b.url===j&&(e&&(k=k.replace(cb,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cc=a.ActiveXObject?function(){for(var a in ce)ce[a](0,1)}:!1,cd=0,ce;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cf()||cg()}:cf,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cc&&delete ce[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cd,cc&&(ce||(ce={},f(a).unload(cc)),ce[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ch={},ci,cj,ck=/^(?:toggle|show|hide)$/,cl=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cm,cn=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],co,cp=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cs("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a=f.timers,b=a.length;while(b--)a[b]()||a.splice(b,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cm),cm=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cu=/^t(?:able|d|h)$/i,cv=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cw(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cu.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="
    ";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cv.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cv.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cw(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cw(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); -------------------------------------------------------------------------------- /public/javascripts/rails.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Unobtrusive scripting adapter for jQuery 3 | * 4 | * Requires jQuery 1.4.4 or later. 5 | * https://github.com/rails/jquery-ujs 6 | 7 | * Uploading file using rails.js 8 | * ============================= 9 | * 10 | * By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields 11 | * in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means. 12 | * 13 | * The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish. 14 | * 15 | * Ex: 16 | * $('form').live('ajax:aborted:file', function(event, elements){ 17 | * // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`. 18 | * // Returning false in this handler tells rails.js to disallow standard form submission 19 | * return false; 20 | * }); 21 | * 22 | * The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value. 23 | * 24 | * Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use 25 | * techniques like the iframe method to upload the file instead. 26 | * 27 | * Required fields in rails.js 28 | * =========================== 29 | * 30 | * If any blank required inputs (required="required") are detected in the remote form, the whole form submission 31 | * is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission. 32 | * 33 | * The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs. 34 | * 35 | * !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never 36 | * get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior. 37 | * 38 | * Ex: 39 | * $('form').live('ajax:aborted:required', function(event, elements){ 40 | * // Returning false in this handler tells rails.js to submit the form anyway. 41 | * // The blank required inputs are passed to this function in `elements`. 42 | * return ! confirm("Would you like to submit the form with missing info?"); 43 | * }); 44 | */ 45 | 46 | (function($) { 47 | // Shorthand to make it a little easier to call public rails functions from within rails.js 48 | var rails; 49 | 50 | $.rails = rails = { 51 | // Link elements bound by jquery-ujs 52 | linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]', 53 | 54 | // Form elements bound by jquery-ujs 55 | formSubmitSelector: 'form', 56 | 57 | // Form input elements bound by jquery-ujs 58 | formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])', 59 | 60 | // Form input elements disabled during form submission 61 | disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]', 62 | 63 | // Form input elements re-enabled after form submission 64 | enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled', 65 | 66 | // Form required input elements 67 | requiredInputSelector: 'input[name][required],textarea[name][required]', 68 | 69 | // Form file input elements 70 | fileInputSelector: 'input:file', 71 | 72 | // Make sure that every Ajax request sends the CSRF token 73 | CSRFProtection: function(xhr) { 74 | var token = $('meta[name="csrf-token"]').attr('content'); 75 | if (token) xhr.setRequestHeader('X-CSRF-Token', token); 76 | }, 77 | 78 | // Triggers an event on an element and returns false if the event result is false 79 | fire: function(obj, name, data) { 80 | var event = $.Event(name); 81 | obj.trigger(event, data); 82 | return event.result !== false; 83 | }, 84 | 85 | // Submits "remote" forms and links with ajax 86 | handleRemote: function(element) { 87 | var method, url, data, 88 | dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType); 89 | 90 | if (rails.fire(element, 'ajax:before')) { 91 | 92 | if (element.is('form')) { 93 | method = element.attr('method'); 94 | url = element.attr('action'); 95 | data = element.serializeArray(); 96 | // memoized value from clicked submit button 97 | var button = element.data('ujs:submit-button'); 98 | if (button) { 99 | data.push(button); 100 | element.data('ujs:submit-button', null); 101 | } 102 | } else { 103 | method = element.data('method'); 104 | url = element.attr('href'); 105 | data = null; 106 | } 107 | 108 | $.ajax({ 109 | url: url, type: method || 'GET', data: data, dataType: dataType, 110 | // stopping the "ajax:beforeSend" event will cancel the ajax request 111 | beforeSend: function(xhr, settings) { 112 | if (settings.dataType === undefined) { 113 | xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script); 114 | } 115 | return rails.fire(element, 'ajax:beforeSend', [xhr, settings]); 116 | }, 117 | success: function(data, status, xhr) { 118 | element.trigger('ajax:success', [data, status, xhr]); 119 | }, 120 | complete: function(xhr, status) { 121 | element.trigger('ajax:complete', [xhr, status]); 122 | }, 123 | error: function(xhr, status, error) { 124 | element.trigger('ajax:error', [xhr, status, error]); 125 | } 126 | }); 127 | } 128 | }, 129 | 130 | // Handles "data-method" on links such as: 131 | // Delete 132 | handleMethod: function(link) { 133 | var href = link.attr('href'), 134 | method = link.data('method'), 135 | csrf_token = $('meta[name=csrf-token]').attr('content'), 136 | csrf_param = $('meta[name=csrf-param]').attr('content'), 137 | form = $('
    '), 138 | metadata_input = ''; 139 | 140 | if (csrf_param !== undefined && csrf_token !== undefined) { 141 | metadata_input += ''; 142 | } 143 | 144 | form.hide().append(metadata_input).appendTo('body'); 145 | form.submit(); 146 | }, 147 | 148 | /* Disables form elements: 149 | - Caches element value in 'ujs:enable-with' data store 150 | - Replaces element text with value of 'data-disable-with' attribute 151 | - Adds disabled=disabled attribute 152 | */ 153 | disableFormElements: function(form) { 154 | form.find(rails.disableSelector).each(function() { 155 | var element = $(this), method = element.is('button') ? 'html' : 'val'; 156 | element.data('ujs:enable-with', element[method]()); 157 | element[method](element.data('disable-with')); 158 | element.attr('disabled', 'disabled'); 159 | }); 160 | }, 161 | 162 | /* Re-enables disabled form elements: 163 | - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`) 164 | - Removes disabled attribute 165 | */ 166 | enableFormElements: function(form) { 167 | form.find(rails.enableSelector).each(function() { 168 | var element = $(this), method = element.is('button') ? 'html' : 'val'; 169 | if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with')); 170 | element.removeAttr('disabled'); 171 | }); 172 | }, 173 | 174 | // If message provided in 'data-confirm' attribute, fires `confirm` event and returns result of confirm dialog. 175 | // Attaching a handler to the element's `confirm` event that returns false cancels the confirm dialog. 176 | allowAction: function(element) { 177 | var message = element.data('confirm'); 178 | return !message || (rails.fire(element, 'confirm') && confirm(message)); 179 | }, 180 | 181 | // Helper function which checks for blank inputs in a form that match the specified CSS selector 182 | blankInputs: function(form, specifiedSelector, nonBlank) { 183 | var inputs = $(), input, 184 | selector = specifiedSelector || 'input,textarea'; 185 | form.find(selector).each(function() { 186 | input = $(this); 187 | // Collect non-blank inputs if nonBlank option is true, otherwise, collect blank inputs 188 | if (nonBlank ? input.val() : !input.val()) { 189 | inputs = inputs.add(input); 190 | } 191 | }); 192 | return inputs.length ? inputs : false; 193 | }, 194 | 195 | // Helper function which checks for non-blank inputs in a form that match the specified CSS selector 196 | nonBlankInputs: function(form, specifiedSelector) { 197 | return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank 198 | }, 199 | 200 | // Helper function, needed to provide consistent behavior in IE 201 | stopEverything: function(e) { 202 | e.stopImmediatePropagation(); 203 | return false; 204 | }, 205 | 206 | // find all the submit events directly bound to the form and 207 | // manually invoke them. If anyone returns false then stop the loop 208 | callFormSubmitBindings: function(form) { 209 | var events = form.data('events'), continuePropagation = true; 210 | if (events !== undefined && events['submit'] !== undefined) { 211 | $.each(events['submit'], function(i, obj){ 212 | if (typeof obj.handler === 'function') return continuePropagation = obj.handler(obj.data); 213 | }); 214 | } 215 | return continuePropagation; 216 | } 217 | }; 218 | 219 | // ajaxPrefilter is a jQuery 1.5 feature 220 | if ('ajaxPrefilter' in $) { 221 | $.ajaxPrefilter(function(options, originalOptions, xhr){ rails.CSRFProtection(xhr); }); 222 | } else { 223 | $(document).ajaxSend(function(e, xhr){ rails.CSRFProtection(xhr); }); 224 | } 225 | 226 | $(rails.linkClickSelector).live('click.rails', function(e) { 227 | var link = $(this); 228 | if (!rails.allowAction(link)) return rails.stopEverything(e); 229 | 230 | if (link.data('remote') !== undefined) { 231 | rails.handleRemote(link); 232 | return false; 233 | } else if (link.data('method')) { 234 | rails.handleMethod(link); 235 | return false; 236 | } 237 | }); 238 | 239 | $(rails.formSubmitSelector).live('submit.rails', function(e) { 240 | var form = $(this), 241 | remote = form.data('remote') !== undefined, 242 | blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector), 243 | nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector); 244 | 245 | if (!rails.allowAction(form)) return rails.stopEverything(e); 246 | 247 | // skip other logic when required values are missing or file upload is present 248 | if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) { 249 | return !remote; 250 | } 251 | 252 | if (remote) { 253 | if (nonBlankFileInputs) { 254 | return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]); 255 | } 256 | 257 | // If browser does not support submit bubbling, then this live-binding will be called before direct 258 | // bindings. Therefore, we should directly call any direct bindings before remotely submitting form. 259 | if (!$.support.submitBubbles && rails.callFormSubmitBindings(form) === false) return rails.stopEverything(e); 260 | 261 | rails.handleRemote(form); 262 | return false; 263 | } else { 264 | // slight timeout so that the submit button gets properly serialized 265 | setTimeout(function(){ rails.disableFormElements(form); }, 13); 266 | } 267 | }); 268 | 269 | $(rails.formInputClickSelector).live('click.rails', function(event) { 270 | var button = $(this); 271 | 272 | if (!rails.allowAction(button)) return rails.stopEverything(event); 273 | 274 | // register the pressed submit button 275 | var name = button.attr('name'), 276 | data = name ? {name:name, value:button.val()} : null; 277 | 278 | button.closest('form').data('ujs:submit-button', data); 279 | }); 280 | 281 | $(rails.formSubmitSelector).live('ajax:beforeSend.rails', function(event) { 282 | if (this == event.target) rails.disableFormElements($(this)); 283 | }); 284 | 285 | $(rails.formSubmitSelector).live('ajax:complete.rails', function(event) { 286 | if (this == event.target) rails.enableFormElements($(this)); 287 | }); 288 | 289 | })( jQuery ); 290 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | User-Agent: * 5 | Disallow: / 6 | -------------------------------------------------------------------------------- /public/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/public/stylesheets/.gitkeep -------------------------------------------------------------------------------- /public/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | ul.hmenu { 2 | list-style: none; 3 | margin: 0 0 2em; 4 | padding: 0; 5 | } 6 | ul.hmenu li { 7 | display: inline; 8 | } 9 | #flash_notice, #flash_alert { 10 | padding: 5px 8px; 11 | margin: 10px 0; 12 | } 13 | #flash_notice { 14 | background-color: #CFC; 15 | border: solid 1px #6C6; 16 | } 17 | #flash_alert { 18 | background-color: #FCC; 19 | border: solid 1px #C66; 20 | } 21 | -------------------------------------------------------------------------------- /script/cucumber: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first 4 | if vendored_cucumber_bin 5 | load File.expand_path(vendored_cucumber_bin) 6 | else 7 | require 'rubygems' unless ENV['NO_RUBYGEMS'] 8 | require 'cucumber' 9 | load Cucumber::BINARY 10 | end 11 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /spec/controllers/home_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe HomeController do 4 | 5 | describe "GET 'index'" do 6 | it "should be successful" do 7 | get 'index' 8 | response.should be_success 9 | end 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/controllers/users_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe UsersController do 4 | 5 | describe "GET 'show'" do 6 | it "should be successful" do 7 | get 'show' 8 | response.should be_success 9 | end 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/models/user_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe User do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] ||= 'test' 3 | require File.expand_path("../../config/environment", __FILE__) 4 | require 'rspec/rails' 5 | 6 | # Requires supporting ruby files with custom matchers and macros, etc, 7 | # in spec/support/ and its subdirectories. 8 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 9 | 10 | RSpec.configure do |config| 11 | # == Mock Framework 12 | # 13 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 14 | # 15 | # config.mock_with :mocha 16 | # config.mock_with :flexmock 17 | # config.mock_with :rr 18 | config.mock_with :rspec 19 | 20 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 21 | # config.fixture_path = "#{::Rails.root}/spec/fixtures" 22 | 23 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 24 | # examples within a transaction, remove the following line or assign false 25 | # instead of true. 26 | # config.use_transactional_fixtures = true 27 | 28 | # Clean up the database 29 | require 'database_cleaner' 30 | config.before(:suite) do 31 | DatabaseCleaner.strategy = :truncation 32 | DatabaseCleaner.orm = "mongoid" 33 | end 34 | 35 | config.before(:each) do 36 | DatabaseCleaner.clean 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /spec/support/mongoid.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include Mongoid::Matchers 3 | end 4 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortuity/rails3-mongoid-omniauth/21abd743cf5b0546987c5c2da2670b0b5c0f0c03/vendor/plugins/.gitkeep --------------------------------------------------------------------------------