Commit 3fe07eef9c4f77fe2c61ba919205c4cfeb8621e9

Authored by Vasiliy Ermolovich
2 parents 08648212 fe44ce0a
Exists in master and in 1 other branch production

Merge remote-tracking branch 'updates/master' into github

Conflicts:
	Gemfile
	Gemfile.lock
	app/assets/javascripts/errbit.js
	app/assets/stylesheets/errbit.css
	app/models/user.rb
	config/initializers/_load_config.rb
Showing 181 changed files with 2733 additions and 2523 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 181 files displayed.

Gemfile
... ... @@ -3,20 +3,25 @@ source 'http://rubygems.org'
3 3 gem 'rails', '~> 3.2.0'
4 4  
5 5 gem 'nokogiri'
6   -gem 'mongoid', '~> 2.2.2'
  6 +gem 'mongoid', '~> 2.4.10'
7 7  
8 8 gem 'haml'
9 9 gem 'htmlentities', "~> 4.3.0"
10   -gem 'devise', '~> 1.4.0'
  10 +
  11 +gem 'devise', '~> 1.5.3'
  12 +
11 13 gem 'omniauth-github'
12 14 gem 'oa-core'
  15 +
13 16 gem 'lighthouse-api'
14 17 gem 'oruen_redmine_client', :require => 'redmine_client'
15 18 gem 'mongoid_rails_migrations'
16 19 gem 'useragent', '~> 0.3.1'
17 20 gem 'pivotal-tracker'
18 21 gem 'ruby-fogbugz', :require => 'fogbugz'
19   -gem 'octokit'
  22 +
  23 +gem 'octokit', '~> 1.0.0'
  24 +
20 25 gem 'inherited_resources'
21 26 gem 'SystemTimer', :platform => :ruby_18
22 27 gem 'hoptoad_notifier', "~> 2.4"
... ... @@ -24,6 +29,7 @@ gem 'actionmailer_inline_css', "~> 1.3.0"
24 29 gem 'kaminari'
25 30 gem 'rack-ssl-enforcer'
26 31 gem 'fabrication', "~> 1.3.0" # Both for tests, and loading demo data
  32 +gem 'rails_autolink', '~> 1.0.9'
27 33  
28 34 platform :ruby do
29 35 gem 'mongo', '= 1.3.1'
... ... @@ -32,13 +38,14 @@ platform :ruby do
32 38 end
33 39  
34 40 gem 'ri_cal'
  41 +gem 'yajl-ruby'
35 42  
36 43 group :development, :test do
37 44 gem 'rspec-rails', '~> 2.6'
38 45 gem 'webmock', :require => false
39   - unless ENV['TRAVIS']
  46 + unless ENV["CI"]
40 47 gem 'ruby-debug', :platform => :mri_18
41   - # gem 'ruby-debug19', :platform => :mri_19, :require => 'ruby-debug'
  48 + gem (RUBY_VERSION == "1.9.2" ? 'ruby-debug19' : 'debugger'), :platform => :mri_19
42 49 end
43 50 # gem 'rpm_contrib', :git => "git://github.com/bensymonds/rpm_contrib.git", :branch => "mongo-1.4.0_update"
44 51 end
... ... @@ -55,3 +62,13 @@ group :heroku do
55 62 gem 'unicorn'
56 63 end
57 64  
  65 +# Use thin for development
  66 +gem 'thin', :group => :development, :platform => :ruby
  67 +
  68 +# Gems used only for assets and not required
  69 +# in production environments by default.
  70 +group :assets do
  71 + gem 'execjs'
  72 + gem 'therubyracer', :platform => :ruby # C Ruby (MRI) or Rubinius, but NOT Windows
  73 + gem 'uglifier', '>= 1.0.3'
  74 +end
... ...
Gemfile.lock
... ... @@ -53,16 +53,27 @@ GEM
53 53 css_parser (1.2.6)
54 54 addressable
55 55 rdoc
  56 + daemons (1.1.8)
56 57 database_cleaner (0.6.7)
57   - devise (1.4.9)
  58 + debugger (1.1.3)
  59 + columnize (>= 0.3.1)
  60 + debugger-linecache (~> 1.1.1)
  61 + debugger-ruby_core_source (~> 1.1.2)
  62 + debugger-linecache (1.1.1)
  63 + debugger-ruby_core_source (>= 1.1.1)
  64 + debugger-ruby_core_source (1.1.2)
  65 + devise (1.5.3)
58 66 bcrypt-ruby (~> 3.0)
59 67 orm_adapter (~> 0.0.3)
60   - warden (~> 1.0.3)
  68 + warden (~> 1.1)
61 69 diff-lcs (1.1.3)
62 70 email_spec (1.2.1)
63 71 mail (~> 2.2)
64 72 rspec (~> 2.0)
65 73 erubis (2.7.0)
  74 + eventmachine (0.12.10)
  75 + execjs (1.4.0)
  76 + multi_json (~> 1.0)
66 77 fabrication (1.3.2)
67 78 faraday (0.7.6)
68 79 addressable (~> 2.2)
... ... @@ -86,7 +97,7 @@ GEM
86 97 has_scope (~> 0.5.0)
87 98 responders (~> 0.6)
88 99 journey (1.0.3)
89   - json (1.7.1)
  100 + json (1.7.3)
90 101 kaminari (0.13.0)
91 102 actionpack (>= 3.0.0)
92 103 activesupport (>= 3.0.0)
... ... @@ -94,6 +105,7 @@ GEM
94 105 kgio (2.7.4)
95 106 launchy (2.1.0)
96 107 addressable (~> 2.2.6)
  108 + libv8 (3.3.10.4)
97 109 libwebsocket (0.1.3)
98 110 addressable
99 111 libxml-ruby (2.3.2)
... ... @@ -109,8 +121,8 @@ GEM
109 121 mime-types (1.18)
110 122 mongo (1.3.1)
111 123 bson (>= 1.3.1)
112   - mongoid (2.2.5)
113   - activemodel (~> 3.0)
  124 + mongoid (2.4.10)
  125 + activemodel (~> 3.1)
114 126 mongo (~> 1.3)
115 127 tzinfo (~> 0.3.22)
116 128 mongoid_rails_migrations (0.0.14)
... ... @@ -118,9 +130,9 @@ GEM
118 130 bundler (>= 1.0.0)
119 131 rails (>= 3.0.0)
120 132 railties (>= 3.0.0)
121   - multi_json (1.0.4)
  133 + multi_json (1.1.0)
122 134 multipart-post (1.1.5)
123   - nokogiri (1.5.2)
  135 + nokogiri (1.5.0)
124 136 oa-core (0.3.2)
125 137 oauth2 (0.5.2)
126 138 faraday (~> 0.7)
... ... @@ -172,6 +184,8 @@ GEM
172 184 activesupport (= 3.2.3)
173 185 bundler (~> 1.0)
174 186 railties (= 3.2.3)
  187 + rails_autolink (1.0.9)
  188 + rails (~> 3.1)
175 189 railties (3.2.3)
176 190 actionpack (= 3.2.3)
177 191 activesupport (= 3.2.3)
... ... @@ -220,24 +234,34 @@ GEM
220 234 hike (~> 1.2)
221 235 rack (~> 1.0)
222 236 tilt (~> 1.1, != 1.3.0)
  237 + therubyracer (0.10.1)
  238 + libv8 (~> 3.3.10)
  239 + thin (1.3.1)
  240 + daemons (>= 1.0.9)
  241 + eventmachine (>= 0.12.6)
  242 + rack (>= 1.0.0)
223 243 thor (0.14.6)
224 244 tilt (1.3.3)
225 245 treetop (1.4.10)
226 246 polyglot
227 247 polyglot (>= 0.3.1)
228 248 tzinfo (0.3.33)
  249 + uglifier (1.2.4)
  250 + execjs (>= 0.3.0)
  251 + multi_json (>= 1.0.2)
229 252 unicorn (4.3.1)
230 253 kgio (~> 2.6)
231 254 rack
232 255 raindrops (~> 0.7)
233 256 useragent (0.3.2)
234   - warden (1.0.6)
  257 + warden (1.2.0)
235 258 rack (>= 1.0)
236 259 webmock (1.8.6)
237 260 addressable (>= 2.2.7)
238 261 crack (>= 0.1.7)
239 262 xpath (0.1.4)
240 263 nokogiri (~> 1.3)
  264 + yajl-ruby (1.1.0)
241 265  
242 266 PLATFORMS
243 267 ruby
... ... @@ -249,8 +273,10 @@ DEPENDENCIES
249 273 bson_ext (= 1.3.1)
250 274 capybara
251 275 database_cleaner (~> 0.6.0)
252   - devise (~> 1.4.0)
  276 + debugger
  277 + devise (~> 1.5.3)
253 278 email_spec
  279 + execjs
254 280 fabrication (~> 1.3.0)
255 281 haml
256 282 hoptoad_notifier (~> 2.4)
... ... @@ -260,21 +286,26 @@ DEPENDENCIES
260 286 launchy
261 287 lighthouse-api
262 288 mongo (= 1.3.1)
263   - mongoid (~> 2.2.2)
  289 + mongoid (~> 2.4.10)
264 290 mongoid_rails_migrations
265 291 nokogiri
266 292 oa-core
267   - octokit
  293 + octokit (~> 1.0.0)
268 294 omniauth-github
269 295 oruen_redmine_client
270 296 pivotal-tracker
271 297 rack-ssl-enforcer
272 298 rails (~> 3.2.0)
  299 + rails_autolink (~> 1.0.9)
273 300 ri_cal
274 301 rspec (~> 2.6)
275 302 rspec-rails (~> 2.6)
276 303 ruby-debug
277 304 ruby-fogbugz
  305 + therubyracer
  306 + thin
  307 + uglifier (>= 1.0.3)
278 308 unicorn
279 309 useragent (~> 0.3.1)
280 310 webmock
  311 + yajl-ruby
... ...
README.md
1   -Errbit [![TravisCI](http://travis-ci.org/errbit/errbit.png?branch=master)](http://travis-ci.org/errbit/errbit)
2   -======
  1 +# Errbit [![TravisCI][travis-img-url]][travis-ci-url]
  2 +
  3 +[travis-img-url]: https://secure.travis-ci.org/errbit/errbit.png?branch=master
  4 +[travis-ci-url]: http://travis-ci.org/errbit/errbit
  5 +
  6 +### The open source, self-hosted error catcher
3 7  
4   -**The open source self-hosted error catcher**
5 8  
6 9 Errbit is a tool for collecting and managing errors from other applications.
7 10 It is [Airbrake](http://airbrakeapp.com) (formerly known as Hoptoad) API compliant,
8   -so if you are already using Airbrake, you can just point hoptoad_notifier at your Errbit server.
  11 +so if you are already using Airbrake, you can just point the `airbrake` gem to your Errbit server.
  12 +
  13 +
  14 +<table>
  15 + <tr>
  16 + <td align="center">
  17 + <a href="http://errbit.github.com/errbit/images/apps.png" target="_blank" title="Apps">
  18 + <img src="http://errbit.github.com/errbit/images/apps_thumb.png" alt="Apps">
  19 + </a>
  20 + <br />
  21 + <em>Apps</em>
  22 + </td>
  23 + <td align="center">
  24 + <a href="http://errbit.github.com/errbit/images/app_errors.png" target="_blank" title="Errors">
  25 + <img src="http://errbit.github.com/errbit/images/app_errors_thumb.png" alt="Errors">
  26 + </a>
  27 + <br />
  28 + <em>Errors</em>
  29 + </td>
  30 + <td align="center">
  31 + <a href="http://errbit.github.com/errbit/images/error_summary.png" target="_blank" title="Error Summary">
  32 + <img src="http://errbit.github.com/errbit/images/error_summary_thumb.png" alt="Error Summary">
  33 + </a>
  34 + <br />
  35 + <em>Error Summary</em>
  36 + </td>
  37 + <td align="center">
  38 + <a href="http://errbit.github.com/errbit/images/error_backtrace.png" target="_blank" title="Error Backtraces">
  39 + <img src="http://errbit.github.com/errbit/images/error_backtrace_thumb.png" alt="Error Backtraces">
  40 + </a>
  41 + <br />
  42 + <em>Error Backtraces</em>
  43 + </td>
  44 + </tr>
  45 +</table>
  46 +
9 47  
10 48 Errbit may be a good fit for you if:
11 49  
... ... @@ -170,6 +208,29 @@ rake db:migrate
170 208 If we change the way that data is stored, this will run any migrations to bring your database up to date.
171 209  
172 210  
  211 +User information in error reports
  212 +-----------------------------
  213 +
  214 +Errbit can now display information about the user who experienced an error.
  215 +This gives you the ability to ask the user for more information,
  216 +and let them know when you've fixed the bug.
  217 +
  218 +If you would like to include information about the current user in your error reports,
  219 +you can replace the `airbrake` gem in your Gemfile with `airbrake_user_attributes`,
  220 +which wraps the `airbrake` gem and injects user information.
  221 +It will inject information about the current user into the error report
  222 +if your Rails app's controller responds to a `#current_user` method.
  223 +The user's attributes are filtered to remove authentication fields.
  224 +
  225 +If user information is received with an error report,
  226 +it will be displayed under the *User Details* tab:
  227 +
  228 +
  229 +![User details tab](http://errbit.github.com/errbit/images/error_user_information.png)
  230 +
  231 +(This tab will be hidden if no user information is available.)
  232 +
  233 +
173 234 Issue Trackers
174 235 --------------
175 236  
... ... @@ -200,8 +261,8 @@ Issue Trackers
200 261 **Github Issues Integration**
201 262  
202 263 * For 'Account/Repository', the account will either be a username or organization. i.e. **errbit/errbit**
203   -* If you are logged in on [Github](https://github.com), you can find your **API Token** on this page: [https://github.com/account/admin](https://github.com/account/admin).
204   -* You will also need to provide the username that your API Token is connected to.
  264 +* You will also need to provide your username and password for your Github account.
  265 + * (We'd really appreciate it if you wanted to help us implement OAuth instead!)
205 266  
206 267  
207 268 What if Errbit has an error?
... ...
Rakefile
... ... @@ -7,7 +7,7 @@ require &#39;bundler&#39;
7 7  
8 8 Errbit::Application.load_tasks
9 9  
10   -Rake::Task[:default].clear
  10 +Rake::Task[:default].clear if Rake::Task.task_defined?(:default)
11 11  
12 12 namespace :spec do
13 13 desc "Preparing test env"
... ...
app/assets/images/alerts/help.gif 0 → 100755

1.54 KB

app/assets/images/alerts/important.gif 0 → 100755

1.46 KB

app/assets/images/alerts/info.gif 0 → 100755

1.45 KB

app/assets/images/alerts/title.gif 0 → 100755

317 Bytes

app/assets/images/fogbugz_create.png 0 → 100644

4.78 KB

app/assets/images/fogbugz_goto.png 0 → 100644

4.78 KB

app/assets/images/fogbugz_inactive.png 0 → 100644

4.58 KB

app/assets/images/github_create.png 0 → 100644

2.3 KB

app/assets/images/github_goto.png 0 → 100644

2.3 KB

app/assets/images/github_inactive.png 0 → 100644

2.03 KB

app/assets/images/lighthouseapp_create.png 0 → 100644

1.57 KB

app/assets/images/lighthouseapp_goto.png 0 → 100644

1.61 KB

app/assets/images/lighthouseapp_inactive.png 0 → 100644

1.57 KB

app/assets/images/loader.gif 0 → 100644

1.7 KB

app/assets/images/mingle_create.png 0 → 100644

2.41 KB

app/assets/images/mingle_goto.png 0 → 100644

2.41 KB

app/assets/images/mingle_inactive.png 0 → 100644

1.96 KB

app/assets/images/none_create.png 0 → 100644

799 Bytes

app/assets/images/none_inactive.png 0 → 100644

818 Bytes

app/assets/images/pivotal_create.png 0 → 100644

1.5 KB

app/assets/images/pivotal_goto.png 0 → 100644

1.52 KB

app/assets/images/pivotal_inactive.png 0 → 100644

1.56 KB

app/assets/images/redmine_create.png 0 → 100644

1.47 KB

app/assets/images/redmine_goto.png 0 → 100644

1.52 KB

app/assets/images/redmine_inactive.png 0 → 100644

1.52 KB

app/assets/images/thumbs-up.png 0 → 100644

1.42 KB

app/assets/javascripts/.gitkeep 0 → 100644
app/assets/javascripts/application.js.erb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +//= require jquery
  2 +//= require underscore-1.1.6
  3 +//= require rails
  4 +//= require form
  5 +//= require jquery.pjax
  6 +//= require jquery.alerts
  7 +//= require rails.alerts
  8 +//= require errbit
  9 +//= require_self
  10 +
  11 +// Allow any gems named 'errbit_*' to require their own assets
  12 +<% Gem.loaded_specs.keys.grep(/^errbit_/).each do |plugin|
  13 + require_asset(plugin) rescue Sprockets::FileNotFound
  14 +end %>
... ...
app/assets/javascripts/apps.show.js 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +$(function() {
  2 + $("#watchers_toggle").click(function() {
  3 + $("#watchers_div").slideToggle("slow");
  4 + });
  5 + $("#repository_toggle").click(function() {
  6 + $("#repository_div").slideToggle("slow");
  7 + });
  8 + $("#deploys_toggle").click(function() {
  9 + $("#deploys_div").slideToggle("slow");
  10 + });
  11 +});
... ...
app/assets/javascripts/errbit.js 0 → 100644
... ... @@ -0,0 +1,134 @@
  1 +// App JS
  2 +
  3 +$(function() {
  4 +
  5 + var currentTab = "summary";
  6 +
  7 + function init() {
  8 +
  9 + activateTabbedPanels();
  10 +
  11 + activateSelectableRows();
  12 +
  13 + toggleProblemsCheckboxes();
  14 +
  15 + bindRequiredPasswordMarks();
  16 +
  17 + $('#watcher_name').live("click", function() {
  18 + $(this).closest('form').find('.show').removeClass('show');
  19 + $('#app_watchers_attributes_0_user_id').addClass('show');
  20 + });
  21 +
  22 + $('#watcher_email').live("click", function() {
  23 + $(this).closest('form').find('.show').removeClass('show');
  24 + $('#app_watchers_attributes_0_email').addClass('show');
  25 + });
  26 +
  27 + $('a.copy_config').live("click", function() {
  28 + $('select.choose_other_app').show().focus();
  29 + });
  30 +
  31 + $('select.choose_other_app').live("change", function() {
  32 + var loc = window.location;
  33 + window.location.href = loc.protocol + "//" + loc.host + loc.pathname +
  34 + "?copy_attributes_from=" + $(this).val();
  35 + });
  36 +
  37 + $('input[type=submit][data-action]').click(function() {
  38 + $(this).closest('form').attr('action', $(this).attr('data-action'));
  39 + });
  40 +
  41 + $('.notice-pagination').each(function() {
  42 + $('.notice-pagination a').pjax('#content', { timeout: 2000});
  43 + $('#content').bind('pjax:start', function() {
  44 + $('.notice-pagination-loader').css("visibility", "visible");
  45 + currentTab = $('.tab-bar ul li a.button.active').attr('rel');
  46 + });
  47 +
  48 + $('#content').bind('pjax:end', function() {
  49 + activateTabbedPanels();
  50 + });
  51 + });
  52 + }
  53 +
  54 + function activateTabbedPanels() {
  55 + $('.tab-bar a').each(function(){
  56 + var tab = $(this);
  57 + var panel = $('#'+tab.attr('rel'));
  58 + panel.addClass('panel');
  59 + panel.find('h3').hide();
  60 + });
  61 +
  62 + $('.tab-bar a').click(function(){
  63 + activateTab($(this));
  64 + return(false);
  65 + });
  66 + activateTab($('.tab-bar ul li a.button[rel=' + currentTab + ']'));
  67 + }
  68 +
  69 + function activateTab(tab) {
  70 + tab = $(tab);
  71 + var panel = $('#'+tab.attr('rel'));
  72 +
  73 + tab.closest('.tab-bar').find('a.active').removeClass('active');
  74 + tab.addClass('active');
  75 +
  76 + // If clicking into 'backtrace' tab, hide external backtrace
  77 + if (tab.attr('rel') == "backtrace") { hide_external_backtrace(); }
  78 +
  79 + $('.panel').hide();
  80 + panel.show();
  81 + }
  82 +
  83 + function toggleProblemsCheckboxes() {
  84 + var checkboxToggler = $('#toggle_problems_checkboxes');
  85 +
  86 + checkboxToggler.live("click", function() {
  87 + $('input[name^="problems"]').each(function() {
  88 + this.checked = checkboxToggler.get(0).checked;
  89 + });
  90 + });
  91 + }
  92 +
  93 + function activateSelectableRows() {
  94 + $('.selectable tr').click(function(event) {
  95 + if(!_.include(['A', 'INPUT', 'BUTTON', 'TEXTAREA'], event.target.nodeName)) {
  96 + var checkbox = $(this).find('input[name="problems[]"]');
  97 + checkbox.attr('checked', !checkbox.is(':checked'));
  98 + }
  99 + });
  100 + }
  101 +
  102 + function bindRequiredPasswordMarks() {
  103 + $('#user_github_login').keyup(function(event) {
  104 + toggleRequiredPasswordMarks(this)
  105 + });
  106 + }
  107 +
  108 + function toggleRequiredPasswordMarks(input) {
  109 + if($(input).val() == "") {
  110 + $('#user_password').parent().attr('class', 'required')
  111 + $('#user_password_confirmation').parent().attr('class', 'required')
  112 + } else {
  113 + $('#user_password').parent().attr('class', '')
  114 + $('#user_password_confirmation').parent().attr('class', '')
  115 + }
  116 + }
  117 +
  118 + toggleRequiredPasswordMarks();
  119 +
  120 + function hide_external_backtrace() {
  121 + $('tr.toggle_external_backtrace').hide();
  122 + $('td.backtrace_separator').show();
  123 + }
  124 + function show_external_backtrace() {
  125 + $('tr.toggle_external_backtrace').show();
  126 + $('td.backtrace_separator').hide();
  127 + }
  128 + // Show external backtrace lines when clicking separator
  129 + $('td.backtrace_separator span').live('click', show_external_backtrace);
  130 + // Hide external backtrace on page load
  131 + hide_external_backtrace();
  132 +
  133 + init();
  134 +});
... ...
app/assets/javascripts/form.js 0 → 100644
... ... @@ -0,0 +1,117 @@
  1 +$(function(){
  2 + activateNestedForms();
  3 + activateCheckboxHooks();
  4 +
  5 + if($('div.watcher.nested').length)
  6 + activateTypeSelector('watcher');
  7 +
  8 + if($('div.issue_tracker.nested').length)
  9 + activateTypeSelector('issue_tracker', 'tracker_params');
  10 +
  11 + $('body').addClass('has-js');
  12 + $('.label_radio').click(function(){
  13 + activateLabelIcons();
  14 + });
  15 + activateLabelIcons();
  16 +});
  17 +
  18 +function activateNestedForms() {
  19 + $('.nested-wrapper').each(function(){
  20 + var wrapper = $(this);
  21 +
  22 + makeNestedItemsDestroyable(wrapper);
  23 +
  24 + var addLink = $('<a/>').text('add another').addClass('add-nested');
  25 + addLink.click(appendNestedItem);
  26 + wrapper.append(addLink);
  27 + });
  28 + $('.nested a.remove-nested').live('click',removeNestedItem);
  29 +}
  30 +
  31 +function makeNestedItemsDestroyable(wrapper) {
  32 + wrapper.find('.nested').each(function(){
  33 + var nestedItem = $(this);
  34 + var destroyLink = $('<a/>').text('remove').addClass('remove-nested');
  35 + destroyLink.css('float','right');
  36 + nestedItem.find('label').first().before(destroyLink);
  37 + })
  38 +}
  39 +
  40 +function appendNestedItem() {
  41 + var addLink = $(this);
  42 + var nestedItem = addLink.parent().find('.nested').first().clone().show();
  43 + var timestamp = new Date();
  44 + timestamp = timestamp.valueOf();
  45 +
  46 + nestedItem.find('input, select').each(function(){
  47 + var input = $(this);
  48 + input.attr('id', input.attr('id').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2'));
  49 + input.attr('name', input.attr('name').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2'));
  50 + if(input.attr('type') != 'radio')
  51 + input.val('');
  52 + });
  53 + nestedItem.find('label').each(function(){
  54 + var label = $(this);
  55 + label.attr('for', label.attr('for').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2'));
  56 + });
  57 + addLink.before(nestedItem);
  58 +}
  59 +
  60 +function removeNestedItem() {
  61 + var destroyLink = $(this);
  62 + var nestedItem = destroyLink.closest('.nested');
  63 + var inputNameExample = nestedItem.find('input').first().attr('name');
  64 + var idFieldName = inputNameExample.replace(/\[[^\]]*\]$/,'[id]');
  65 + if($("input[name='"+idFieldName+"']").length) {
  66 + var destroyFlagName = inputNameExample.replace(/\[[^\]]*\]$/,'[_destroy]')
  67 + var destroyFlag = $('<input/>').attr('name',destroyFlagName).attr('type','hidden').val('true');
  68 + $("input[name='"+idFieldName+"']").after(destroyFlag);
  69 + }
  70 + nestedItem.hide();
  71 +}
  72 +
  73 +
  74 +function activateTypeSelector(field_class, section_class) {
  75 + var section_class = section_class || field_class+"_params"; // section_class can be deduced if not given
  76 + // disable all inactive tabs to avoid sending its values on server
  77 + $('div.'+field_class+' > div.'+section_class).not('.chosen').find('input')
  78 + .attr('disabled','disabled').val('');
  79 +
  80 + $('div.'+field_class+' input[name*=type]').live('click', function(){
  81 + // Look for section in 'data-section', and fall back to 'value'
  82 + var chosen = $(this).data("section") || $(this).val();
  83 + var wrapper = $(this).closest('.nested');
  84 + wrapper.find('div.chosen.'+section_class).removeClass('chosen').find('input').attr('disabled','disabled');
  85 + wrapper.find('div.'+section_class+'.'+chosen).addClass('chosen').find('input').removeAttr('disabled');
  86 + });
  87 +}
  88 +
  89 +
  90 +function activateCheckboxHooks() {
  91 + // Hooks to hide/show content when a checkbox is clicked
  92 + $('input[type="checkbox"][data-hide-when-checked]').each(function(){
  93 + $(this).change(function(){
  94 + el = $($(this).data('hide-when-checked'));
  95 + $(this).attr('checked') ? el.hide() : el.show();
  96 + });
  97 + });
  98 + $('input[type="checkbox"][data-show-when-checked]').each(function(){
  99 + $(this).change(function(){
  100 + el = $($(this).data('show-when-checked'));
  101 + $(this).attr('checked') ? el.show() : el.hide();
  102 + });
  103 + });
  104 +}
  105 +
  106 +
  107 +function activateLabelIcons() {
  108 + if ($('.label_radio input').length) {
  109 + $('.label_radio').each(function(){
  110 + $(this).removeClass('r_on');
  111 + });
  112 + $('.label_radio input:checked').each(function(){
  113 + $(this).parent('label').addClass('r_on');
  114 + });
  115 + };
  116 +};
  117 +
... ...
app/assets/javascripts/jquery.alerts.js 0 → 100644
... ... @@ -0,0 +1,230 @@
  1 +// jQuery Alert Dialogs Plugin
  2 +//
  3 +// Version 1.2
  4 +//
  5 +// Cory S.N. LaViska
  6 +// A Beautiful Site (http://abeautifulsite.net/)
  7 +// 14 May 2009
  8 +//
  9 +// Visit http://abeautifulsite.net/notebook/87 for more information
  10 +//
  11 +// Usage:
  12 +// $.jAlert( message, [title, callback] )
  13 +// $.jConfirm( message, [title, callback] )
  14 +// $.jPrompt( message, [value, title, callback] )
  15 +//
  16 +// History:
  17 +//
  18 +// 1.00 - Released (29 December 2008)
  19 +//
  20 +// 1.01 - Fixed bug where unbinding would destroy all resize events
  21 +//
  22 +// 1.2 - global methods removed.
  23 +//
  24 +// License:
  25 +//
  26 +// This plugin is dual-licensed under the GNU General Public License and the MIT License and
  27 +// is copyright 2008 A Beautiful Site, LLC.
  28 +//
  29 +(function($) {
  30 +
  31 + $.alerts = {
  32 +
  33 + // These properties can be read/written by accessing $.alerts.propertyName from your scripts at any time
  34 +
  35 + verticalOffset: -75, // vertical offset of the dialog from center screen, in pixels
  36 + horizontalOffset: 0, // horizontal offset of the dialog from center screen, in pixels/
  37 + repositionOnResize: true, // re-centers the dialog on window resize
  38 + overlayOpacity: 0.01, // transparency level of overlay
  39 + overlayColor: '#FFF', // base color of overlay
  40 + draggable: true, // make the dialogs draggable (requires UI Draggables plugin)
  41 + okButton: '&nbsp;OK&nbsp;', // text for the OK button
  42 + cancelButton: '&nbsp;Cancel&nbsp;', // text for the Cancel button
  43 + dialogClass: null, // if specified, this class will be applied to all dialogs
  44 + titles: {
  45 + alert: 'Alert',
  46 + confirm: 'Confirm',
  47 + prompt: 'Prompt'
  48 + },
  49 +
  50 + // Public methods
  51 +
  52 + alert: function(message, title, callback) {
  53 + if (! title) title = $.alerts.titles.alert;
  54 + $.alerts._show(title, message, null, 'alert', function(result) {
  55 + if (callback) callback(result);
  56 + });
  57 + },
  58 +
  59 + confirm: function(message, title, callback) {
  60 + if (! title) title = $.alerts.titles.confirm;
  61 + $.alerts._show(title, message, null, 'confirm', function(result) {
  62 + if (callback) callback(result);
  63 + });
  64 + },
  65 +
  66 + prompt: function(message, value, title, callback) {
  67 + if (! title) title = $.alerts.titles.prompt;
  68 + $.alerts._show(title, message, value, 'prompt', function(result) {
  69 + if(callback) callback(result);
  70 + });
  71 + },
  72 +
  73 + // Private methods
  74 +
  75 + _show: function(title, msg, value, type, callback) {
  76 +
  77 + $.alerts._hide();
  78 + $.alerts._overlay('show');
  79 +
  80 + $("BODY").append(
  81 + '<div id="popup_container">' +
  82 + '<h1 id="popup_title"></h1>' +
  83 + '<div id="popup_content">' +
  84 + '<div id="popup_message"></div>' +
  85 + '</div>' +
  86 + '</div>');
  87 +
  88 + if( $.alerts.dialogClass ) $("#popup_container").addClass($.alerts.dialogClass);
  89 +
  90 + // IE6 Fix
  91 + var pos = ($.browser.msie && parseInt($.browser.version, 10) <= 6 ) ? 'absolute' : 'fixed';
  92 +
  93 + $("#popup_container").css({
  94 + position: pos,
  95 + zIndex: 99999,
  96 + padding: 0,
  97 + margin: 0
  98 + });
  99 +
  100 + $("#popup_title").text(title);
  101 + $("#popup_content").addClass(type);
  102 + $("#popup_message").text(msg);
  103 + $("#popup_message").html( $("#popup_message").text().replace(/\n/g, '<br />') );
  104 +
  105 + $("#popup_container").css({
  106 + minWidth: $("#popup_container").outerWidth(),
  107 + maxWidth: $("#popup_container").outerWidth()
  108 + });
  109 +
  110 + $.alerts._reposition();
  111 + $.alerts._maintainPosition(true);
  112 +
  113 + switch( type ) {
  114 + case 'alert':
  115 + $("#popup_message").after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /></div>');
  116 + $("#popup_ok").click( function() {
  117 + $.alerts._hide();
  118 + callback(true);
  119 + });
  120 + $("#popup_ok").focus().keypress( function(e) {
  121 + if( e.keyCode == 13 || e.keyCode == 27 ) $("#popup_ok").trigger('click');
  122 + });
  123 + break;
  124 + case 'confirm':
  125 + $("#popup_message").after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
  126 + $("#popup_ok").click( function() {
  127 + $.alerts._hide();
  128 + if( callback ) callback(true);
  129 + });
  130 + $("#popup_cancel").click( function() {
  131 + $.alerts._hide();
  132 + if( callback ) callback(false);
  133 + });
  134 + $("#popup_ok").focus();
  135 + $("#popup_ok, #popup_cancel").keypress( function(e) {
  136 + if( e.keyCode == 13 ) $("#popup_ok").trigger('click');
  137 + if( e.keyCode == 27 ) $("#popup_cancel").trigger('click');
  138 + });
  139 + break;
  140 + case 'prompt':
  141 + $("#popup_message").append('<br /><input type="text" size="30" id="popup_prompt" />').after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
  142 + $("#popup_prompt").width( $("#popup_message").width() );
  143 + $("#popup_ok").click( function() {
  144 + var val = $("#popup_prompt").val();
  145 + $.alerts._hide();
  146 + if( callback ) callback( val );
  147 + });
  148 + $("#popup_cancel").click( function() {
  149 + $.alerts._hide();
  150 + if( callback ) callback( null );
  151 + });
  152 + $("#popup_prompt, #popup_ok, #popup_cancel").keypress( function(e) {
  153 + if( e.keyCode == 13 ) $("#popup_ok").trigger('click');
  154 + if( e.keyCode == 27 ) $("#popup_cancel").trigger('click');
  155 + });
  156 + if( value ) $("#popup_prompt").val(value);
  157 + $("#popup_prompt").focus().select();
  158 + break;
  159 + default: break;
  160 + }
  161 +
  162 + // Make draggable
  163 + if ($.alerts.draggable && $.fn.draggable) {
  164 + $("#popup_container").draggable({ handle: $("#popup_title") });
  165 + $("#popup_title").css({ cursor: 'move' });
  166 + }
  167 + },
  168 +
  169 + _hide: function() {
  170 + $("#popup_container").remove();
  171 + $.alerts._overlay('hide');
  172 + $.alerts._maintainPosition(false);
  173 + },
  174 +
  175 + _overlay: function(status) {
  176 + switch( status ) {
  177 + case 'show':
  178 + $.alerts._overlay('hide');
  179 + $("BODY").append('<div id="popup_overlay"></div>');
  180 + $("#popup_overlay").css({
  181 + position: 'absolute',
  182 + zIndex: 99998,
  183 + top: '0px',
  184 + left: '0px',
  185 + width: '100%',
  186 + height: $(document).height(),
  187 + background: $.alerts.overlayColor,
  188 + opacity: $.alerts.overlayOpacity
  189 + });
  190 + break;
  191 + case 'hide':
  192 + $("#popup_overlay").remove();
  193 + break;
  194 + default: break;
  195 + }
  196 + },
  197 +
  198 + _reposition: function() {
  199 + var top = (($(window).height() / 2) - ($("#popup_container").outerHeight() / 2)) + $.alerts.verticalOffset;
  200 + var left = (($(window).width() / 2) - ($("#popup_container").outerWidth() / 2)) + $.alerts.horizontalOffset;
  201 + if( top < 0 ) top = 0;
  202 + if( left < 0 ) left = 0;
  203 +
  204 + // IE6 fix
  205 + if( $.browser.msie && parseInt($.browser.version, 10) <= 6 ) top = top + $(window).scrollTop();
  206 +
  207 + $("#popup_container").css({
  208 + top: top + 'px',
  209 + left: left + 'px'
  210 + });
  211 + $("#popup_overlay").height( $(document).height() );
  212 + },
  213 +
  214 + _maintainPosition: function(status) {
  215 + if( $.alerts.repositionOnResize ) {
  216 + switch(status) {
  217 + case true:
  218 + $(window).bind('resize', $.alerts._reposition);
  219 + break;
  220 + case false:
  221 + $(window).unbind('resize', $.alerts._reposition);
  222 + break;
  223 + default: break;
  224 + }
  225 + }
  226 + }
  227 +
  228 + };
  229 +
  230 +})(jQuery);
0 231 \ No newline at end of file
... ...
app/assets/javascripts/jquery.js 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +/*!
  2 + * jQuery JavaScript Library v1.6.2
  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: Thu Jun 30 14:16:56 2011 -0400
  15 + */
  16 +(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){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<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bC.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bR,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bX(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bX(a,c,d,e,"*",g));return l}function bW(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bN),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bA(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bv:bw;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bg(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function W(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(R.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=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;i<s.length;i++)g=s[i],g.origType.replace(x,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)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){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);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(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,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=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};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=i.exec(a):g=[null,a,null];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.2",length:0,size:function(){return this.length},toArray:function(){return F.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)?E.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(),A.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(F.apply(this,arguments),"slice",F.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:E,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(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},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):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.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)},camelCase:function(a){return a.replace(w,x)},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(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(H)return H.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?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<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),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[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||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<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u=/\:|^on/,v,w;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-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;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}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,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},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);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},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.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}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},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);i&&(c=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:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?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 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<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.
  17 +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!=null?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<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,N(a.origType,a.selector),f.extend({},a,{handler:M,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,N(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?E:D):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=E;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=E;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=E,this.stopPropagation()},isDefaultPrevented:D,isPropagationStopped:D,isImmediatePropagationStopped:D};var F=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},G=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?G:F,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?G:F)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&K("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&K("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var H,I=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};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;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var L={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||D,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=x.exec(h),k="",j&&(k=j[0],h=h.replace(x,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,L[h]?(a.push(L[h]+k),h=h+k):h=(L[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+N(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+N(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?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;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){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<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\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;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=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){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[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<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=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<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",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 href='#'></a>",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="<p class='TEST'></p>";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="<div class='test e'></div><div class='test'></div>";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;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var O=/Until$/,P=/^(?:parents|prevUntil|prevAll)/,Q=/,/,R=/^.[^:#\[\.,]*$/,S=Array.prototype.slice,T=f.expr.match.POS,U={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(W(this,a,!1),"not",a)},filter:function(a){return this.pushStack(W(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=T.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-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<e;d++){g=this[d];while(g){if(l?l.index(g)>-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:]+)/,_=/<tbody/i,ba=/<|&#?\w+;/,bb=/<(?:script|object|embed|option|style)/i,bc=/checked\s*(?:[^=]|=\s*.checked.)/i,bd=/\/(java|ecma)script/i,be=/^\s*<!(?:\[CDATA\[|\-\-)/,bf={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div<div>","</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))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bc.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bg(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bm)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bb.test(a[0])&&(f.support.checkClone||!bc.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j
  18 +)}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)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;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=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1></$2>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bl(k[i]);else bl(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bd.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bn=/alpha\([^)]*\)/i,bo=/opacity=([^)]*)/,bp=/([A-Z]|^ms)/g,bq=/^-?\d+(?:px)?$/i,br=/^-?\d/,bs=/^[+\-]=/,bt=/[^+\-\.\de]+/g,bu={position:"absolute",visibility:"hidden",display:"block"},bv=["Left","Right"],bw=["Top","Bottom"],bx,by,bz;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bx(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bs.test(d)&&(d=+d.replace(bt,"")+parseFloat(f.css(a,c)),h="number"),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bx)return bx(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bA(a,b,d);f.swap(a,bu,function(){e=bA(a,b,d)});return e}},set:function(a,b){if(!bq.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.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=bn.test(g)?g.replace(bn,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 bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.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("<div>").append(c.replace(bL,"")).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||bM.test(this.nodeName)||bG.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(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\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:bT,isLocal:bH.test(bU[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:bW(bR),ajaxTransport:bW(bS),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?bZ(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=bF.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(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.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=bX(bS,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)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),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&&(ca.test(b.url)||e&&ca.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(ca,l),b.url===j&&(e&&(k=k.replace(ca,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 cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,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,cb&&delete cd[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=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cs(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cr("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cr("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cs(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cr("show",1),slideUp:cr("hide",1),slideToggle:cr("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=cn||cp(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!cl&&(co?(cl=!0,g=function(){cl&&(co(g),e.tick())},co(g)):cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||cp(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=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(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=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 ct=/^t(?:able|d|h)$/i,cu=/^(?: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=cv(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||!ct.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="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";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=cu.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&&!cu.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=cv(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=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,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);
0 19 \ No newline at end of file
... ...
app/assets/javascripts/jquery.pjax.js 0 → 100644
... ... @@ -0,0 +1,264 @@
  1 +// jquery.pjax.js
  2 +// copyright chris wanstrath
  3 +// https://github.com/defunkt/jquery-pjax
  4 +
  5 +(function($){
  6 +
  7 +// When called on a link, fetches the href with ajax into the
  8 +// container specified as the first parameter or with the data-pjax
  9 +// attribute on the link itself.
  10 +//
  11 +// Tries to make sure the back button and ctrl+click work the way
  12 +// you'd expect.
  13 +//
  14 +// Accepts a jQuery ajax options object that may include these
  15 +// pjax specific options:
  16 +//
  17 +// container - Where to stick the response body. Usually a String selector.
  18 +// $(container).html(xhr.responseBody)
  19 +// push - Whether to pushState the URL. Defaults to true (of course).
  20 +// replace - Want to use replaceState instead? That's cool.
  21 +//
  22 +// For convenience the first parameter can be either the container or
  23 +// the options object.
  24 +//
  25 +// Returns the jQuery object
  26 +$.fn.pjax = function( container, options ) {
  27 + if ( options )
  28 + options.container = container
  29 + else
  30 + options = $.isPlainObject(container) ? container : {container:container}
  31 +
  32 + // We can't persist $objects using the history API so we must use
  33 + // a String selector. Bail if we got anything else.
  34 + if ( options.container && typeof options.container !== 'string' ) {
  35 + throw "pjax container must be a string selector!"
  36 + return false
  37 + }
  38 +
  39 + return this.live('click', function(event){
  40 + // Middle click, cmd click, and ctrl click should open
  41 + // links in a new tab as normal.
  42 + if ( event.which > 1 || event.metaKey )
  43 + return true
  44 +
  45 + var defaults = {
  46 + url: this.href,
  47 + container: $(this).attr('data-pjax'),
  48 + clickedElement: $(this),
  49 + fragment: null
  50 + }
  51 +
  52 + $.pjax($.extend({}, defaults, options))
  53 +
  54 + event.preventDefault()
  55 + })
  56 +}
  57 +
  58 +
  59 +// Loads a URL with ajax, puts the response body inside a container,
  60 +// then pushState()'s the loaded URL.
  61 +//
  62 +// Works just like $.ajax in that it accepts a jQuery ajax
  63 +// settings object (with keys like url, type, data, etc).
  64 +//
  65 +// Accepts these extra keys:
  66 +//
  67 +// container - Where to stick the response body. Must be a String.
  68 +// $(container).html(xhr.responseBody)
  69 +// push - Whether to pushState the URL. Defaults to true (of course).
  70 +// replace - Want to use replaceState instead? That's cool.
  71 +//
  72 +// Use it just like $.ajax:
  73 +//
  74 +// var xhr = $.pjax({ url: this.href, container: '#main' })
  75 +// console.log( xhr.readyState )
  76 +//
  77 +// Returns whatever $.ajax returns.
  78 +var pjax = $.pjax = function( options ) {
  79 + var $container = $(options.container),
  80 + success = options.success || $.noop
  81 +
  82 + // We don't want to let anyone override our success handler.
  83 + delete options.success
  84 +
  85 + // We can't persist $objects using the history API so we must use
  86 + // a String selector. Bail if we got anything else.
  87 + if ( typeof options.container !== 'string' )
  88 + throw "pjax container must be a string selector!"
  89 +
  90 + options = $.extend(true, {}, pjax.defaults, options)
  91 +
  92 + if ( $.isFunction(options.url) ) {
  93 + options.url = options.url()
  94 + }
  95 +
  96 + options.context = $container
  97 +
  98 + options.success = function(data){
  99 + if ( options.fragment ) {
  100 + // If they specified a fragment, look for it in the response
  101 + // and pull it out.
  102 + var $fragment = $(data).find(options.fragment)
  103 + if ( $fragment.length )
  104 + data = $fragment.children()
  105 + else
  106 + return window.location = options.url
  107 + } else {
  108 + // If we got no data or an entire web page, go directly
  109 + // to the page and let normal error handling happen.
  110 + if ( !$.trim(data) || /<html/i.test(data) )
  111 + return window.location = options.url
  112 + }
  113 +
  114 + // Make it happen.
  115 + this.html(data)
  116 +
  117 + // If there's a <title> tag in the response, use it as
  118 + // the page's title.
  119 + var oldTitle = document.title,
  120 + title = $.trim( this.find('title').remove().text() )
  121 + if ( title ) document.title = title
  122 +
  123 + // No <title>? Fragment? Look for data-title and title attributes.
  124 + if ( !title && options.fragment ) {
  125 + title = $fragment.attr('title') || $fragment.data('title')
  126 + }
  127 +
  128 + var state = {
  129 + pjax: options.container,
  130 + fragment: options.fragment,
  131 + timeout: options.timeout
  132 + }
  133 +
  134 + // If there are extra params, save the complete URL in the state object
  135 + var query = $.param(options.data)
  136 + if ( query != "_pjax=true" )
  137 + state.url = options.url + (/\?/.test(options.url) ? "&" : "?") + query
  138 +
  139 + if ( options.replace ) {
  140 + window.history.replaceState(state, document.title, options.url)
  141 + } else if ( options.push ) {
  142 + // this extra replaceState before first push ensures good back
  143 + // button behavior
  144 + if ( !pjax.active ) {
  145 + window.history.replaceState($.extend({}, state, {url:null}), oldTitle)
  146 + pjax.active = true
  147 + }
  148 +
  149 + window.history.pushState(state, document.title, options.url)
  150 + }
  151 +
  152 + // Google Analytics support
  153 + if ( (options.replace || options.push) && window._gaq )
  154 + _gaq.push(['_trackPageview'])
  155 +
  156 + // If the URL has a hash in it, make sure the browser
  157 + // knows to navigate to the hash.
  158 + var hash = window.location.hash.toString()
  159 + if ( hash !== '' ) {
  160 + window.location.href = hash
  161 + }
  162 +
  163 + // Invoke their success handler if they gave us one.
  164 + success.apply(this, arguments)
  165 + }
  166 +
  167 + // Cancel the current request if we're already pjaxing
  168 + var xhr = pjax.xhr
  169 + if ( xhr && xhr.readyState < 4) {
  170 + xhr.onreadystatechange = $.noop
  171 + xhr.abort()
  172 + }
  173 +
  174 + pjax.options = options
  175 + pjax.xhr = $.ajax(options)
  176 + $(document).trigger('pjax', [pjax.xhr, options])
  177 +
  178 + return pjax.xhr
  179 +}
  180 +
  181 +
  182 +pjax.defaults = {
  183 + timeout: 650,
  184 + push: true,
  185 + replace: false,
  186 + // We want the browser to maintain two separate internal caches: one for
  187 + // pjax'd partial page loads and one for normal page loads. Without
  188 + // adding this secret parameter, some browsers will often confuse the two.
  189 + data: { _pjax: true },
  190 + type: 'GET',
  191 + dataType: 'html',
  192 + beforeSend: function(xhr){
  193 + this.trigger('pjax:start', [xhr, pjax.options])
  194 + // start.pjax is deprecated
  195 + this.trigger('start.pjax', [xhr, pjax.options])
  196 + xhr.setRequestHeader('X-PJAX', 'true')
  197 + },
  198 + error: function(xhr, textStatus, errorThrown){
  199 + if ( textStatus !== 'abort' )
  200 + window.location = pjax.options.url
  201 + },
  202 + complete: function(xhr){
  203 + this.trigger('pjax:end', [xhr, pjax.options])
  204 + // end.pjax is deprecated
  205 + this.trigger('end.pjax', [xhr, pjax.options])
  206 + }
  207 +}
  208 +
  209 +
  210 +// Used to detect initial (useless) popstate.
  211 +// If history.state exists, assume browser isn't going to fire initial popstate.
  212 +var popped = ('state' in window.history), initialURL = location.href
  213 +
  214 +
  215 +// popstate handler takes care of the back and forward buttons
  216 +//
  217 +// You probably shouldn't use pjax on pages with other pushState
  218 +// stuff yet.
  219 +$(window).bind('popstate', function(event){
  220 + // Ignore inital popstate that some browsers fire on page load
  221 + var initialPop = !popped && location.href == initialURL
  222 + popped = true
  223 + if ( initialPop ) return
  224 +
  225 + var state = event.state
  226 +
  227 + if ( state && state.pjax ) {
  228 + var container = state.pjax
  229 + if ( $(container+'').length )
  230 + $.pjax({
  231 + url: state.url || location.href,
  232 + fragment: state.fragment,
  233 + container: container,
  234 + push: false,
  235 + timeout: state.timeout
  236 + })
  237 + else
  238 + window.location = location.href
  239 + }
  240 +})
  241 +
  242 +
  243 +// Add the state property to jQuery's event object so we can use it in
  244 +// $(window).bind('popstate')
  245 +if ( $.inArray('state', $.event.props) < 0 )
  246 + $.event.props.push('state')
  247 +
  248 +
  249 +// Is pjax supported by this browser?
  250 +$.support.pjax =
  251 + window.history && window.history.pushState && window.history.replaceState
  252 + // pushState isn't reliable on iOS yet.
  253 + && !navigator.userAgent.match(/(iPod|iPhone|iPad|WebApps\/.+CFNetwork)/)
  254 +
  255 +
  256 +// Fall back to normalcy for older browsers.
  257 +if ( !$.support.pjax ) {
  258 + $.pjax = function( options ) {
  259 + window.location = $.isFunction(options.url) ? options.url() : options.url
  260 + }
  261 + $.fn.pjax = function() { return this }
  262 +}
  263 +
  264 +})(jQuery);
... ...
app/assets/javascripts/rails.alerts.js 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +/*
  2 + * Replaces default rails.confirm implementation with $.alerts.confirm.
  3 + */
  4 +
  5 +(function($) {
  6 + $.rails.confirm = function(msg) {
  7 + var answer = $.Deferred();
  8 + $.alerts.confirm(msg, 'Confirmation', function(r) {
  9 + $.rails.resolveOrReject(answer, r);
  10 + });
  11 + return answer.promise();
  12 + };
  13 +})(jQuery);
  14 +
... ...
app/assets/javascripts/rails.js 0 → 100644
... ... @@ -0,0 +1,406 @@
  1 +/**
  2 + * Unobtrusive scripting adapter for jQuery
  3 + *
  4 + * Requires jQuery 1.6.0 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($, undefined) {
  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 + // Select elements bound by jquery-ujs
  55 + selectChangeSelector: 'select[data-remote]',
  56 +
  57 + // Form elements bound by jquery-ujs
  58 + formSubmitSelector: 'form',
  59 +
  60 + // Form input elements bound by jquery-ujs
  61 + formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type])',
  62 +
  63 + // Form input elements disabled during form submission
  64 + disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]',
  65 +
  66 + // Form input elements re-enabled after form submission
  67 + enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled',
  68 +
  69 + // Form required input elements
  70 + requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])',
  71 +
  72 + // Form file input elements
  73 + fileInputSelector: 'input:file',
  74 +
  75 + // Make sure that every Ajax request sends the CSRF token
  76 + CSRFProtection: function(xhr) {
  77 + var token = $('meta[name="csrf-token"]').attr('content');
  78 + if (token) xhr.setRequestHeader('X-CSRF-Token', token);
  79 + },
  80 +
  81 + // Triggers an event on an element and returns false if the event result is false
  82 + fire: function(obj, name, data) {
  83 + var event = $.Event(name);
  84 + obj.trigger(event, data);
  85 + return event.result !== false;
  86 + },
  87 +
  88 + resolveOrReject: function(deferred, resolved) {
  89 + if (resolved) {
  90 + deferred.resolve();
  91 + } else {
  92 + deferred.reject();
  93 + }
  94 + return deferred;
  95 + },
  96 +
  97 + // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
  98 + confirm: function(message) {
  99 + var res = confirm(message),
  100 + answer = $.Deferred();
  101 +
  102 + rails.resolveOrReject(answer, res);
  103 + return answer.promise();
  104 + },
  105 +
  106 + // Default ajax function, may be overridden with custom function in $.rails.ajax
  107 + ajax: function(options) {
  108 + return $.ajax(options);
  109 + },
  110 +
  111 + // Submits "remote" forms and links with ajax
  112 + handleRemote: function(element) {
  113 + var method, url, data, button,
  114 + crossDomain = element.data('cross-domain') || null,
  115 + dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType),
  116 + options;
  117 +
  118 + if (rails.fire(element, 'ajax:before')) {
  119 +
  120 + if (element.is('form')) {
  121 + method = element.attr('method');
  122 + url = element.attr('action');
  123 + data = element.serializeArray();
  124 + // memoized value from clicked submit button
  125 + button = element.data('ujs:submit-button');
  126 + if (button) {
  127 + data.push(button);
  128 + element.data('ujs:submit-button', null);
  129 + }
  130 + } else if (element.is('select')) {
  131 + method = element.data('method');
  132 + url = element.data('url');
  133 + data = element.serialize();
  134 + if (element.data('params')) data = data + "&" + element.data('params');
  135 + } else {
  136 + method = element.data('method');
  137 + url = element.attr('href');
  138 + data = element.data('params') || null;
  139 + }
  140 +
  141 + options = {
  142 + type: method || 'GET', data: data, dataType: dataType, crossDomain: crossDomain,
  143 + // stopping the "ajax:beforeSend" event will cancel the ajax request
  144 + beforeSend: function(xhr, settings) {
  145 + if (settings.dataType === undefined) {
  146 + xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
  147 + }
  148 + return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
  149 + },
  150 + success: function(data, status, xhr) {
  151 + element.trigger('ajax:success', [data, status, xhr]);
  152 + },
  153 + complete: function(xhr, status) {
  154 + element.trigger('ajax:complete', [xhr, status]);
  155 + },
  156 + error: function(xhr, status, error) {
  157 + element.trigger('ajax:error', [xhr, status, error]);
  158 + }
  159 + };
  160 + // Only pass url to `ajax` options if not blank
  161 + if (url) { options.url = url; }
  162 +
  163 + rails.ajax(options);
  164 + }
  165 + },
  166 +
  167 + // Handles "data-method" on links such as:
  168 + // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
  169 + handleMethod: function(link) {
  170 + var href = link.attr('href'),
  171 + method = link.data('method') || 'GET',
  172 + csrf_token = $('meta[name=csrf-token]').attr('content'),
  173 + csrf_param = $('meta[name=csrf-param]').attr('content'),
  174 + form = $('<form></form>', { action: href, method: method, 'data-ujs-generated': 'true' }),
  175 + metadata_input = '';
  176 +
  177 + if (method !== 'GET') {
  178 + form.attr('method', 'POST');
  179 + metadata_input += '<input name="_method" value="' + method + '" type="hidden" />';
  180 +
  181 + if (csrf_param !== undefined && csrf_token !== undefined) {
  182 + metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
  183 + }
  184 + }
  185 +
  186 + form.hide().append(metadata_input).appendTo('body');
  187 + form.submit();
  188 + },
  189 +
  190 + /* Disables form elements:
  191 + - Caches element value in 'ujs:enable-with' data store
  192 + - Replaces element text with value of 'data-disable-with' attribute
  193 + - Adds disabled=disabled attribute
  194 + */
  195 + disableFormElements: function(form) {
  196 + form.find(rails.disableSelector).each(function() {
  197 + var element = $(this),
  198 + method = element.is('button') ? 'html' : 'val';
  199 +
  200 + element.data('ujs:enable-with', element[method]());
  201 + element[method](element.data('disable-with'));
  202 + element.attr('disabled', 'disabled');
  203 + });
  204 + },
  205 +
  206 + /* Re-enables disabled form elements:
  207 + - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
  208 + - Removes disabled attribute
  209 + */
  210 + enableFormElements: function(form) {
  211 + form.find(rails.enableSelector).each(function() {
  212 + var element = $(this),
  213 + method = element.is('button') ? 'html' : 'val';
  214 +
  215 + if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
  216 + element.removeAttr('disabled');
  217 + });
  218 + },
  219 +
  220 + /* For 'data-confirm' attribute:
  221 + - Fires `confirm` event
  222 + - Shows the confirmation dialog
  223 + - Fires the `confirm:complete` event
  224 +
  225 + Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
  226 + Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
  227 + Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
  228 + return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
  229 + */
  230 + allowAction: function(element) {
  231 + var message = element.data('confirm'),
  232 + confirmAnswer,
  233 + answer = $.Deferred();
  234 +
  235 + if (!message) { return $.when(true); }
  236 +
  237 + if (rails.fire(element, 'confirm')) {
  238 + confirmAnswer = rails.confirm(message);
  239 + confirmAnswer.then(
  240 + function() {
  241 + var callbackOk = rails.fire(element, 'confirm:complete', [ true ]);
  242 + rails.resolveOrReject(answer, callbackOk);
  243 + },
  244 + function() {
  245 + rails.fire(element, 'confirm:complete', [ false ]);
  246 + answer.reject();
  247 + }
  248 + );
  249 + return answer.promise();
  250 + // If `confirm` event handler returned false...
  251 + } else {
  252 + answer.reject();
  253 + return answer.promise();
  254 + }
  255 + },
  256 +
  257 + // Helper function which checks for blank inputs in a form that match the specified CSS selector
  258 + blankInputs: function(form, specifiedSelector, nonBlank) {
  259 + var inputs = $(), input,
  260 + selector = specifiedSelector || 'input,textarea';
  261 +
  262 + form.find(selector).each(function() {
  263 + input = $(this);
  264 + // Collect non-blank inputs if nonBlank option is true, otherwise, collect blank inputs
  265 + if (nonBlank ? input.val() : !input.val()) {
  266 + inputs = inputs.add(input);
  267 + }
  268 + });
  269 + return inputs.length ? inputs : false;
  270 + },
  271 +
  272 + // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
  273 + nonBlankInputs: function(form, specifiedSelector) {
  274 + return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
  275 + },
  276 +
  277 + // Helper function, needed to provide consistent behavior in IE
  278 + stopEverything: function(e) {
  279 + $(e.target).trigger('ujs:everythingStopped');
  280 + e.stopImmediatePropagation();
  281 + return false;
  282 + },
  283 +
  284 + // find all the submit events directly bound to the form and
  285 + // manually invoke them. If anyone returns false then stop the loop
  286 + callFormSubmitBindings: function(form) {
  287 + var events = form.data('events'), continuePropagation = true;
  288 +
  289 + if (events !== undefined && events['submit'] !== undefined) {
  290 + $.each(events['submit'], function(i, obj){
  291 + if (typeof obj.handler === 'function') return continuePropagation = obj.handler(obj.data);
  292 + });
  293 + }
  294 + return continuePropagation;
  295 + }
  296 + };
  297 +
  298 + $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
  299 +
  300 + $(rails.linkClickSelector).live('click.rails', function(e) {
  301 + var link = $(this);
  302 +
  303 + rails.allowAction(link).then(
  304 + function() {
  305 + if (link.data('remote') !== undefined) {
  306 + rails.handleRemote(link);
  307 + } else {
  308 + rails.handleMethod(link);
  309 + }
  310 + },
  311 + function() {
  312 + rails.stopEverything(e);
  313 + }
  314 + );
  315 +
  316 + e.preventDefault();
  317 + });
  318 +
  319 + $(rails.selectChangeSelector).live('change.rails', function(e) {
  320 + var link = $(this);
  321 +
  322 + rails.allowAction(link).then(
  323 + function() {
  324 + rails.handleRemote(link);
  325 + },
  326 + function() {
  327 + rails.stopEverything(e);
  328 + }
  329 + );
  330 +
  331 + e.preventDefault();
  332 + });
  333 +
  334 + $(rails.formSubmitSelector).live('submit.rails', function(e) {
  335 + var form = $(this),
  336 + remote = (form.data('remote') !== undefined),
  337 + blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
  338 + nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
  339 +
  340 + rails.allowAction(form).then(
  341 + function() {
  342 + // skip other logic when required values are missing or file upload is present
  343 + if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
  344 + return rails.stopEverything(e);
  345 + }
  346 +
  347 + if (remote) {
  348 + if (nonBlankFileInputs) {
  349 + return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
  350 + }
  351 +
  352 + // If browser does not support submit bubbling, then this live-binding will be called before direct
  353 + // bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
  354 + if (!$.support.submitBubbles && rails.callFormSubmitBindings(form) === false) return rails.stopEverything(e);
  355 +
  356 + rails.handleRemote(form);
  357 + } else {
  358 + // slight timeout so that the submit button gets properly serialized
  359 + setTimeout(function() {
  360 + rails.disableFormElements(form);
  361 + // Submit the form from dom-level js (i.e. *not* via jquery),
  362 + // which will skip all submit bindings (including this live-binding),
  363 + // since they have already been called.
  364 + form.get(0).submit();
  365 + }, 13);
  366 + }
  367 + },
  368 + function() {
  369 + rails.stopEverything(e);
  370 + }
  371 + );
  372 +
  373 + e.preventDefault();
  374 + });
  375 +
  376 + $(rails.formInputClickSelector).live('click.rails', function(event) {
  377 + var button = $(this);
  378 +
  379 + rails.allowAction(button).then(
  380 + function() {
  381 + // register the pressed submit button
  382 + var name = button.attr('name'), form,
  383 + data = name ? {name:name, value:button.val()} : null;
  384 +
  385 + form = button.closest('form');
  386 + form.data('ujs:submit-button', data);
  387 + form.submit();
  388 + },
  389 + function() {
  390 + rails.stopEverything(event);
  391 + }
  392 + );
  393 +
  394 + event.preventDefault();
  395 + });
  396 +
  397 + $(rails.formSubmitSelector).live('ajax:beforeSend.rails', function(event) {
  398 + if (this == event.target) rails.disableFormElements($(this));
  399 + });
  400 +
  401 + $(rails.formSubmitSelector).live('ajax:complete.rails', function(event) {
  402 + if (this == event.target) rails.enableFormElements($(this));
  403 + });
  404 +
  405 +})( jQuery );
  406 +
... ...
app/assets/javascripts/underscore-1.1.6.js 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +// Underscore.js 1.1.6
  2 +// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
  3 +// Underscore is freely distributable under the MIT license.
  4 +// Portions of Underscore are inspired or borrowed from Prototype,
  5 +// Oliver Steele's Functional, and John Resig's Micro-Templating.
  6 +// For all details and documentation:
  7 +// http://documentcloud.github.com/underscore
  8 +(function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.6";var h=b.each=b.forEach=function(a,c,d){if(a!=null)if(s&&a.forEach===s)a.forEach(c,d);else if(b.isNumber(a.length))for(var e=
  9 +0,k=a.length;e<k;e++){if(c.call(d,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(d,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bind(c,e)),k?a.reduce(c,d):a.reduce(c);h(a,function(a,b,f){!k&&b===0?(d=a,k=!0):d=c.call(e,d,a,b,f)});if(!k)throw new TypeError("Reduce of empty array with no initial value");
  10 +return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(v&&a.reduceRight===v)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;A(a,function(a,g,f){if(c.call(b,a,g,f))return e=a,!0});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.filter===w)return a.filter(c,b);h(a,function(a,g,f){c.call(b,a,g,f)&&(e[e.length]=a)});return e};
  11 +b.reject=function(a,c,b){var e=[];if(a==null)return e;h(a,function(a,g,f){c.call(b,a,g,f)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=!0;if(a==null)return e;if(x&&a.every===x)return a.every(c,b);h(a,function(a,g,f){if(!(e=e&&c.call(b,a,g,f)))return m});return e};var A=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=!1;if(a==null)return e;if(y&&a.some===y)return a.some(c,d);h(a,function(a,b,f){if(e=c.call(d,a,b,f))return m});return e};b.include=b.contains=function(a,c){var b=
  12 +!1;if(a==null)return b;if(o&&a.indexOf===o)return a.indexOf(c)!=-1;A(a,function(a){if(b=a===c)return!0});return b};b.invoke=function(a,c){var d=f.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,
  13 +c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,f){return{value:a,criteria:c.call(d,a,b,f)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=
  14 +function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return f.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?f.call(a,0,b):a[0]};b.rest=b.tail=function(a,b,d){return f.call(a,b==null||d?1:b)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a){return b.reduce(a,function(a,d){if(b.isArray(d))return a.concat(b.flatten(d));
  15 +a[a.length]=d;return a},[])};b.without=function(a){var c=f.call(arguments,1);return b.filter(a,function(a){return!b.include(c,a)})};b.uniq=b.unique=function(a,c){return b.reduce(a,function(a,e,f){if(0==f||(c===!0?b.last(a)!=e:!b.include(a,e)))a[a.length]=e;return a},[])};b.intersect=function(a){var c=f.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),
  16 +e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(o&&a.indexOf===o)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/
  17 +d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};b.bind=function(a,b){if(a.bind===q&&q)return q.apply(a,f.call(arguments,1));var d=f.call(arguments,2);return function(){return a.apply(b,d.concat(f.call(arguments)))}};b.bindAll=function(a){var c=f.call(arguments,1);c.length==0&&(c=b.functions(a));h(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return l.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=
  18 +function(a,b){var d=f.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(f.call(arguments,1)))};var B=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};b.throttle=function(a,b){return B(a,b,!1)};b.debounce=function(a,b){return B(a,b,!0)};b.once=function(a){var b=!1,d;return function(){if(b)return d;b=!0;return d=a.apply(this,arguments)}};
  19 +b.wrap=function(a,b){return function(){var d=[a].concat(f.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=f.call(arguments);return function(){for(var b=f.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,
  20 +b.identity)};b.functions=b.methods=function(a){return b.filter(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=
  21 +typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;
  22 +for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};
  23 +b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset||!a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=
  24 +0;e<a;e++)b.call(d,e)};b.mixin=function(a){h(b.functions(a),function(c){H(c,b[c]=a[c])})};var I=0;b.uniqueId=function(a){var b=I++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||
  25 +null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d};var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort",
  26 +"splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})();
0 27 \ No newline at end of file
... ...
app/assets/stylesheets/.gitkeep 0 → 100644
app/assets/stylesheets/application.css.erb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +/*
  2 + *= require reset
  3 + *= require jquery.alerts
  4 + *= require errbit
  5 + *= require issue_tracker_icons
  6 + *= require_self
  7 + */
  8 +
  9 +// Allow any gems named 'errbit_*' to require their own assets
  10 +<% Gem.loaded_specs.keys.grep(/^errbit_/).each do |plugin|
  11 + require_asset(plugin) rescue Sprockets::FileNotFound
  12 +end %>
... ...
app/assets/stylesheets/errbit.css 0 → 100644
... ... @@ -0,0 +1,855 @@
  1 +html {
  2 + margin: 0; padding: 0;
  3 + color: #585858;
  4 + background-color: #e6e6e6;
  5 + font-size: 62.8%; font-family: Helvetica, "Lucida Grande","Lucida Sans",Arial,sans-serif;
  6 +}
  7 +body {
  8 + margin: 0; padding: 0;
  9 + font-size: 1.3em; line-height: 1.4em;
  10 +}
  11 +
  12 +/* Convenience Classes */
  13 +.float-left { float: left; }
  14 +.float-right { float: right; }
  15 +.clear { clear: both; }
  16 +.clear-left { clear: left; }
  17 +.clear-right { clear: right; }
  18 +.nowrap { white-space: nowrap; }
  19 +
  20 +/* Headings */
  21 +h1, h2, h3, h4, h5, h6 { padding: 0.2em 0; margin-bottom: 1em; border-bottom: 1px solid #dedede;}
  22 +h1 { font-size: 2.0em; line-height: 1.2em; text-shadow: 1px 1px 0px #FFF; -webkit-text-shadow: 1px 1px 0px #FFF;}
  23 +h2 { font-size: 1.7em; line-height: 1.2em; }
  24 +h3 { font-size: 1.5em; line-height: 1.2em; }
  25 +h4 { font-size: 1.3em; line-height: 1.2em; }
  26 +h5 { font-size: 1.1em; line-height: 1.2em; }
  27 +h6 { font-size: 0.9em; line-height: 1.2em; }
  28 +
  29 +/* General */
  30 +p { margin-bottom: 1em; }
  31 +
  32 +/* Links */
  33 +a { color: #0069cc; text-decoration: none;}
  34 +a:visited { color: #0069cc;}
  35 +a:hover { color: #0069cc; text-decoration: underline; }
  36 +a.action { float: right; font-size: 0.9em;}
  37 +
  38 +#header > div, #content-wrapper, #footer {
  39 + width: 930px;
  40 + margin: 0 auto;
  41 + position: relative;
  42 +}
  43 +
  44 +/* Header */
  45 +#header {
  46 + margin-bottom: 24px;
  47 + height: 71px;
  48 + border-bottom: 1px solid #fff;
  49 + position:relative;
  50 + background: #000000;
  51 +}
  52 +#header > div {
  53 + height: 71px;
  54 +}
  55 +#header #site-name {
  56 + display: block;
  57 + width: 88px;
  58 + height: 31px;
  59 + position: absolute;
  60 + top: 22px;
  61 + left: 2px;
  62 + background: transparent url(images/logo.png) 0 0 no-repeat;
  63 + text-indent: -5000em;
  64 +}
  65 +
  66 +#header #session-links {
  67 + position: absolute;
  68 + top: 20px;
  69 + right: 0;
  70 + font-size: 0.9em;
  71 +}
  72 +#header #session-links li {
  73 + float: right;
  74 + margin-left: 10px;
  75 + color: #ccc;
  76 + background-color: #1e1e1e;
  77 + border-radius: 30px;
  78 + -moz-border-radius: 30px;
  79 + -webkit-border-radius: 30px;
  80 + border: 1px solid #484B4F;
  81 + font-size: 14px;
  82 +}
  83 +#header #session-links li:hover {
  84 + box-shadow: 0 0 3px #69c;
  85 + -moz-box-shadow: 0 0 3px #69c;
  86 + -webkit-box-shadow: 0 0 3px #69c;
  87 +}
  88 +#header #session-links li:hover a {
  89 + color: white;
  90 +}
  91 +#header #session-links a {
  92 + color: #ccc;
  93 + padding: 0 14px;
  94 + line-height: 30px;
  95 +}
  96 +#header #session-links #sign-out {
  97 + background: transparent url(images/icons/bullet-red-sm.png) 12px 50% no-repeat;
  98 + padding-left: 29px;
  99 +}
  100 +#header #session-links a:hover {
  101 + text-decoration: none;
  102 +}
  103 +
  104 +/* Navigation */
  105 +#nav-bar {
  106 + position: absolute;
  107 + bottom: 0;
  108 + left: 172px;
  109 +}
  110 +#nav-bar li {
  111 + float: left;
  112 + height: 34px;
  113 + margin-right: 12px;
  114 + color: #666;
  115 + background-color: #d0d0d0;
  116 + background-image: none;
  117 + border-top-left-radius: 12px;
  118 + border-top-right-radius: 12px;
  119 + -moz-border-top-left-radius: 12px;
  120 + -moz-border-top-right-radius: 12px;
  121 + -webkit-border-top-left-radius: 12px;
  122 + -webkit-border-top-right-radius: 12px;
  123 + border: 1px solid #bbb;
  124 +}
  125 +#nav-bar li.active {
  126 + border-color: #fff;
  127 + background: #FFF url(images/button-bg.png) 0 -2px repeat-x;
  128 + border-width:1px 1px 0;
  129 + margin-bottom:-2px;
  130 + height: 37px;
  131 +}
  132 +#nav-bar li.active a {
  133 + color: #333;
  134 +}
  135 +
  136 +#nav-bar li a {
  137 + color: #666;
  138 + display: block;
  139 + padding: 0 20px 0 40px;
  140 + font-size: 14px;
  141 + font-weight: bold;
  142 + line-height: 37px;
  143 + text-decoration: none;
  144 + text-shadow: 1px 1px 0px #FFF;
  145 + -webkit-text-shadow: 1px 1px 0px #FFF;
  146 + background: transparent 10px 6px no-repeat;
  147 +}
  148 +#nav-bar li a:hover { color: #666;}
  149 +#nav-bar li.apps a { background-image: url(images/icons/briefcase.png); }
  150 +#nav-bar li.errs a { background-image: url(images/icons/error.png); }
  151 +#nav-bar li.users a { background-image: url(images/icons/user.png); }
  152 +#nav-bar li:not(.active):hover {
  153 + box-shadow: 0 0 3px #69c;
  154 + -moz-box-shadow: 0 0 3px #69c;
  155 + -webkit-box-shadow: 0 0 3px #69c;
  156 +}
  157 +
  158 +/* Content Wrapper */
  159 +#content-wrapper {
  160 + border: 1px solid #C6C6C6;
  161 +}
  162 +
  163 +/* Content Title and Comments */
  164 +#content-title, #content-comments {
  165 + padding: 30px 20px;
  166 + border-top: 1px solid #FFF;
  167 + border-bottom: 1px solid #FFF;
  168 + background-color: #ececec;
  169 +}
  170 +#content-comments {
  171 + background-color: #ffffff;
  172 +}
  173 +#content-title h1, #content-comments h3 {
  174 + padding: 0; margin: 0;
  175 + width: 85%;
  176 + border: none;
  177 + color: #636363;
  178 + font-size: 2em; line-height: 1em; font-weight: bold; font-family: arial, sans-serif;
  179 + word-wrap: break-word;
  180 +}
  181 +#content-comments h3 {
  182 + font-size: 1.5em;
  183 + margin-bottom: 14px;
  184 +}
  185 +
  186 +#content-title .meta { font-size: 0.9em; color: #787878; }
  187 +
  188 +/* Action Bar */
  189 +#action-bar {
  190 + position: absolute;
  191 + top: 25px; right: 20px;
  192 +}
  193 +#action-bar span {
  194 + display: inline-block;
  195 + margin-left: 18px;
  196 + text-decoration: none;
  197 + color: #666;
  198 + background: #FFF url(images/button-bg.png) 0 bottom repeat-x;
  199 + border-radius: 50px;
  200 + -moz-border-radius: 50px;
  201 + -webkit-border-radius: 50px;
  202 + border: 1px solid #bbb;
  203 +}
  204 +#action-bar span a {
  205 + color: #666;
  206 + display: block;
  207 + padding: 0 20px 0 40px;
  208 + font-size: 14px; font-weight: bold; line-height: 39px; text-decoration: none;
  209 + text-shadow: 1px 1px 0px #FFF; -webkit-text-shadow: 1px 1px 0px #FFF;
  210 + background: transparent 10px 8px no-repeat;
  211 +}
  212 +#action-bar a:hover { text-decoration: none;}
  213 +#action-bar span:hover {
  214 + box-shadow: 0 0 3px #69c;
  215 + -moz-box-shadow: 0 0 3px #69c;
  216 + -webkit-box-shadow: 0 0 3px #69c;
  217 +}
  218 +#action-bar a.add {
  219 + background-image: url(images/icons/add.png);
  220 +}
  221 +
  222 +#action-bar .calendar_link {
  223 + background: url(images/icons/ical.png) no-repeat scroll 12px 6px transparent;
  224 + padding-left: 47px;
  225 +}
  226 +
  227 +
  228 +/* Content */
  229 +#content {
  230 + padding: 20px; border-top: 1px solid #C6C6C6;
  231 + background-color: #FFF;
  232 +}
  233 +
  234 +#content a.button {
  235 + float: right;
  236 + display: block;
  237 + margin-bottom: 10px;
  238 +}
  239 +
  240 +/* Footer */
  241 +#footer {
  242 + padding: 20px 0;
  243 + font-size: 0.8em; text-align: center;
  244 + color: #929292;
  245 +}
  246 +
  247 +/* Flash Messages */
  248 +#flash-messages li {
  249 + padding: 13px 45px;
  250 + margin-bottom:25px;
  251 + border: 1px solid #C6C6C6;
  252 + background-color: #F9F9F9;
  253 + line-height: 1em;
  254 +}
  255 +#flash-messages li.notice {
  256 + padding-left: 20px;
  257 + background-color: #b5eeff;
  258 + border: 1px solid #6cf;
  259 +}
  260 +#flash-messages li.success {
  261 + background: #cfc url(images/icons/success.png) 16px 50% no-repeat;
  262 + border: 1px solid #6c3;
  263 +}
  264 +#flash-messages li.error {
  265 + background: #fcc url(images/icons/error.png) 16px 50% no-repeat;
  266 + border: 1px solid #f99;
  267 +}
  268 +#flash-messages .alert {
  269 + background: #ffc url(images/icons/warning.png) 10px 7px no-repeat;
  270 + border-color: #e4bb69;
  271 +}
  272 +
  273 +/* Forms */
  274 +form#new_user,
  275 +form.edit_user,
  276 +form#new_app,
  277 +form.edit_app {
  278 + width: 620px;
  279 +}
  280 +form > div, form fieldset > div { margin: 1em 0;}
  281 +form fieldset {
  282 + padding: 0.8em; margin-bottom: 1em;
  283 + background-color: #F0F0F0; border: 1px solid #C6C6C6; border-left: none; border-right: none;
  284 +}
  285 +form fieldset legend {
  286 + font-size: 1.2em; font-weight: bold; text-transform: uppercase;
  287 + color: #555;
  288 +}
  289 +form label {
  290 + font-weight: bold; text-transform: uppercase; line-height: 1.6em;
  291 + display: inline-block;
  292 +}
  293 +form label.inline { display: inline; }
  294 +form .checkbox label { display: inline; }
  295 +form .required label { padding-right: 20px; background: transparent url(images/icons/required.png) right 50% no-repeat; }
  296 +form .field_with_errors label { color: #900; }
  297 +form input[type=text], form input[type=password] {
  298 + width: 96%; padding: 0.8em;
  299 + font-size: 1em;
  300 + color: #787878; border: 1px solid #C6C6C6;
  301 +}
  302 +form textarea {
  303 + width: 100%; padding: 0.8em;
  304 + font-size: inherit; font-family: inherit;
  305 + color: #787878; border: 1px solid #C6C6C6;
  306 +}
  307 +form textarea.short { height: 8em; }
  308 +form textarea.supershort { height: 4em; }
  309 +form input[type=text]:focus, form input[type=password]:focus, form textarea:focus {
  310 + box-shadow: 0px 0px 4px #69C;
  311 + -moz-box-shadow: 0px 0px 4px #69C;
  312 + -webkit-box-shadow: 0px 0px 4px #69C
  313 +}
  314 +form input[type=checkbox]:focus + label{
  315 + color: #69C;
  316 +}
  317 +form input[type=submit] {
  318 + display:block; width: auto; padding: 0.5em;
  319 + font-size: 1.2em; line-height: 1em; text-transform: uppercase;
  320 + border: none; color: #FFF; background-color: #387fc1;
  321 +}
  322 +form input[type=submit].button {
  323 + font-size: 1em;
  324 + text-transform: none;
  325 +}
  326 +form div.buttons {
  327 + color: #666;
  328 + background: #FFF url(images/button-bg.png) 0 bottom repeat-x;
  329 + border-radius: 50px;
  330 + -moz-border-radius: 50px;
  331 + -webkit-border-radius: 50px;
  332 + border: 1px solid #bbb;
  333 + display: inline-block;
  334 +}
  335 +form div.buttons:hover {
  336 + color: #666;
  337 + box-shadow: 0 0 3px #69c;
  338 + -moz-box-shadow: 0 0 3px #69c;
  339 + -webkit-box-shadow: 0 0 3px #69c;
  340 +}
  341 +form div.buttons input, form div.buttons button {
  342 + padding: 0 20px;
  343 + color: #666;
  344 + background: none;
  345 + display: inline-block;
  346 + height: 36px;
  347 + font-size: 14px; font-weight: bold; line-height: 36px; text-decoration: none;
  348 + text-shadow: 1px 1px 0px #FFF;
  349 + -moz-text-shadow: 1px 1px 0px #FFF;
  350 + -webkit-text-shadow: 1px 1px 0px #FFF;
  351 + border: none;
  352 +}
  353 +form div.buttons button.sign_in {
  354 + padding-left: 40px;
  355 + background: transparent url(images/icons/right-arrow.png) 3px 3px no-repeat;
  356 +}
  357 +form strong.option {
  358 + display: block;
  359 + margin: 0.7em 0;
  360 + color: #999;
  361 +}
  362 +
  363 +form .nested {
  364 + border-top: 1px dotted #BBB;
  365 + margin-top: 1.5em;
  366 + padding-top: 1.5em;
  367 +}
  368 +
  369 +form legend + .nested {
  370 + border: none;
  371 + margin-top: 0;
  372 + padding-top: 0;
  373 +}
  374 +
  375 +form .error-messages {
  376 + padding: 13px;
  377 + background: #fcc;
  378 + border: 1px solid #f99;
  379 +}
  380 +
  381 +form .error-messages h2 {
  382 + font-size: 1.2em;
  383 + border-color: #F99;
  384 +}
  385 +form .error-messages ul {
  386 + margin-left: 2em;
  387 + list-style-type: square;
  388 +}
  389 +
  390 +form .field-helpertext {
  391 + display: inline;
  392 +}
  393 +
  394 +form input#app_email_at_notices {
  395 + width: 130px;
  396 + margin: 0 5px;
  397 +}
  398 +
  399 +
  400 +/* Tables */
  401 +table {
  402 + width: 100%;
  403 + border: 1px solid #C6C6C6;
  404 + margin-bottom: 1.5em;
  405 + border-collapse: separate;
  406 +}
  407 +table thead th {
  408 + border-top: 1px solid #FFF;
  409 + border-bottom: 1px solid #FFF;
  410 +}
  411 +table th, table td {
  412 + border-top: 1px solid #C6C6C6;
  413 + padding: 10px 8px;
  414 + text-align: left;
  415 +}
  416 +table tbody tr:first-child th, table tbody tr:first-child td {
  417 + border-top: none;
  418 +}
  419 +table thead + tbody tr:first-child td {
  420 + border-top: 1px solid #C6C6C6;
  421 +}
  422 +table th { background-color: #ececec; font-weight: bold; text-transform: uppercase; white-space: nowrap; }
  423 +table tbody tr:nth-child(odd) td { background-color: #F9F9F9; }
  424 +table .main { width: 100%; }
  425 +
  426 +table.single_user {
  427 + border-top: none;
  428 +}
  429 +
  430 +.raw_data {
  431 + width: 100%;
  432 + color: #f0f0f0;
  433 + background-color: #222;
  434 + overflow: auto;
  435 +}
  436 +
  437 +/* Code */
  438 +pre {
  439 + padding: 0.8em;
  440 + margin-bottom: 1em;
  441 + font-family: monaco, courier, monospace;
  442 + font-size: 1.1em;
  443 +}
  444 +
  445 +/* HTML Styling */
  446 +.html { padding-left: 1em; border-left: 2px solid #C6C6C6;}
  447 +.html h1, .html h2, .html h3, .html h4, .html h5, .html h6 {
  448 + border: none;
  449 +}
  450 +.html ul, .html ol { margin-left: 2em; margin-bottom: 1em; }
  451 +.html ul li { margin-bottom: 0.5em; list-style: disc; }
  452 +.html ol li { margin-bottom: 0.5em; list-style: decimal; }
  453 +
  454 +/* Pagination */
  455 +.pagination {
  456 + margin: 0 0 25px;
  457 + font-size: 17px;
  458 + text-align: center;
  459 +}
  460 +.pagination em {
  461 + font-style: normal;
  462 + font-weight: bold;
  463 +}
  464 +
  465 +
  466 +/* Buttons */
  467 +input[type="submit"].button,
  468 +a.button {
  469 + display: inline-block;
  470 + padding: 0 0.8em;
  471 + margin-left: 0.5em;
  472 + color: #666;
  473 + background-color: #dadada;
  474 + border: 1px solid #BBB;
  475 + border-radius: 30px;
  476 + -moz-border-radius: 30px;
  477 + -webkit-border-radius: 30px;
  478 + line-height: 30px;
  479 + min-width: 54px;
  480 + text-align: center;
  481 + text-shadow: 0 1px 0 #fff;
  482 +}
  483 +input[type="submit"]:hover.button,
  484 +a:hover.button {
  485 + box-shadow: 0px 0px 4px #bfbfbf;
  486 + -moz-box-shadow: 0px 0px 4px #bfbfbf;
  487 + -webkit-box-shadow: 0px 0px 4px #bfbfbf;
  488 + text-decoration: none;
  489 + background-color: #e5e5e5;
  490 +}
  491 +a.button.active {
  492 + border-color: #fff;
  493 + background-color: #CCC;
  494 + background-image: none;
  495 +}
  496 +
  497 +
  498 +/* Tab Bar */
  499 +.tab-bar {
  500 + margin-top: 12px;
  501 +}
  502 +#content .tab-bar a.button {
  503 + border-bottom:0;
  504 + margin-bottom:0;
  505 + border-top-left-radius:12px;
  506 + border-top-right-radius:12px;
  507 + border-bottom-left-radius:0;
  508 + border-bottom-right-radius:0;
  509 + height:30px;
  510 +}
  511 +#content .tab-bar a.button.active {
  512 + background: #FFF;
  513 + color: #444;
  514 + border-color:#ccc;
  515 + border-style:solid;
  516 + border-width:1px 1px 0;
  517 + margin-bottom:-1px;
  518 + height:31px;
  519 +}
  520 +.tab-bar ul {
  521 + padding: 9px 0 0;
  522 + line-height:0;
  523 +}
  524 +.tab-bar li {
  525 + display: inline-block;
  526 +}
  527 +
  528 +/* Watchers and Issue Tracker Forms */
  529 +div.watcher.nested .watcher_params, div.issue_tracker.nested .tracker_params {
  530 + display: none;
  531 +}
  532 +div.nested .chosen {
  533 + display: block !important;
  534 +}
  535 +div.nested .choose {
  536 + margin-bottom: 0.5em;
  537 +}
  538 +
  539 +div.issue_tracker.nested .choose {
  540 + background-color: #ebebeb;
  541 + border: 1px solid #dddddd;
  542 + margin: 0 0 15px;
  543 + padding: 12px;
  544 +}
  545 +div.issue_tracker.nested img {
  546 + vertical-align: middle;
  547 +}
  548 +
  549 +/* Icons for Issue Tracker Radio Buttons */
  550 +div.issue_tracker.nested label.label_radio {
  551 + color: #929292;
  552 + padding-left: 33px;
  553 + margin-bottom: 6px;
  554 + margin-right: 8px;
  555 + line-height: 30px;
  556 +}
  557 +div.issue_tracker.nested .choose {
  558 + padding-bottom: 6px;
  559 +}
  560 +div.issue_tracker.nested label.label_radio:hover {
  561 + color: #696969;
  562 +}
  563 +div.issue_tracker.nested .label_radio input {
  564 + position: absolute; left: -9999px;
  565 +}
  566 +
  567 +div.issue_tracker.nested label.r_on, div.issue_tracker.nested label.r_on:hover {
  568 + color: #191919;
  569 +}
  570 +
  571 +/* Icons need to be preloaded, otherwise it looks bad */
  572 +.image_preloader { display: none; }
  573 +
  574 +/* Apps Table */
  575 +table.apps tbody tr:hover td ,table.errs tbody tr:hover td { background-color: #F2F2F2;}
  576 +
  577 +table.apps td.name, table.errs td.message {
  578 + width: 100%;
  579 +}
  580 +td.message .line {
  581 + display:inline-block;
  582 + margin-left:1em;
  583 +}
  584 +td.deploy {
  585 + white-space: nowrap;
  586 +}
  587 +td.latest {
  588 + white-space: nowrap;
  589 +}
  590 +td.count, td.issue_link {
  591 + text-align: center;
  592 +}
  593 +
  594 +.count a {
  595 + display: inline-block;
  596 + padding: 0.1em 0.7em;
  597 + margin-top: 3px;
  598 + color: #fff;
  599 + background: #cc0033 url(images/error-badge-bg.png) 0 bottom repeat-x;
  600 + border: 1px solid #900;
  601 + border-radius: 18px;
  602 + -moz-border-radius: 18px;
  603 + -webkit-border-radius: 18px;
  604 + font-weight: bold;
  605 + opacity: 0.8;
  606 + -moz-opacity: 0.8;
  607 + -webkit-opacity: 0.8
  608 +}
  609 +.count a.resolved {
  610 + background: #05B81d url(images/resolved-badge-bg.png) 0 bottom repeat-x;
  611 + border: 1px solid #080;
  612 +}
  613 +.count a:hover {
  614 + text-decoration: none;
  615 + opacity: 1;
  616 + -moz-opacity: 1;
  617 + -webkit-opacity: 1;
  618 +}
  619 +
  620 +/* Err Tables */
  621 +table.errs td.app {
  622 + padding-right: 2em;
  623 + width: 20%;
  624 +}
  625 +table.errs td.app .environment {
  626 + font-size: 0.8em;
  627 + color: #999;
  628 +}
  629 +table.errs td.message a {
  630 + display: block;
  631 + word-wrap: break-word;
  632 +}
  633 +table.errs td.message em {
  634 + color: #727272;
  635 + font-size: 0.9em;
  636 +}
  637 +
  638 +table.errs tr.resolved td > * {
  639 + opacity: 0.5;
  640 + -moz-opacity: 0.5;
  641 + -webkit-opacity: 0.5;
  642 +}
  643 +
  644 +/* Tally tables */
  645 +table.tally {
  646 + border:none;
  647 +}
  648 +table.tally td,
  649 +table.tally th {
  650 + border:none !important;
  651 + background:none !important;
  652 + padding:8px 0 0;
  653 +}
  654 +table.tally tbody tr:first-child td,
  655 +table.tally tbody tr:first-child th {
  656 + padding-top:0;
  657 +}
  658 +table.tally td.percent {
  659 + width:4.5em;
  660 +}
  661 +table.tally th.value {
  662 + text-transform:none;
  663 +}
  664 +
  665 +/* Deploys table */
  666 +table.deploys td.when {
  667 + width: 102px;
  668 +}
  669 +
  670 +/* Resolve Errs */
  671 +#action-bar a.resolve {
  672 + background: transparent url(images/icons/thumbs-up.png) 6px 5px no-repeat;
  673 +}
  674 +
  675 +/* Go Up */
  676 +#action-bar a.up {
  677 + background: transparent url(images/icons/up.png) 6px 5px no-repeat;
  678 +}
  679 +
  680 +/* Notices Pagination */
  681 +.notice-pagination {
  682 + float: left;
  683 + margin-right: 10px;
  684 +}
  685 +
  686 +.notice-pagination-loader {
  687 + visibility: hidden;
  688 + float: left;
  689 + margin-right: 2em;
  690 +}
  691 +.notice-pagination-loader img {
  692 + vertical-align: middle
  693 +}
  694 +
  695 +
  696 +/* Backtrace */
  697 +.window {
  698 + width: 100%;
  699 + margin-bottom: 1em;
  700 + overflow: auto;
  701 + border:1px solid #ccc;
  702 + padding:1px;
  703 +}
  704 +
  705 +.window table {
  706 + margin: 0;
  707 +}
  708 +
  709 +table.backtrace {
  710 + padding: 8px 0;
  711 + background-color: #222;
  712 +}
  713 +
  714 +table.backtrace td {
  715 + width: 100%;
  716 + padding: 0;
  717 + margin: 0;
  718 + color: #C7C7C7;
  719 + background-color: #222;
  720 +}
  721 +
  722 +table.backtrace td, table.backtrace th {
  723 + border-top: none;
  724 +}
  725 +
  726 +/* remove alternating color rules */
  727 +table.backtrace tr:nth-child(2n+1) td { background-color: #222; }
  728 +table.backtrace tr:first-child td { border-top: 0; }
  729 +
  730 +table.backtrace th.line-numbers {
  731 + border-bottom: 1px solid #F0F0F0;
  732 + font-size: 13px;
  733 + text-align: right;
  734 + vertical-align: top;
  735 + padding: 1px 6px 1px 7px;
  736 +}
  737 +
  738 +table.backtrace td.line {
  739 + font-size: 13px;
  740 + padding: 2px 8px;
  741 + vertical-align: top;
  742 + white-space: nowrap;
  743 +}
  744 +table.backtrace td.line .file {
  745 + font-weight: bold;
  746 +}
  747 +table.backtrace td.line .method {
  748 + color: #aaa;
  749 + font-weight: bold;
  750 +}
  751 +
  752 +table.backtrace td.line.in-app {
  753 + color: #2adb2e;
  754 + background-color: #2f2f2f;
  755 +}
  756 +table.backtrace td.line.in-app .path,
  757 +table.backtrace td.line.in-app .number { color: #2ACB2E; }
  758 +table.backtrace td.line.in-app .file { color: #3AFB3E; }
  759 +table.backtrace td.line.in-app .method { color: #2ACB2E; }
  760 +
  761 +table.backtrace td.line.in-app a .path,
  762 +table.backtrace td.line.in-app a .number,
  763 +table.backtrace td.line.in-app a:hover { color: #21B4FF; }
  764 +table.backtrace td.line.in-app a .file { color: #31C4FF; }
  765 +
  766 +/* External backtrace classes and separators */
  767 +table.backtrace tr.hidden_external_backtrace {
  768 + display: none;
  769 +}
  770 +table.backtrace td.backtrace_separator span {
  771 + cursor: pointer;
  772 + display: inline-block;
  773 + font-size: 17px;
  774 + font-weight: bold;
  775 + padding: 0px 11px 5px;
  776 + margin: 4px 0;
  777 + background-color: #444444;
  778 + border: 1px solid #555555;
  779 +}
  780 +table.backtrace td.backtrace_separator span:hover {
  781 + background-color: #666666;
  782 + border: 1px solid #777777;
  783 +}
  784 +
  785 +
  786 +
  787 +/* Extra empty rows at top and bottom of table */
  788 +table.backtrace tr.padding th, table.backtrace tr.padding td {
  789 + height: 10px;
  790 + margin: 0;
  791 + padding: 0;
  792 +}
  793 +
  794 +h3#watchers_toggle, h3#repository_toggle, h3#deploys_toggle {
  795 + cursor: pointer;
  796 +}
  797 +
  798 +span.click_span {
  799 + font-size: 0.7em;
  800 +}
  801 +
  802 +#deploys_div, #repository_div, #watchers_div {
  803 + display: none;
  804 +}
  805 +
  806 +/* Comments */
  807 +#content-comments form p {
  808 + margin: 30px 0 0 0;
  809 + text-transform: uppercase;
  810 +}
  811 +table.comment tbody th {
  812 + text-transform: none;
  813 + font-weight: normal;
  814 + height: 20px;
  815 + line-height: 0.5em;
  816 +}
  817 +table.comment tbody td {
  818 + background-color: #F9F9F9;
  819 +}
  820 +#content-comments a.destroy-comment {
  821 + color: #EE0000;
  822 + margin-right: 5px;
  823 +}
  824 +#content-comments a.destroy-comment:hover {
  825 + text-decoration: none;
  826 +}
  827 +#content-comments #comment_submit {
  828 + margin-top: 15px;
  829 +}
  830 +/* Inline comments in tables */
  831 +table.errs tr td.message .inline_comment {
  832 + display: inline-block;
  833 + padding: 3px 7px;
  834 + margin: 6px 0;
  835 + background-color: #DAE5FF;
  836 + border: 1px solid #E2E2E2;
  837 + text-shadow: 0 1px 0 #FAFAFA;
  838 + font-style: normal;
  839 +}
  840 +table.errs tr:hover td.message .inline_comment {
  841 + background-color: #D5E0FA;
  842 + border-color: #DBDBDB;
  843 + text-shadow: 0 1px 0 #FFFFFF;
  844 +}
  845 +table.errs tr td.message .inline_comment em {
  846 + color: #444;
  847 +}
  848 +table.errs tr td.message .inline_comment em.commenter {
  849 + color: #777;
  850 +}
  851 +
  852 +.current.asc:after { content: ' ↑'; }
  853 +.current.desc:after { content: ' ↓'; }
  854 +
  855 +span.github a { background: url(../images/github.png) no-repeat 5px 5px; }
... ...
app/assets/stylesheets/images/button-bg.png 0 → 100644

148 Bytes

app/assets/stylesheets/images/content-fade.png 0 → 100644

174 Bytes

app/assets/stylesheets/images/error-badge-bg.png 0 → 100644

119 Bytes

app/assets/stylesheets/images/header.png 0 → 100644

196 Bytes

app/assets/stylesheets/images/icons/add.png 0 → 100644

1.04 KB

app/assets/stylesheets/images/icons/briefcase.png 0 → 100644

675 Bytes

app/assets/stylesheets/images/icons/bullet-red-sm.png 0 → 100644

417 Bytes

app/assets/stylesheets/images/icons/cross.png 0 → 100755

473 Bytes

app/assets/stylesheets/images/icons/edit.png 0 → 100644

1.22 KB

app/assets/stylesheets/images/icons/error.png 0 → 100644

1.05 KB

app/assets/stylesheets/images/icons/ical.png 0 → 100644

1.86 KB

app/assets/stylesheets/images/icons/notice.png 0 → 100644

157 Bytes

app/assets/stylesheets/images/icons/required.png 0 → 100644

250 Bytes

app/assets/stylesheets/images/icons/right-arrow.png 0 → 100644

1.11 KB

app/assets/stylesheets/images/icons/success.png 0 → 100644

1.06 KB

app/assets/stylesheets/images/icons/thumbs-up.png 0 → 100644

1.42 KB

app/assets/stylesheets/images/icons/trash.png 0 → 100644

1.65 KB

app/assets/stylesheets/images/icons/up.png 0 → 100644

1.11 KB

app/assets/stylesheets/images/icons/user.png 0 → 100644

877 Bytes

app/assets/stylesheets/images/icons/warning.png 0 → 100644

674 Bytes

app/assets/stylesheets/images/logo.png 0 → 100644

3.21 KB

app/assets/stylesheets/images/notebook.png 0 → 100644

133 Bytes

app/assets/stylesheets/images/resolved-badge-bg.png 0 → 100644

119 Bytes

app/assets/stylesheets/issue_tracker_icons.css.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +/* Issue Tracker inactive, select, create and goto icons */
  2 +<% trackers = IssueTracker.subclasses.map{|t| t::Label } << 'none' %>
  3 +<% trackers.each do |tracker| %>
  4 +div.issue_tracker.nested label.<%= tracker %> {
  5 + background: url(/assets/<%= tracker %>_inactive.png) no-repeat;
  6 +}
  7 +div.issue_tracker.nested label.r_on.<%= tracker %> {
  8 + background: url(/assets/<%= tracker %>_create.png) no-repeat;
  9 +}
  10 +#action-bar a.<%= tracker %>_create {
  11 + background: transparent url(/assets/<%= tracker %>_create.png) 6px 5px no-repeat;
  12 +}
  13 +#action-bar a.<%= tracker %>_goto {
  14 + background: transparent url(/assets/<%= tracker %>_goto.png) 6px 5px no-repeat;
  15 +}
  16 +<% end %>
... ...
app/assets/stylesheets/jquery.alerts.css 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +#popup_container {
  2 + font-family: Arial, sans-serif;
  3 + font-size: 12px;
  4 + min-width: 300px; /* Dialog will be no smaller than this */
  5 + max-width: 600px; /* Dialog will wrap after this width */
  6 + background: #FFF;
  7 + border: solid 5px #999;
  8 + color: #000;
  9 + -moz-border-radius: 5px;
  10 + -webkit-border-radius: 5px;
  11 + border-radius: 5px;
  12 +}
  13 +
  14 +#popup_title {
  15 + font-size: 14px;
  16 + font-weight: bold;
  17 + text-align: center;
  18 + line-height: 1.75em;
  19 + color: #666;
  20 + background: #CCC url(/images/alerts/title.gif) top repeat-x;
  21 + border: solid 1px #FFF;
  22 + border-bottom: solid 1px #999;
  23 + cursor: default;
  24 + padding: 0em;
  25 + margin: 0em;
  26 +}
  27 +
  28 +#popup_content {
  29 + background: 16px 16px no-repeat url(/images/alerts/info.gif);
  30 + padding: 1em 1.75em;
  31 + margin: 0em;
  32 +}
  33 +
  34 +#popup_content.alert {
  35 + background-image: url(/images/alerts/info.gif);
  36 +}
  37 +
  38 +#popup_content.confirm {
  39 + background-image: url(/images/alerts/important.gif);
  40 +}
  41 +
  42 +#popup_content.prompt {
  43 + background-image: url(/images/alerts/help.gif);
  44 +}
  45 +
  46 +#popup_message {
  47 + padding-left: 48px;
  48 +}
  49 +
  50 +#popup_panel {
  51 + text-align: center;
  52 + margin: 1em 0em 0em 1em;
  53 +}
  54 +
  55 +#popup_prompt {
  56 + margin: .5em 0em;
  57 +}
0 58 \ No newline at end of file
... ...
app/assets/stylesheets/mailers/mailer.css 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +td.header {
  2 + padding: 10px 20px 8px 20px;
  3 + height: 70px;
  4 + background-color: #11112f;
  5 + text-align: left;
  6 + border-bottom: 1px solid #ccccee;
  7 +}
  8 + td.header a {
  9 + display: block;
  10 + height: 31px;
  11 + width: 88px;
  12 + margin-top: 4px;
  13 + }
  14 + /* Style 'Errbit' logo alt text if image cannot be loaded. */
  15 + td.header a img {
  16 + border: none;
  17 + color: #E3E3E3;
  18 + font-family: helvetica;
  19 + font-size: 30px;
  20 + font-weight: bold;
  21 + min-height: 31px;
  22 + text-shadow: 0 1px 0 #EEEEFF;
  23 + }
  24 +
  25 +td.section, td.content, td.footer {
  26 + font-family: Helvetica,Arial,sans-serif;
  27 + font-size: 14px;
  28 + background-color: #ffffff;
  29 + text-align: left;
  30 +}
  31 +td.section {
  32 + padding: 0;
  33 + border-bottom: 1px solid #dddddd;
  34 +}
  35 +td.content {
  36 + padding: 20px 20px 10px 20px;
  37 + line-height: 1.3em;
  38 +}
  39 +td.footer {
  40 + padding: 10px 20px 20px 20px;
  41 + font-size: 11px;
  42 + font-weight: bold;
  43 + color: #666666;
  44 +}
  45 +
  46 +a.bold, span.bold { font-weight: bold; }
  47 +
  48 +p { margin: 0 0 15px 0; }
  49 +p.heading {
  50 + color: #6a6a6a;
  51 + margin-bottom: 4px;
  52 +}
  53 +p.monospace, p.backtrace { font-family: monospace; }
  54 +p.backtrace { margin-bottom: 2px; }
  55 +
... ...
app/assets/stylesheets/reset.css 0 → 100644
... ... @@ -0,0 +1,74 @@
  1 +/*
  2 + * Reset.css - by Eric Meyer
  3 + * Modified for NewsStand
  4 + * By Jared Pace
  5 + * Codeword: Studios
  6 + */
  7 +
  8 + html, body, div, span, applet, object, iframe,
  9 + h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  10 + a, abbr, acronym, address, big, cite, code,
  11 + del, dfn, em, font, img, ins, kbd, q, s, samp,
  12 + small, strike, strong, sub, sup, tt, var,
  13 + b, u, i, center,
  14 + dl, dt, dd, ol, ul, li,
  15 + fieldset, form, label, legend,
  16 + table, caption, tbody, tfoot, thead, tr, th, td {
  17 + margin: 0;
  18 + padding: 0;
  19 + border: 0;
  20 + outline: 0;
  21 + font-size: 100%;
  22 + vertical-align: baseline;
  23 + background: transparent;
  24 + }
  25 + body {
  26 + line-height: 1;
  27 + }
  28 + ol, ul {
  29 + list-style: none;
  30 + }
  31 + blockquote, q {
  32 + quotes: none;
  33 + }
  34 + td {
  35 + vertical-align: top;
  36 +}
  37 +
  38 + /* remember to define focus styles! */
  39 + :focus {
  40 + outline: 0;
  41 + }
  42 +
  43 + /* remember to highlight inserts somehow! */
  44 + ins {
  45 + text-decoration: none;
  46 + }
  47 + del {
  48 + text-decoration: line-through;
  49 + }
  50 +
  51 + /* tables still need 'cellspacing="0"' in the markup */
  52 + table {
  53 + border-collapse: collapse;
  54 + border-spacing: 0;
  55 + }
  56 +
  57 + sup, sub {
  58 + height: 0;
  59 + line-height: 1;
  60 + vertical-align: baseline;
  61 + _vertical-align: bottom;
  62 + position: relative;
  63 + font-size: 0.8em;
  64 + }
  65 +
  66 + sup {
  67 + bottom: 1ex;
  68 + }
  69 +
  70 + sub {
  71 + top: .5ex;
  72 + }
  73 +
  74 +p { margin-bottom: 1em; }
0 75 \ No newline at end of file
... ...
app/controllers/errs_controller.rb
... ... @@ -39,7 +39,11 @@ class ErrsController &lt; ApplicationController
39 39 set_tracker_params
40 40  
41 41 if @app.issue_tracker
42   - @app.issue_tracker.create_issue @problem
  42 + begin
  43 + @app.issue_tracker.create_issue @problem, current_user
  44 + rescue IssueTrackers::IssueTrackerError => ex
  45 + flash[:error] = ex.message
  46 + end
43 47 else
44 48 flash[:error] = "This app has no issue tracker setup."
45 49 end
... ...
app/helpers/notices_helper.rb
1 1 # encoding: utf-8
2 2 module NoticesHelper
3   - def notice_atom_summary notice
  3 + def in_app_backtrace_line?(line)
  4 + !!(line['file'] =~ %r{^\[PROJECT_ROOT\]/(?!(vendor))})
  5 + end
  6 +
  7 + def notice_atom_summary(notice)
4 8 render :partial => "notices/atom_entry.html.haml", :locals => {:notice => notice}
5 9 end
6 10  
7   - def link_to_source_file(app, line, text)
8   - if Notice.in_app_backtrace_line?(line)
  11 + def link_to_source_file(app, line, &block)
  12 + text = capture_haml(&block)
  13 + if in_app_backtrace_line?(line)
9 14 return link_to_github(app, line, text) if app.github_url?
10 15 if app.issue_tracker && app.issue_tracker.respond_to?(:url_to_file)
11 16 # Return link to file on tracker if issue tracker supports this
... ... @@ -30,5 +35,34 @@ module NoticesHelper
30 35 href = app.issue_tracker.url_to_file(file_path, line['number'])
31 36 link_to(text || file_name, href, :target => '_blank')
32 37 end
  38 +
  39 + # Group lines into sections of in-app files and external files
  40 + # (An implementation of Enumerable#chunk so we don't break 1.8.7 support.)
  41 + def grouped_lines(lines)
  42 + line_groups = []
  43 + lines.each do |line|
  44 + in_app = in_app_backtrace_line?(line)
  45 + if line_groups.last && line_groups.last[0] == in_app
  46 + line_groups.last[1] << line
  47 + else
  48 + line_groups << [in_app, [line]]
  49 + end
  50 + end
  51 + line_groups
  52 + end
  53 +
  54 + def path_for_backtrace_line(line)
  55 + path = File.dirname(line['file'])
  56 + return '' if path == '.'
  57 + # Remove [PROJECT_ROOT]
  58 + path.gsub!('[PROJECT_ROOT]/', '')
  59 + # Make gem name bold if starts with [GEM_ROOT]/gems
  60 + path.gsub!(/\[GEM_ROOT\]\/gems\/([^\/]+)/, "<strong>\\1</strong>")
  61 + (path << '/').html_safe
  62 + end
  63 +
  64 + def file_for_backtrace_line(line)
  65 + file = File.basename(line['file'])
  66 + end
33 67 end
34 68  
... ...
app/models/app.rb
... ... @@ -47,7 +47,7 @@ class App
47 47 #
48 48 # Accepts either XML or a hash with the following attributes:
49 49 #
50   - # * <tt>:klass</tt> - the class of error
  50 + # * <tt>:error_class</tt> - the class of error
51 51 # * <tt>:message</tt> - the error message
52 52 # * <tt>:backtrace</tt> - an array of stack trace lines
53 53 #
... ... @@ -67,7 +67,7 @@ class App
67 67 #
68 68 # Accepts a hash with the following attributes:
69 69 #
70   - # * <tt>:klass</tt> - the class of error
  70 + # * <tt>:error_class</tt> - the class of error
71 71 # * <tt>:message</tt> - the error message
72 72 # * <tt>:backtrace</tt> - an array of stack trace lines
73 73 #
... ...
app/models/err.rb
... ... @@ -6,7 +6,7 @@ class Err
6 6 include Mongoid::Document
7 7 include Mongoid::Timestamps
8 8  
9   - field :klass
  9 + field :error_class
10 10 field :component
11 11 field :action
12 12 field :environment
... ... @@ -14,11 +14,11 @@ class Err
14 14  
15 15 belongs_to :problem
16 16 index :problem_id
17   - index :klass
  17 + index :error_class
18 18  
19 19 has_many :notices, :inverse_of => :err, :dependent => :destroy
20 20  
21   - validates_presence_of :klass, :environment
  21 + validates_presence_of :error_class, :environment
22 22  
23 23 delegate :app, :resolved?, :to => :problem
24 24  
... ...
app/models/error_report.rb
... ... @@ -2,7 +2,7 @@ require &#39;digest/md5&#39;
2 2 require 'hoptoad_notifier'
3 3  
4 4 class ErrorReport
5   - attr_reader :klass, :message, :backtrace, :request, :server_environment, :api_key, :notifier
  5 + attr_reader :error_class, :message, :backtrace, :request, :server_environment, :api_key, :notifier, :user_attributes
6 6  
7 7 def initialize(xml_or_attributes)
8 8 @attributes = (xml_or_attributes.is_a?(String) ? Hoptoad.parse_xml!(xml_or_attributes) : xml_or_attributes).with_indifferent_access
... ... @@ -10,7 +10,11 @@ class ErrorReport
10 10 end
11 11  
12 12 def fingerprint
13   - @fingerprint ||= Digest::MD5.hexdigest(backtrace[0].to_s)
  13 + normalized_backtrace = backtrace[0...3].map do |trace|
  14 + trace.merge 'method' => trace['method'].gsub(/[0-9_]{10,}+/, "__FRAGMENT__")
  15 + end
  16 +
  17 + @fingerprint ||= Digest::MD5.hexdigest(normalized_backtrace.to_s)
14 18 end
15 19  
16 20 def rails_env
... ... @@ -32,13 +36,15 @@ class ErrorReport
32 36 def generate_notice!
33 37 notice = Notice.new(
34 38 :message => message,
  39 + :error_class => error_class,
35 40 :backtrace => backtrace,
36 41 :request => request,
37 42 :server_environment => server_environment,
38   - :notifier => notifier)
  43 + :notifier => notifier,
  44 + :user_attributes => user_attributes)
39 45  
40 46 err = app.find_or_create_err!(
41   - :klass => klass,
  47 + :error_class => error_class,
42 48 :component => component,
43 49 :action => action,
44 50 :environment => rails_env,
... ...
app/models/issue_trackers/fogbugz_tracker.rb
... ... @@ -22,7 +22,7 @@ class IssueTrackers::FogbugzTracker &lt; IssueTracker
22 22 end
23 23 end
24 24  
25   - def create_issue(problem)
  25 + def create_issue(problem, reported_by = nil)
26 26 fogbugz = Fogbugz::Interface.new(:email => username, :password => password, :uri => "https://#{account}.fogbugz.com")
27 27 fogbugz.authenticate
28 28  
... ...
app/models/issue_trackers/github_issues_tracker.rb
... ... @@ -8,25 +8,28 @@ class IssueTrackers::GithubIssuesTracker &lt; IssueTracker
8 8 [:username, {
9 9 :placeholder => "Your username on Github"
10 10 }],
11   - [:api_token, {
12   - :placeholder => "Your Github API Token"
  11 + [:password, {
  12 + :placeholder => "Password for your account"
13 13 }]
14 14 ]
15 15  
16 16 def check_params
17 17 if Fields.detect {|f| self[f[0]].blank? }
18   - errors.add :base, 'You must specify your Github repository, username and API Token'
  18 + errors.add :base, 'You must specify your Github repository, username and password'
19 19 end
20 20 end
21 21  
22   - def create_issue(err)
23   - client = Octokit::Client.new(:login => username, :token => api_token)
24   - issue = client.create_issue(project_id, issue_title(err), body_template.result(binding).unpack('C*').pack('U*'), options = {})
25   - err.update_attribute :issue_link, issue.html_url
  22 + def create_issue(problem, reported_by = nil)
  23 + client = Octokit::Client.new(:login => username, :password => password)
  24 + begin
  25 + issue = client.create_issue(project_id, issue_title(problem), body_template.result(binding).unpack('C*').pack('U*'), options = {})
  26 + problem.update_attribute :issue_link, issue.html_url
  27 + rescue Octokit::Unauthorized
  28 + raise IssueTrackers::AuthenticationError, "Could not authenticate with Github. Please check your username and password."
  29 + end
26 30 end
27 31  
28 32 def body_template
29 33 @@body_template ||= ERB.new(File.read(Rails.root + "app/views/issue_trackers/github_issues_body.txt.erb").gsub(/^\s*/, ''))
30 34 end
31 35 end
32   -
... ...
app/models/issue_trackers/lighthouse_tracker.rb
... ... @@ -18,7 +18,7 @@ class IssueTrackers::LighthouseTracker &lt; IssueTracker
18 18 end
19 19 end
20 20  
21   - def create_issue(problem)
  21 + def create_issue(problem, reported_by = nil)
22 22 Lighthouse.account = account
23 23 Lighthouse.token = api_token
24 24 # updating lighthouse account
... ...
app/models/issue_trackers/mingle_tracker.rb
... ... @@ -27,7 +27,7 @@ class IssueTrackers::MingleTracker &lt; IssueTracker
27 27 end
28 28 end
29 29  
30   - def create_issue(problem)
  30 + def create_issue(problem, reported_by = nil)
31 31 properties = ticket_properties_hash
32 32 basic_auth = account.gsub(/https?:\/\//, "https://#{username}:#{password}@")
33 33 Mingle.set_site "#{basic_auth}/api/v1/projects/#{project_id}/"
... ...
app/models/issue_trackers/pivotal_labs_tracker.rb
... ... @@ -13,7 +13,7 @@ class IssueTrackers::PivotalLabsTracker &lt; IssueTracker
13 13 end
14 14 end
15 15  
16   - def create_issue(problem)
  16 + def create_issue(problem, reported_by = nil)
17 17 PivotalTracker::Client.token = api_token
18 18 PivotalTracker::Client.use_ssl = true
19 19 project = PivotalTracker::Project.find project_id.to_i
... ...
app/models/issue_trackers/redmine_tracker.rb
... ... @@ -25,7 +25,7 @@ class IssueTrackers::RedmineTracker &lt; IssueTracker
25 25 end
26 26 end
27 27  
28   - def create_issue(problem)
  28 + def create_issue(problem, reported_by = nil)
29 29 token = api_token
30 30 acc = account
31 31 RedmineClient::Base.configure do
... ...
app/models/notice.rb
... ... @@ -10,7 +10,8 @@ class Notice
10 10 field :server_environment, :type => Hash
11 11 field :request, :type => Hash
12 12 field :notifier, :type => Hash
13   - field :klass
  13 + field :user_attributes, :type => Hash
  14 + field :error_class
14 15  
15 16 belongs_to :err
16 17 index :created_at
... ... @@ -61,10 +62,6 @@ class Notice
61 62 where
62 63 end
63 64  
64   - def self.in_app_backtrace_line?(line)
65   - !!(line['file'] =~ %r{^\[PROJECT_ROOT\]/(?!(vendor))})
66   - end
67   -
68 65 def request
69 66 read_attribute(:request) || {}
70 67 end
... ...
app/models/problem.rb
... ... @@ -16,7 +16,7 @@ class Problem
16 16 field :notices_count, :type => Integer, :default => 0
17 17 field :message
18 18 field :environment
19   - field :klass
  19 + field :error_class
20 20 field :where
21 21 field :user_agents, :type => Hash, :default => {}
22 22 field :messages, :type => Hash, :default => {}
... ... @@ -128,7 +128,7 @@ class Problem
128 128 attrs.merge!(
129 129 :message => notice.message,
130 130 :environment => notice.environment_name,
131   - :klass => notice.klass,
  131 + :error_class => notice.error_class,
132 132 :where => notice.where,
133 133 :messages => attribute_count_increase(:messages, notice.message),
134 134 :hosts => attribute_count_increase(:hosts, notice.host),
... ...
app/models/user.rb
... ... @@ -3,9 +3,7 @@ class User
3 3 include Mongoid::Document
4 4 include Mongoid::Timestamps
5 5  
6   - devise :database_authenticatable,
7   - :recoverable, :rememberable, :trackable,
8   - :validatable, :token_authenticatable, :omniauthable
  6 + devise *Errbit::Config.devise_modules
9 7  
10 8 field :email
11 9 field :github_login
... ...
app/views/apps/_issue_tracker_fields.html.haml
... ... @@ -17,7 +17,8 @@
17 17 %div.tracker_params{:class => (w.object.is_a?(tracker) ? 'chosen ' : '') << tracker::Label}
18 18 - tracker::Fields.each do |field, field_info|
19 19 = w.label field, field_info[:label] || field.to_s.titleize
20   - = w.text_field field, :placeholder => field_info[:placeholder]
  20 + - field_type = field == :password ? :password_field : :text_field
  21 + = w.send field_type, field, :placeholder => field_info[:placeholder]
21 22  
22 23 .image_preloader
23 24 - (IssueTracker.subclasses.map{|t| t::Label } << 'none').each do |tracker|
... ...
app/views/errs/_table.html.haml
1   -- any_issue_links = errs.any?{|e| e.issue_link.present? }
  1 +- any_issue_links = errs.any?{|e| e.issue_link.present? && e.issue_link != 'pending' }
2 2 =form_tag do
3 3 %table.errs.selectable
4 4 %thead
... ... @@ -30,19 +30,20 @@
30 30 - comment = problem.comments.last
31 31 %br
32 32 .inline_comment
33   - %em.commenter= (Errbit::Config.user_has_username ? comment.user.username : comment.user.email).to_s << ":"
  33 + - if comment.user
  34 + %em.commenter= (Errbit::Config.user_has_username ? comment.user.username : comment.user.email).to_s << ":"
34 35 %em= truncate(comment.body, :length => 100, :separator => ' ')
35 36 %td.latest #{time_ago_in_words(last_notice_at problem)} ago
36 37 %td.deploy= problem.last_deploy_at ? problem.last_deploy_at.to_s(:micro) : 'n/a'
37 38 %td.count= link_to problem.notices_count, app_err_path(problem.app, problem)
38 39 - if any_issue_links
39 40 %td.issue_link
40   - - if problem.issue_link.present?
  41 + - if problem.app.issue_tracker_configured? && problem.issue_link.present? && problem.issue_link != 'pending'
41 42 = link_to image_tag("#{problem.app.issue_tracker.class::Label}_goto.png"), problem.issue_link, :target => "_blank"
42 43 %td.resolve= link_to image_tag("thumbs-up.png"), resolve_app_err_path(problem.app, problem), :title => "Resolve", :method => :put, :confirm => err_confirm, :class => 'resolve' if problem.unresolved?
43 44 - if errs.none?
44 45 %tr
45   - %td{:colspan => (@app ? 6 : 7)}
  46 + %td{:colspan => (any_issue_links ? 8 : 7)}
46 47 %em No errs here
47 48 = paginate errs
48 49 .tab-bar
... ...
app/views/errs/show.html.haml
1 1 - content_for :page_title, @problem.message
2   -- content_for :title, @problem.klass
  2 +- content_for :title, @problem.error_class
3 3 - content_for :meta do
4 4 %strong App:
5 5 = link_to @app.name, app_path(@app)
... ... @@ -16,6 +16,9 @@
16 16 - if @problem.app.issue_tracker_configured?
17 17 - if @problem.issue_link.blank?
18 18 %span= link_to 'create issue', create_issue_app_err_path(@app, @problem), :method => :post, :class => "#{@app.issue_tracker.class::Label}_create create-issue"
  19 + - elsif @problem.issue_link == "pending"
  20 + %span.disabled= link_to 'creating...', '#', :class => "#{@app.issue_tracker.class::Label}_inactive create-issue"
  21 + = link_to 'retry', create_issue_app_err_path(@app, @problem), :method => :post
19 22 - else
20 23 %span= link_to 'go to issue', @problem.issue_link, :class => "#{@app.issue_tracker.class::Label}_goto goto-issue"
21 24 = link_to 'unlink issue', unlink_issue_app_err_path(@app, @problem), :method => :delete, :confirm => "Unlink err issues?", :class => "unlink-issue"
... ... @@ -50,6 +53,8 @@
50 53 %ul
51 54 %li= link_to 'Summary', '#summary', :rel => 'summary', :class => 'button'
52 55 %li= link_to 'Backtrace', '#backtrace', :rel => 'backtrace', :class => 'button'
  56 + - if @notice && @notice.user_attributes.present?
  57 + %li= link_to 'User Details', '#user_attributes', :rel => 'user_attributes', :class => 'button'
53 58 %li= link_to 'Environment', '#environment', :rel => 'environment', :class => 'button'
54 59 %li= link_to 'Parameters', '#params', :rel => 'params', :class => 'button'
55 60 %li= link_to 'Session', '#session', :rel => 'session', :class => 'button'
... ... @@ -63,6 +68,11 @@
63 68 %h3 Backtrace
64 69 = render 'notices/backtrace', :lines => @notice.backtrace
65 70  
  71 + - if @notice.user_attributes.present?
  72 + #user_attributes
  73 + %h3 User Details
  74 + = render 'notices/user_attributes', :user => @notice.user_attributes
  75 +
66 76 #environment
67 77 %h3 Environment
68 78 = render 'notices/environment', :notice => @notice
... ... @@ -74,4 +84,3 @@
74 84 #session
75 85 %h3 Session
76 86 = render 'notices/session', :notice => @notice
77   -
... ...
app/views/issue_trackers/_icons.css.erb
... ... @@ -1,17 +0,0 @@
1   -/* Issue Tracker inactive, select, create and goto icons */
2   -<% trackers = IssueTracker.subclasses.map{|t| t::Label } << 'none' %>
3   -<% trackers.each do |tracker| %>
4   -div.issue_tracker.nested label.<%= tracker %> {
5   - background: url(/images/<%= tracker %>_inactive.png) no-repeat;
6   -}
7   -div.issue_tracker.nested label.r_on.<%= tracker %> {
8   - background: url(/images/<%= tracker %>_create.png) no-repeat;
9   -}
10   -#action-bar a.<%= tracker %>_create {
11   - background: transparent url(/images/<%= tracker %>_create.png) 6px 5px no-repeat;
12   -}
13   -#action-bar a.<%= tracker %>_goto {
14   - background: transparent url(/images/<%= tracker %>_goto.png) 6px 5px no-repeat;
15   -}
16   -<% end %>
17   -
app/views/issue_trackers/github_issues_body.txt.erb
1   -[See this exception on Errbit](<%= app_err_url err.app, err %> "See this exception on Errbit")
2   -<% if notice = err.notices.first %>
  1 +[See this exception on Errbit](<%= app_err_url problem.app, problem %> "See this exception on Errbit")
  2 +<% if notice = problem.notices.first %>
3 3 # <%= notice.message %> #
4 4 ## Summary ##
5 5 <% if notice.request['url'].present? %>
... ...
app/views/layouts/application.html.haml
... ... @@ -7,10 +7,8 @@
7 7 %meta{ :content => "text/html; charset=utf-8", "http-equiv" => "content-type" }/
8 8 = favicon_link_tag
9 9 = csrf_meta_tag
10   - = javascript_include_tag :defaults
11   - = stylesheet_link_tag 'reset', 'application', 'jquery.alerts'
12   - :css
13   - #{render :partial => "issue_trackers/icons", :formats => :css}
  10 + = stylesheet_link_tag :application
  11 + = javascript_include_tag :application
14 12  
15 13 = yield :head
16 14 %body{:id => controller.controller_name, :class => controller.action_name}
... ...
app/views/layouts/mailer.html.haml
... ... @@ -3,14 +3,14 @@
3 3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
4 4 =# stylesheet_link_tag 'mailers/mailer'
5 5 -# Include CSS inline
6   - %style= File.read(Rails.root.join('public/stylesheets/mailers/mailer.css'))
  6 + %style= File.read(Rails.root.join('app/assets/stylesheets/mailers/mailer.css'))
7 7 %body(leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0")
8 8 %center
9 9 %table(cellpadding="0" cellspacing="0" border="0" width="100%")
10 10 %tbody
11 11 %tr
12 12 %td.header
13   - = link_to image_tag(URI.join(root_url,"stylesheets/images/logo.png").to_s, :alt => "Errbit"), root_url
  13 + = link_to image_tag(URI.join(root_url,"assets/images/logo.png").to_s, :alt => "Errbit"), root_url
14 14  
15 15 = yield
16 16  
... ...
app/views/notices/_backtrace.html.haml
1 1 .window
2 2 %table.backtrace
3   - - lines.each do |line|
4   - - path = File.dirname(line['file'])
5   - - path = path == "." ? "" : path + '/'
6   - - file = File.basename(line['file'])
7   - - file = "#{file}:#{line['number']}" unless line['number'].blank?
8   - %tr
9   - %td.line{:class => (Notice.in_app_backtrace_line?(line) ? 'in-app' : nil)}
10   - %span.path>= path
11   - %span.file= link_to_source_file(@app, line, file).html_safe
12   - &rarr;
13   - %span.method= line['method']
  3 + -# Group lines into internal / external so we can toggle the external backtrace
  4 + -# Includes a margin of x lines that are not toggled.
  5 + - em = 4 # (external backtrace margin)
  6 + - grouped_lines(lines).each do |in_app, line_group|
  7 + - if !in_app && line_group.size > (em * 3)
  8 + = render :partial => 'notices/backtrace_line', :collection => line_group[0, em], :as => :line
  9 + = render :partial => 'notices/backtrace_line', :collection => line_group[em, line_group.size - (em * 2)], :as => :line, :locals => {:row_class => 'toggle_external_backtrace'}
  10 + %tr
  11 + %td.line.backtrace_separator
  12 + %span ...
  13 + = render :partial => 'notices/backtrace_line', :collection => line_group[em * -1, em], :as => :line
14 14  
  15 + - else
  16 + = render :partial => "notices/backtrace_line", :collection => line_group, :as => :line
... ...
app/views/notices/_backtrace_line.html.haml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +%tr{:class => defined?(row_class) ? row_class : nil}
  2 + %td.line{:class => (in_app_backtrace_line?(line) ? 'in-app' : nil)}
  3 + = link_to_source_file(@app, line) do
  4 + %span.path>= path_for_backtrace_line(line)
  5 + %span.file>= file_for_backtrace_line(line)
  6 + - if line['number'].present?
  7 + %span.number>= ":#{line['number']}"
  8 + &rarr;
  9 + %span.method= line['method']
... ...
app/views/notices/_summary.html.haml
... ... @@ -3,6 +3,9 @@
3 3 %tr
4 4 %th Message
5 5 %td.main.nowrap= message_graph(problem)
  6 + %tr
  7 + %th Error Class
  8 + %td= notice.error_class
6 9 - if notice.request['url'].present?
7 10 %tr
8 11 %th URL
... ...
app/views/notices/_user_attributes.html.haml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +.window
  2 + %table.user_attributes
  3 + %tr
  4 + %td
  5 + %strong Information about the user who experienced the error.
  6 + - user.each do |user_key, user_value|
  7 + %tr
  8 + %th= user_key
  9 + %td= auto_link(user_value).html_safe
... ...
config/application.rb
... ... @@ -7,7 +7,7 @@ require &quot;action_controller/railtie&quot;
7 7 require "action_mailer/railtie"
8 8 # require "active_resource/railtie"
9 9 require 'mongoid/railtie'
10   -
  10 +require "sprockets/railtie"
11 11  
12 12 # If you have a Gemfile, require the gems listed there, including any gems
13 13 # you've limited to :test, :development, or :production.
... ... @@ -37,9 +37,6 @@ module Errbit
37 37 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
38 38 # config.i18n.default_locale = :de
39 39  
40   - # JavaScript files you want as :defaults (application.js is always included).
41   - config.action_view.javascript_expansions[:defaults] = %w(jquery underscore-1.1.6 rails form jquery.pjax jquery.alerts rails.alerts)
42   -
43 40 # > rails generate - config
44 41 config.generators do |g|
45 42 g.orm :mongoid
... ... @@ -62,6 +59,16 @@ module Errbit
62 59  
63 60 # Configure Devise mailer to use our mailer layout.
64 61 config.to_prepare { Devise::Mailer.layout "mailer" }
  62 +
  63 +
  64 + # Enable the asset pipeline
  65 + config.assets.enabled = true
  66 +
  67 + # Need to initialize Rails environment for issue_tracker_icons.css.erb
  68 + config.assets.initialize_on_precompile = true
  69 +
  70 + # Version of your assets, change this if you want to expire all your assets
  71 + config.assets.version = '1.0'
65 72 end
66 73 end
67 74  
... ...
config/deploy.example.rb
... ... @@ -9,6 +9,7 @@
9 9 config = YAML.load_file('config/config.yml')['deployment'] || {}
10 10  
11 11 require 'bundler/capistrano'
  12 +load 'deploy/assets'
12 13  
13 14 set :application, "errbit"
14 15 set :repository, config['repository']
... ...
config/environments/development.rb
... ... @@ -19,5 +19,11 @@ Errbit::Application.configure do
19 19  
20 20 # Print deprecation notices to the Rails logger
21 21 config.active_support.deprecation = :log
  22 +
  23 + # Do not compress assets
  24 + config.assets.compress = false
  25 +
  26 + # Expands the lines which load the assets
  27 + config.assets.debug = true
22 28 end
23 29  
... ...
config/environments/production.rb
... ... @@ -28,10 +28,22 @@ Errbit::Application.configure do
28 28 # Use a different cache store in production
29 29 # config.cache_store = :mem_cache_store
30 30  
  31 + # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
  32 + config.assets.precompile += %w( apps.show.js )
  33 +
31 34 # Disable Rails's static asset server
32 35 # In production, Apache or nginx will already do this
33 36 config.serve_static_assets = false
34 37  
  38 + # Compress JavaScripts and CSS
  39 + config.assets.compress = true
  40 +
  41 + # Don't fallback to assets pipeline if a precompiled asset is missed
  42 + config.assets.compile = false
  43 +
  44 + # Generate digests for assets URLs
  45 + config.assets.digest = true
  46 +
35 47 # Enable serving of images, stylesheets, and javascripts from an asset server
36 48 # config.action_controller.asset_host = "http://assets.example.com"
37 49  
... ...