From 0f43e98ef8c2da8908b1107f75b67cda2572c2c4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 9 Oct 2011 00:34:49 +0300 Subject: [PATCH 01/18] gitignore --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c83fcb68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.bundle +.rbx/ +db/*.sqlite3 +log/*.log +tmp/ +.sass-cache/ +coverage/* +*.swp +public/uploads/ From d3784687943e0bd699d73d82a6bc6cac39689473 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 13 Oct 2011 04:00:00 +0300 Subject: [PATCH 02/18] v1.0 --- .rails_footnotes | 3 + .rspec | 1 + .rvmrc | 1 + CHANGELOG | 28 + Gemfile | 50 ++ Gemfile.lock | 277 ++++++ LICENSE | 19 + README.rdoc | 85 ++ Rakefile | 7 + VERSION | 1 + app/assets/images/.directory | 4 + app/assets/images/ajax-loader.gif | Bin 0 -> 6820 bytes app/assets/images/blueprint_add.png | Bin 0 -> 4544 bytes app/assets/images/blueprint_delete.png | Bin 0 -> 4506 bytes app/assets/images/blueprint_info.png | Bin 0 -> 4512 bytes app/assets/images/blueprint_notice.png | Bin 0 -> 4531 bytes app/assets/images/dir.png | Bin 0 -> 485 bytes app/assets/images/favicon.ico | Bin 0 -> 1150 bytes app/assets/images/favicon.png | Bin 0 -> 338 bytes app/assets/images/git.png | Bin 0 -> 21559 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 5355 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes app/assets/images/list_view_icon.jpg | Bin 0 -> 357 bytes app/assets/images/no_avatar.png | Bin 0 -> 1335 bytes app/assets/images/rails.png | Bin 0 -> 6646 bytes app/assets/images/txt.png | Bin 0 -> 290 bytes app/assets/javascripts/application.js | 18 + app/assets/javascripts/commits.js | 9 + app/assets/javascripts/dashboard.js.coffee | 3 + app/assets/javascripts/issues.js.coffee | 3 + .../jquery-ui-1.8.16.custom.min.js | 791 ++++++++++++++++ app/assets/javascripts/jquery.cookie.js | 41 + .../javascripts/jquery.ui.selectmenu.js | 845 ++++++++++++++++++ app/assets/javascripts/profile.js.coffee | 3 + app/assets/javascripts/projects.js | 41 + app/assets/stylesheets/application.css | 7 + app/assets/stylesheets/dashboard.css.scss | 3 + app/assets/stylesheets/highlight.css.scss | 135 +++ app/assets/stylesheets/issues.css.scss | 3 + .../stylesheets/jquery.ui.selectmenu.css | 33 + app/assets/stylesheets/profile.css.scss | 3 + app/assets/stylesheets/projects.css.scss | 541 +++++++++++ app/controllers/admin/mailer_controller.rb | 44 + app/controllers/admin/projects_controller.rb | 74 ++ .../admin/team_members_controller.rb | 75 ++ app/controllers/admin/users_controller.rb | 84 ++ app/controllers/application_controller.rb | 44 + app/controllers/commits_controller.rb | 44 + app/controllers/dashboard_controller.rb | 5 + app/controllers/errors_controller.rb | 5 + app/controllers/issues_controller.rb | 72 ++ app/controllers/keys_controller.rb | 38 + app/controllers/notes_controller.rb | 49 + app/controllers/profile_controller.rb | 21 + app/controllers/projects_controller.rb | 152 ++++ app/controllers/team_members_controller.rb | 66 ++ app/helpers/admin/projects_helper.rb | 2 + app/helpers/admin/users_helper.rb | 2 + app/helpers/application_helper.rb | 77 ++ app/helpers/commits_helper.rb | 24 + app/helpers/dashboard_helper.rb | 2 + app/helpers/issues_helper.rb | 2 + app/helpers/keys_helper.rb | 2 + app/helpers/profile_helper.rb | 2 + app/helpers/projects_helper.rb | 6 + app/helpers/team_members_helper.rb | 2 + app/mailers/.gitkeep | 0 app/mailers/notify.rb | 41 + app/models/.gitkeep | 0 app/models/ability.rb | 34 + app/models/issue.rb | 39 + app/models/key.rb | 58 ++ app/models/note.rb | 41 + app/models/project.rb | 164 ++++ app/models/user.rb | 62 ++ app/models/users_project.rb | 35 + app/uploaders/attachment_uploader.rb | 49 + app/views/admin/_top_menu.html.haml | 6 + app/views/admin/mailer/preview.html.haml | 29 + app/views/admin/projects/_form.html.haml | 30 + app/views/admin/projects/edit.html.haml | 5 + app/views/admin/projects/index.html.haml | 26 + app/views/admin/projects/new.html.haml | 5 + app/views/admin/projects/show.html.haml | 45 + app/views/admin/team_members/_form.html.haml | 34 + app/views/admin/team_members/edit.html.haml | 5 + app/views/admin/team_members/index.html.haml | 30 + app/views/admin/team_members/new.html.haml | 5 + app/views/admin/team_members/show.html.haml | 32 + app/views/admin/users/_form.html.haml | 38 + app/views/admin/users/edit.html.haml | 4 + app/views/admin/users/index.html.haml | 24 + app/views/admin/users/new.html.haml | 6 + app/views/admin/users/show.html.haml | 45 + app/views/commits/_commits.html.haml | 22 + app/views/commits/_diff.html.haml | 58 ++ app/views/commits/_index.html.haml | 9 + app/views/commits/index.html.haml | 13 + app/views/commits/index.js.erb | 2 + app/views/commits/show.html.haml | 39 + app/views/commits/show.js.haml | 6 + app/views/dashboard/index.html.haml | 1 + app/views/devise/confirmations/new.html.erb | 12 + .../mailer/confirmation_instructions.html.erb | 5 + .../reset_password_instructions.html.erb | 8 + .../mailer/unlock_instructions.html.erb | 7 + app/views/devise/passwords/edit.html.erb | 16 + app/views/devise/passwords/new.html.erb | 15 + app/views/devise/registrations/edit.html.erb | 28 + app/views/devise/registrations/new.html.erb | 18 + app/views/devise/sessions/new.html.erb | 20 + app/views/devise/shared/_links.erb | 25 + app/views/devise/unlocks/new.html.erb | 12 + app/views/issues/_form.html.haml | 24 + app/views/issues/_issues.html.haml | 10 + app/views/issues/_show.html.haml | 18 + app/views/issues/create.js.haml | 9 + app/views/issues/edit.js.haml | 12 + app/views/issues/index.html.haml | 24 + app/views/issues/index.js.haml | 2 + app/views/issues/new.js.haml | 12 + app/views/issues/show.html.haml | 44 + app/views/issues/update.js.haml | 14 + app/views/keys/_form.html.haml | 16 + app/views/keys/_show.html.haml | 4 + app/views/keys/create.js.haml | 8 + app/views/keys/edit.html.haml | 7 + app/views/keys/index.html.haml | 15 + app/views/keys/new.html.haml | 5 + app/views/keys/new.js.haml | 11 + app/views/layouts/_flash.html.haml | 18 + app/views/layouts/_head_panel.html.erb | 34 + app/views/layouts/application.html.haml | 29 + app/views/layouts/notify.html.haml | 36 + app/views/notes/_form.html.haml | 28 + app/views/notes/_notes.html.haml | 14 + app/views/notes/_show.html.haml | 19 + app/views/notes/create.js.haml | 8 + app/views/notify/new_issue_email.html.haml | 18 + app/views/notify/new_user_email.html.haml | 23 + app/views/notify/note_commit_email.html.haml | 23 + app/views/notify/note_issue_email.html.haml | 25 + app/views/notify/note_wall_email.html.haml | 22 + app/views/profile/_top_menu.html.haml | 5 + app/views/profile/index.html.haml | 1 + app/views/profile/password.html.haml | 20 + app/views/profile/show.html.haml | 8 + app/views/projects/_form.html.haml | 50 ++ app/views/projects/_list.html.haml | 26 + .../projects/_projects_top_menu.html.haml | 16 + app/views/projects/_side_panel.html.haml | 14 + app/views/projects/_team.html.haml | 18 + app/views/projects/_tile.html.haml | 16 + app/views/projects/_top_menu.html.haml | 24 + app/views/projects/_tree.html.haml | 60 ++ app/views/projects/_tree_file.html.haml | 21 + app/views/projects/_tree_item.html.haml | 15 + app/views/projects/create.js.haml | 6 + app/views/projects/edit.html.erb | 1 + app/views/projects/empty.html.erb | 49 + app/views/projects/index.html.haml | 4 + app/views/projects/new.html.erb | 1 + app/views/projects/show.html.haml | 3 + app/views/projects/team.html.haml | 3 + app/views/projects/tree.html.erb | 5 + app/views/projects/tree.js.haml | 5 + app/views/projects/update.js.haml | 6 + app/views/projects/wall.html.haml | 1 + app/views/team_members/_form.html.haml | 25 + app/views/team_members/_show.html.haml | 18 + app/views/team_members/create.js.haml | 9 + app/views/team_members/new.js.haml | 15 + app/views/team_members/update.js.haml | 6 + config.ru | 4 + config/application.rb | 48 + config/boot.rb | 6 + config/database.yml | 25 + config/environment.rb | 7 + config/environments/development.rb | 32 + config/environments/production.rb | 70 ++ config/environments/test.rb | 42 + config/gitosis.yml | 4 + config/initializers/backtrace_silencers.rb | 7 + config/initializers/devise.rb | 211 +++++ config/initializers/inflections.rb | 10 + config/initializers/load_config.rb | 1 + config/initializers/mime_types.rb | 5 + config/initializers/rails_footnotes.rb | 5 + config/initializers/secret_token.rb | 7 + config/initializers/session_store.rb | 8 + config/initializers/wrap_parameters.rb | 14 + config/locales/devise.en.yml | 58 ++ config/locales/en.yml | 10 + config/routes.rb | 47 + configure.rb | 5 + db/fixtures/development/001_admin.rb | 11 + db/fixtures/production/001_admin.rb | 10 + db/fixtures/test/001_repo.rb | 11 + .../20110913200833_devise_create_users.rb | 28 + db/migrate/20110913204141_create_projects.rb | 11 + .../20110914221600_create_users_projects.rb | 13 + ...10915205627_add_private_flag_to_project.rb | 5 + db/migrate/20110915213352_create_keys.rb | 9 + db/migrate/20110916123731_add_name_to_user.rb | 5 + .../20110916162511_add_key_title_to_key.rb | 7 + .../20110917212932_add_identifier_to_key.rb | 5 + db/migrate/20110921192501_create_issues.rb | 13 + .../20110922110156_add_code_to_project.rb | 5 + .../20110923211333_add_status_to_issue.rb | 5 + ...4549_create_rails_admin_histories_table.rb | 18 + .../20110924215658_add_admin_field_to_user.rb | 5 + db/migrate/20110926082616_remove_admin.rb | 9 + db/migrate/20110927130352_create_notes.rb | 12 + .../20110928140106_add_project_id_for_note.rb | 9 + ...10928142747_change_noteable_id_for_note.rb | 9 + .../20110928161328_add_attachment_to_note.rb | 5 + ...193700_add_allow_repo_creation_for_user.rb | 9 + .../20111009101738_add_ownerto_project.rb | 5 + ...111009110913_add_projects_limit_to_user.rb | 5 + ...1204_remove_allow_create_repo_from_user.rb | 9 + db/pkey.example | 3 + db/schema.rb | 89 ++ db/seeds.rb | 0 doc/README_FOR_APP | 2 + install/prepare.rb | 51 ++ lib/assets/.gitkeep | 0 lib/file_size_validator.rb | 65 ++ lib/gitosis.rb | 73 ++ lib/tasks/.gitkeep | 0 lib/utils.rb | 8 + log/.gitkeep | 0 public/404.html | 25 + public/422.html | 25 + public/500.html | 25 + public/favicon.ico | 0 public/gitosis_error.html | 26 + public/index.html.example | 241 +++++ public/robots.txt | 5 + script/rails | 6 + spec/factories.rb | 45 + spec/factory.rb | 29 + spec/models/issue_spec.rb | 42 + spec/models/key_spec.rb | 32 + spec/models/note_spec.rb | 78 ++ spec/models/project_security_spec.rb | 57 ++ spec/models/project_spec.rb | 127 +++ spec/models/user_spec.rb | 43 + spec/models/users_project_spec.rb | 32 + spec/monkeypatch.rb | 31 + spec/requests/admin/admin_projects_spec.rb | 106 +++ spec/requests/admin/admin_users_spec.rb | 102 +++ spec/requests/admin/security_spec.rb | 27 + spec/requests/commits_notes_spec.rb | 24 + spec/requests/commits_spec.rb | 39 + spec/requests/issues_notes_spec.rb | 27 + spec/requests/issues_spec.rb | 147 +++ spec/requests/keys_spec.rb | 54 ++ spec/requests/profile_spec.rb | 55 ++ spec/requests/projects_security_spec.rb | 111 +++ spec/requests/projects_spec.rb | 152 ++++ spec/requests/projects_tree_spec.rb | 92 ++ spec/requests/projects_wall_spec.rb | 33 + spec/requests/team_members_spec.rb | 46 + spec/requests/top_panel_spec.rb | 34 + spec/requests/user_security_spec.rb | 37 + spec/seed_project.tar.gz | Bin 0 -> 1699843 bytes spec/spec_helper.rb | 56 ++ spec/support/js_patch.rb | 6 + spec/support/login.rb | 29 + spec/support/matchers.rb | 46 + spec/support/security.rb | 0 spec/support/shared_examples.rb | 18 + spec/support/valid_commit.rb | 25 + vendor/assets/stylesheets/.gitkeep | 0 vendor/assets/stylesheets/blueprint/ie.css | 36 + .../blueprint/plugins/buttons/icons/cross.png | Bin 0 -> 655 bytes .../blueprint/plugins/buttons/icons/key.png | Bin 0 -> 455 bytes .../blueprint/plugins/buttons/icons/tick.png | Bin 0 -> 537 bytes .../blueprint/plugins/buttons/readme.txt | 32 + .../blueprint/plugins/buttons/screen.css | 97 ++ .../blueprint/plugins/fancy-type/readme.txt | 14 + .../blueprint/plugins/fancy-type/screen.css | 71 ++ .../plugins/link-icons/icons/doc.png | Bin 0 -> 777 bytes .../plugins/link-icons/icons/email.png | Bin 0 -> 641 bytes .../plugins/link-icons/icons/external.png | Bin 0 -> 46848 bytes .../plugins/link-icons/icons/feed.png | Bin 0 -> 691 bytes .../blueprint/plugins/link-icons/icons/im.png | Bin 0 -> 741 bytes .../plugins/link-icons/icons/lock.png | Bin 0 -> 749 bytes .../plugins/link-icons/icons/pdf.png | Bin 0 -> 591 bytes .../plugins/link-icons/icons/visited.png | Bin 0 -> 46990 bytes .../plugins/link-icons/icons/xls.png | Bin 0 -> 663 bytes .../blueprint/plugins/link-icons/readme.txt | 18 + .../blueprint/plugins/link-icons/screen.css | 42 + .../blueprint/plugins/rtl/readme.txt | 10 + .../blueprint/plugins/rtl/screen.css | 110 +++ vendor/assets/stylesheets/blueprint/print.css | 29 + .../assets/stylesheets/blueprint/screen.css | 265 ++++++ .../stylesheets/blueprint/src/forms.css | 82 ++ .../assets/stylesheets/blueprint/src/grid.css | 280 ++++++ .../assets/stylesheets/blueprint/src/grid.png | Bin 0 -> 195 bytes .../assets/stylesheets/blueprint/src/ie.css | 79 ++ .../stylesheets/blueprint/src/print.css | 92 ++ .../stylesheets/blueprint/src/reset.css | 65 ++ .../stylesheets/blueprint/src/typography.css | 123 +++ .../jquery_ui/jquery-ui-1.8.16.custom.css | 577 ++++++++++++ vendor/plugins/.gitkeep | 0 317 files changed, 11347 insertions(+) create mode 100644 .rails_footnotes create mode 100644 .rspec create mode 100644 .rvmrc create mode 100644 CHANGELOG create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 LICENSE create mode 100644 README.rdoc create mode 100644 Rakefile create mode 100644 VERSION create mode 100644 app/assets/images/.directory create mode 100644 app/assets/images/ajax-loader.gif create mode 100644 app/assets/images/blueprint_add.png create mode 100644 app/assets/images/blueprint_delete.png create mode 100644 app/assets/images/blueprint_info.png create mode 100644 app/assets/images/blueprint_notice.png create mode 100644 app/assets/images/dir.png create mode 100644 app/assets/images/favicon.ico create mode 100644 app/assets/images/favicon.png create mode 100644 app/assets/images/git.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 app/assets/images/jquery_ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 app/assets/images/jquery_ui/images/ui-icons_222222_256x240.png create mode 100644 app/assets/images/jquery_ui/images/ui-icons_2e83ff_256x240.png create mode 100644 app/assets/images/jquery_ui/images/ui-icons_454545_256x240.png create mode 100644 app/assets/images/jquery_ui/images/ui-icons_888888_256x240.png create mode 100644 app/assets/images/jquery_ui/images/ui-icons_cd0a0a_256x240.png create mode 100644 app/assets/images/list_view_icon.jpg create mode 100644 app/assets/images/no_avatar.png create mode 100644 app/assets/images/rails.png create mode 100644 app/assets/images/txt.png create mode 100644 app/assets/javascripts/application.js create mode 100644 app/assets/javascripts/commits.js create mode 100644 app/assets/javascripts/dashboard.js.coffee create mode 100644 app/assets/javascripts/issues.js.coffee create mode 100644 app/assets/javascripts/jquery-ui-1.8.16.custom.min.js create mode 100644 app/assets/javascripts/jquery.cookie.js create mode 100644 app/assets/javascripts/jquery.ui.selectmenu.js create mode 100644 app/assets/javascripts/profile.js.coffee create mode 100644 app/assets/javascripts/projects.js create mode 100644 app/assets/stylesheets/application.css create mode 100644 app/assets/stylesheets/dashboard.css.scss create mode 100644 app/assets/stylesheets/highlight.css.scss create mode 100644 app/assets/stylesheets/issues.css.scss create mode 100644 app/assets/stylesheets/jquery.ui.selectmenu.css create mode 100644 app/assets/stylesheets/profile.css.scss create mode 100644 app/assets/stylesheets/projects.css.scss create mode 100644 app/controllers/admin/mailer_controller.rb create mode 100644 app/controllers/admin/projects_controller.rb create mode 100644 app/controllers/admin/team_members_controller.rb create mode 100644 app/controllers/admin/users_controller.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/commits_controller.rb create mode 100644 app/controllers/dashboard_controller.rb create mode 100644 app/controllers/errors_controller.rb create mode 100644 app/controllers/issues_controller.rb create mode 100644 app/controllers/keys_controller.rb create mode 100644 app/controllers/notes_controller.rb create mode 100644 app/controllers/profile_controller.rb create mode 100644 app/controllers/projects_controller.rb create mode 100644 app/controllers/team_members_controller.rb create mode 100644 app/helpers/admin/projects_helper.rb create mode 100644 app/helpers/admin/users_helper.rb create mode 100644 app/helpers/application_helper.rb create mode 100644 app/helpers/commits_helper.rb create mode 100644 app/helpers/dashboard_helper.rb create mode 100644 app/helpers/issues_helper.rb create mode 100644 app/helpers/keys_helper.rb create mode 100644 app/helpers/profile_helper.rb create mode 100644 app/helpers/projects_helper.rb create mode 100644 app/helpers/team_members_helper.rb create mode 100644 app/mailers/.gitkeep create mode 100644 app/mailers/notify.rb create mode 100644 app/models/.gitkeep create mode 100644 app/models/ability.rb create mode 100644 app/models/issue.rb create mode 100644 app/models/key.rb create mode 100644 app/models/note.rb create mode 100644 app/models/project.rb create mode 100644 app/models/user.rb create mode 100644 app/models/users_project.rb create mode 100644 app/uploaders/attachment_uploader.rb create mode 100644 app/views/admin/_top_menu.html.haml create mode 100644 app/views/admin/mailer/preview.html.haml create mode 100644 app/views/admin/projects/_form.html.haml create mode 100644 app/views/admin/projects/edit.html.haml create mode 100644 app/views/admin/projects/index.html.haml create mode 100644 app/views/admin/projects/new.html.haml create mode 100644 app/views/admin/projects/show.html.haml create mode 100644 app/views/admin/team_members/_form.html.haml create mode 100644 app/views/admin/team_members/edit.html.haml create mode 100644 app/views/admin/team_members/index.html.haml create mode 100644 app/views/admin/team_members/new.html.haml create mode 100644 app/views/admin/team_members/show.html.haml create mode 100644 app/views/admin/users/_form.html.haml create mode 100644 app/views/admin/users/edit.html.haml create mode 100644 app/views/admin/users/index.html.haml create mode 100644 app/views/admin/users/new.html.haml create mode 100644 app/views/admin/users/show.html.haml create mode 100644 app/views/commits/_commits.html.haml create mode 100644 app/views/commits/_diff.html.haml create mode 100644 app/views/commits/_index.html.haml create mode 100644 app/views/commits/index.html.haml create mode 100644 app/views/commits/index.js.erb create mode 100644 app/views/commits/show.html.haml create mode 100644 app/views/commits/show.js.haml create mode 100644 app/views/dashboard/index.html.haml create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/reset_password_instructions.html.erb create mode 100644 app/views/devise/mailer/unlock_instructions.html.erb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 app/views/devise/registrations/edit.html.erb create mode 100644 app/views/devise/registrations/new.html.erb create mode 100644 app/views/devise/sessions/new.html.erb create mode 100644 app/views/devise/shared/_links.erb create mode 100644 app/views/devise/unlocks/new.html.erb create mode 100644 app/views/issues/_form.html.haml create mode 100644 app/views/issues/_issues.html.haml create mode 100644 app/views/issues/_show.html.haml create mode 100644 app/views/issues/create.js.haml create mode 100644 app/views/issues/edit.js.haml create mode 100644 app/views/issues/index.html.haml create mode 100644 app/views/issues/index.js.haml create mode 100644 app/views/issues/new.js.haml create mode 100644 app/views/issues/show.html.haml create mode 100644 app/views/issues/update.js.haml create mode 100644 app/views/keys/_form.html.haml create mode 100644 app/views/keys/_show.html.haml create mode 100644 app/views/keys/create.js.haml create mode 100644 app/views/keys/edit.html.haml create mode 100644 app/views/keys/index.html.haml create mode 100644 app/views/keys/new.html.haml create mode 100644 app/views/keys/new.js.haml create mode 100644 app/views/layouts/_flash.html.haml create mode 100644 app/views/layouts/_head_panel.html.erb create mode 100644 app/views/layouts/application.html.haml create mode 100644 app/views/layouts/notify.html.haml create mode 100644 app/views/notes/_form.html.haml create mode 100644 app/views/notes/_notes.html.haml create mode 100644 app/views/notes/_show.html.haml create mode 100644 app/views/notes/create.js.haml create mode 100644 app/views/notify/new_issue_email.html.haml create mode 100644 app/views/notify/new_user_email.html.haml create mode 100644 app/views/notify/note_commit_email.html.haml create mode 100644 app/views/notify/note_issue_email.html.haml create mode 100644 app/views/notify/note_wall_email.html.haml create mode 100644 app/views/profile/_top_menu.html.haml create mode 100644 app/views/profile/index.html.haml create mode 100644 app/views/profile/password.html.haml create mode 100644 app/views/profile/show.html.haml create mode 100644 app/views/projects/_form.html.haml create mode 100644 app/views/projects/_list.html.haml create mode 100644 app/views/projects/_projects_top_menu.html.haml create mode 100644 app/views/projects/_side_panel.html.haml create mode 100644 app/views/projects/_team.html.haml create mode 100644 app/views/projects/_tile.html.haml create mode 100644 app/views/projects/_top_menu.html.haml create mode 100644 app/views/projects/_tree.html.haml create mode 100644 app/views/projects/_tree_file.html.haml create mode 100644 app/views/projects/_tree_item.html.haml create mode 100644 app/views/projects/create.js.haml create mode 100644 app/views/projects/edit.html.erb create mode 100644 app/views/projects/empty.html.erb create mode 100644 app/views/projects/index.html.haml create mode 100644 app/views/projects/new.html.erb create mode 100644 app/views/projects/show.html.haml create mode 100644 app/views/projects/team.html.haml create mode 100644 app/views/projects/tree.html.erb create mode 100644 app/views/projects/tree.js.haml create mode 100644 app/views/projects/update.js.haml create mode 100644 app/views/projects/wall.html.haml create mode 100644 app/views/team_members/_form.html.haml create mode 100644 app/views/team_members/_show.html.haml create mode 100644 app/views/team_members/create.js.haml create mode 100644 app/views/team_members/new.js.haml create mode 100644 app/views/team_members/update.js.haml create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/gitosis.yml create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/devise.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/load_config.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/rails_footnotes.rb create mode 100644 config/initializers/secret_token.rb create mode 100644 config/initializers/session_store.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/devise.en.yml create mode 100644 config/locales/en.yml create mode 100644 config/routes.rb create mode 100644 configure.rb create mode 100644 db/fixtures/development/001_admin.rb create mode 100644 db/fixtures/production/001_admin.rb create mode 100644 db/fixtures/test/001_repo.rb create mode 100644 db/migrate/20110913200833_devise_create_users.rb create mode 100644 db/migrate/20110913204141_create_projects.rb create mode 100644 db/migrate/20110914221600_create_users_projects.rb create mode 100644 db/migrate/20110915205627_add_private_flag_to_project.rb create mode 100644 db/migrate/20110915213352_create_keys.rb create mode 100644 db/migrate/20110916123731_add_name_to_user.rb create mode 100644 db/migrate/20110916162511_add_key_title_to_key.rb create mode 100644 db/migrate/20110917212932_add_identifier_to_key.rb create mode 100644 db/migrate/20110921192501_create_issues.rb create mode 100644 db/migrate/20110922110156_add_code_to_project.rb create mode 100644 db/migrate/20110923211333_add_status_to_issue.rb create mode 100644 db/migrate/20110924214549_create_rails_admin_histories_table.rb create mode 100644 db/migrate/20110924215658_add_admin_field_to_user.rb create mode 100644 db/migrate/20110926082616_remove_admin.rb create mode 100644 db/migrate/20110927130352_create_notes.rb create mode 100644 db/migrate/20110928140106_add_project_id_for_note.rb create mode 100644 db/migrate/20110928142747_change_noteable_id_for_note.rb create mode 100644 db/migrate/20110928161328_add_attachment_to_note.rb create mode 100644 db/migrate/20111005193700_add_allow_repo_creation_for_user.rb create mode 100644 db/migrate/20111009101738_add_ownerto_project.rb create mode 100644 db/migrate/20111009110913_add_projects_limit_to_user.rb create mode 100644 db/migrate/20111009111204_remove_allow_create_repo_from_user.rb create mode 100644 db/pkey.example create mode 100644 db/schema.rb create mode 100644 db/seeds.rb create mode 100644 doc/README_FOR_APP create mode 100644 install/prepare.rb create mode 100644 lib/assets/.gitkeep create mode 100644 lib/file_size_validator.rb create mode 100644 lib/gitosis.rb create mode 100644 lib/tasks/.gitkeep create mode 100644 lib/utils.rb create mode 100644 log/.gitkeep create mode 100644 public/404.html create mode 100644 public/422.html create mode 100644 public/500.html create mode 100644 public/favicon.ico create mode 100644 public/gitosis_error.html create mode 100644 public/index.html.example create mode 100644 public/robots.txt create mode 100755 script/rails create mode 100644 spec/factories.rb create mode 100644 spec/factory.rb create mode 100644 spec/models/issue_spec.rb create mode 100644 spec/models/key_spec.rb create mode 100644 spec/models/note_spec.rb create mode 100644 spec/models/project_security_spec.rb create mode 100644 spec/models/project_spec.rb create mode 100644 spec/models/user_spec.rb create mode 100644 spec/models/users_project_spec.rb create mode 100644 spec/monkeypatch.rb create mode 100644 spec/requests/admin/admin_projects_spec.rb create mode 100644 spec/requests/admin/admin_users_spec.rb create mode 100644 spec/requests/admin/security_spec.rb create mode 100644 spec/requests/commits_notes_spec.rb create mode 100644 spec/requests/commits_spec.rb create mode 100644 spec/requests/issues_notes_spec.rb create mode 100644 spec/requests/issues_spec.rb create mode 100644 spec/requests/keys_spec.rb create mode 100644 spec/requests/profile_spec.rb create mode 100644 spec/requests/projects_security_spec.rb create mode 100644 spec/requests/projects_spec.rb create mode 100644 spec/requests/projects_tree_spec.rb create mode 100644 spec/requests/projects_wall_spec.rb create mode 100644 spec/requests/team_members_spec.rb create mode 100644 spec/requests/top_panel_spec.rb create mode 100644 spec/requests/user_security_spec.rb create mode 100644 spec/seed_project.tar.gz create mode 100644 spec/spec_helper.rb create mode 100644 spec/support/js_patch.rb create mode 100644 spec/support/login.rb create mode 100644 spec/support/matchers.rb create mode 100644 spec/support/security.rb create mode 100644 spec/support/shared_examples.rb create mode 100644 spec/support/valid_commit.rb create mode 100644 vendor/assets/stylesheets/.gitkeep create mode 100644 vendor/assets/stylesheets/blueprint/ie.css create mode 100755 vendor/assets/stylesheets/blueprint/plugins/buttons/icons/cross.png create mode 100755 vendor/assets/stylesheets/blueprint/plugins/buttons/icons/key.png create mode 100755 vendor/assets/stylesheets/blueprint/plugins/buttons/icons/tick.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/buttons/readme.txt create mode 100644 vendor/assets/stylesheets/blueprint/plugins/buttons/screen.css create mode 100644 vendor/assets/stylesheets/blueprint/plugins/fancy-type/readme.txt create mode 100644 vendor/assets/stylesheets/blueprint/plugins/fancy-type/screen.css create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/doc.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/email.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/external.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/feed.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/im.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/lock.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/pdf.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/visited.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/icons/xls.png create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/readme.txt create mode 100644 vendor/assets/stylesheets/blueprint/plugins/link-icons/screen.css create mode 100644 vendor/assets/stylesheets/blueprint/plugins/rtl/readme.txt create mode 100644 vendor/assets/stylesheets/blueprint/plugins/rtl/screen.css create mode 100644 vendor/assets/stylesheets/blueprint/print.css create mode 100644 vendor/assets/stylesheets/blueprint/screen.css create mode 100644 vendor/assets/stylesheets/blueprint/src/forms.css create mode 100755 vendor/assets/stylesheets/blueprint/src/grid.css create mode 100644 vendor/assets/stylesheets/blueprint/src/grid.png create mode 100644 vendor/assets/stylesheets/blueprint/src/ie.css create mode 100755 vendor/assets/stylesheets/blueprint/src/print.css create mode 100755 vendor/assets/stylesheets/blueprint/src/reset.css create mode 100644 vendor/assets/stylesheets/blueprint/src/typography.css create mode 100644 vendor/assets/stylesheets/jquery_ui/jquery-ui-1.8.16.custom.css create mode 100644 vendor/plugins/.gitkeep diff --git a/.rails_footnotes b/.rails_footnotes new file mode 100644 index 00000000..1019a70a --- /dev/null +++ b/.rails_footnotes @@ -0,0 +1,3 @@ +#this code temporarily disables notes for all controllers +# Footnotes::Filter.notes = [] + diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..53607ea5 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--colour diff --git a/.rvmrc b/.rvmrc new file mode 100644 index 00000000..8ad3b66d --- /dev/null +++ b/.rvmrc @@ -0,0 +1 @@ +rvm use 1.9.2-p290 diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 00000000..121ae398 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,28 @@ +v 1.0.0 + - bug fix + - projects preview mode +v 0.9.6 + - css fix + - new repo empty tree until restart server - fixed +v 0.9.4 + - security improved + - authorization improved + - html escaping + - bug fix + - increassed test coverage + - design improvements + +v 0.9.1 + - increassed test coverage + - design improvements + - new issue email notification + - updated app name + - issue redesigned + - issue can be edit +v 0.8.0 + - sytax highlight for main file types + - redesign + - stability + - security fixes + - increased test coverage + - email notification diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..353af0e1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,50 @@ +source 'http://rubygems.org' + +gem 'rails', '3.1.0' + +gem 'sqlite3' +gem 'devise', "1.4.7" +gem 'stamp' +gem 'will_paginate', '~> 3.0' +gem 'haml-rails' +gem 'jquery-rails' +gem 'grit', :git => 'git://github.com/gitlabhq/grit.git' +gem "carrierwave" +gem 'six' +gem 'therubyracer' +gem 'faker' +gem 'seed-fu', :branch => 'rails-3-1', :git => 'git://github.com/mbleigh/seed-fu.git' +gem "inifile" +gem "albino", :git => "git://github.com/gitlabhq/albino.git" +gem "kaminari" +gem "thin" +gem "git" + +group :assets do + gem 'sass-rails', " ~> 3.1.0" + gem 'coffee-rails', "~> 3.1.0" + gem 'uglifier' +end + +group :development do + gem 'rails-footnotes', '>= 3.7.5.rc4' + gem 'annotate', :git => 'git://github.com/ctran/annotate_models.git' +end + +group :development, :test do + gem 'rspec-rails' + gem 'shoulda' + gem 'capybara' + gem 'autotest' + gem 'autotest-rails' + gem 'ruby-debug19', :require => 'ruby-debug' + gem 'awesome_print' + gem 'database_cleaner' + gem 'launchy' +end + + +group :test do + gem 'turn', :require => false + gem 'simplecov', :require => false +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..46c908a1 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,277 @@ +GIT + remote: git://github.com/ctran/annotate_models.git + revision: cfeec96c9ca0fa5035b10be3d73e798cc4fc52f7 + specs: + annotate (2.4.1.beta1) + +GIT + remote: git://github.com/gitlabhq/albino.git + revision: 118380924969f3a856659f86ea1f40c1ba7bfcb1 + specs: + albino (1.3.3) + posix-spawn (>= 0.3.6) + +GIT + remote: git://github.com/gitlabhq/grit.git + revision: ff015074ef35bd94cba943f9c0f98e161ab5851c + specs: + grit (2.4.1) + diff-lcs (~> 1.1) + mime-types (~> 1.15) + posix-spawn (~> 0.3.6) + +GIT + remote: git://github.com/mbleigh/seed-fu.git + revision: 29fe8c61ca6cc4408115ea7475fe2647081bd348 + branch: rails-3-1 + specs: + seed-fu (2.0.1.rails31) + activerecord (~> 3.1.0.rc4) + activesupport (~> 3.1.0.rc4) + +GEM + remote: http://rubygems.org/ + specs: + ZenTest (4.5.0) + actionmailer (3.1.0) + actionpack (= 3.1.0) + mail (~> 2.3.0) + actionpack (3.1.0) + activemodel (= 3.1.0) + activesupport (= 3.1.0) + builder (~> 3.0.0) + erubis (~> 2.7.0) + i18n (~> 0.6) + rack (~> 1.3.2) + rack-cache (~> 1.0.3) + rack-mount (~> 0.8.2) + rack-test (~> 0.6.1) + sprockets (~> 2.0.0) + activemodel (3.1.0) + activesupport (= 3.1.0) + bcrypt-ruby (~> 3.0.0) + builder (~> 3.0.0) + i18n (~> 0.6) + activerecord (3.1.0) + activemodel (= 3.1.0) + activesupport (= 3.1.0) + arel (~> 2.2.1) + tzinfo (~> 0.3.29) + activeresource (3.1.0) + activemodel (= 3.1.0) + activesupport (= 3.1.0) + activesupport (3.1.0) + multi_json (~> 1.0) + addressable (2.2.6) + ansi (1.3.0) + archive-tar-minitar (0.5.2) + arel (2.2.1) + autotest (4.4.6) + ZenTest (>= 4.4.1) + autotest-rails (4.1.1) + ZenTest (= 4.5) + awesome_print (0.4.0) + bcrypt-ruby (3.0.1) + builder (3.0.0) + capybara (1.0.1) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 0.1.4) + carrierwave (0.5.7) + activesupport (~> 3.0) + childprocess (0.2.2) + ffi (~> 1.0.6) + coffee-rails (3.1.1) + coffee-script (>= 2.2.0) + railties (~> 3.1.0) + coffee-script (2.2.0) + coffee-script-source + execjs + coffee-script-source (1.1.2) + columnize (0.3.4) + daemons (1.1.4) + database_cleaner (0.6.7) + devise (1.4.7) + bcrypt-ruby (~> 3.0) + orm_adapter (~> 0.0.3) + warden (~> 1.0.3) + diff-lcs (1.1.3) + erubis (2.7.0) + eventmachine (0.12.10) + execjs (1.2.6) + multi_json (~> 1.0) + faker (0.9.5) + i18n (~> 0.4) + ffi (1.0.9) + git (1.2.5) + haml (3.1.3) + haml-rails (0.3.4) + actionpack (~> 3.0) + activesupport (~> 3.0) + haml (~> 3.0) + railties (~> 3.0) + hike (1.2.1) + i18n (0.6.0) + inifile (0.4.1) + jquery-rails (1.0.14) + railties (~> 3.0) + thor (~> 0.14) + json_pure (1.5.4) + spruz (~> 0.2.8) + kaminari (0.12.4) + rails (>= 3.0.0) + launchy (2.0.5) + addressable (~> 2.2.6) + libv8 (3.3.10.2) + linecache19 (0.5.12) + ruby_core_source (>= 0.1.4) + mail (2.3.0) + i18n (>= 0.4.0) + mime-types (~> 1.16) + treetop (~> 1.4.8) + mime-types (1.16) + multi_json (1.0.3) + nokogiri (1.5.0) + orm_adapter (0.0.5) + polyglot (0.3.2) + posix-spawn (0.3.6) + rack (1.3.2) + rack-cache (1.0.3) + rack (>= 0.4) + rack-mount (0.8.3) + rack (>= 1.0.0) + rack-ssl (1.3.2) + rack + rack-test (0.6.1) + rack (>= 1.0) + rails (3.1.0) + actionmailer (= 3.1.0) + actionpack (= 3.1.0) + activerecord (= 3.1.0) + activeresource (= 3.1.0) + activesupport (= 3.1.0) + bundler (~> 1.0) + railties (= 3.1.0) + rails-footnotes (3.7.5.rc4) + rails (>= 3.0.0) + railties (3.1.0) + actionpack (= 3.1.0) + activesupport (= 3.1.0) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (~> 0.14.6) + rake (0.9.2) + rdoc (3.9.4) + rspec (2.6.0) + rspec-core (~> 2.6.0) + rspec-expectations (~> 2.6.0) + rspec-mocks (~> 2.6.0) + rspec-core (2.6.4) + rspec-expectations (2.6.0) + diff-lcs (~> 1.1.2) + rspec-mocks (2.6.0) + rspec-rails (2.6.1) + actionpack (~> 3.0) + activesupport (~> 3.0) + railties (~> 3.0) + rspec (~> 2.6.0) + ruby-debug-base19 (0.11.25) + columnize (>= 0.3.1) + linecache19 (>= 0.5.11) + ruby_core_source (>= 0.1.4) + ruby-debug19 (0.11.6) + columnize (>= 0.3.1) + linecache19 (>= 0.5.11) + ruby-debug-base19 (>= 0.11.19) + ruby_core_source (0.1.5) + archive-tar-minitar (>= 0.5.2) + rubyzip (0.9.4) + sass (3.1.7) + sass-rails (3.1.1) + actionpack (~> 3.1.0) + railties (~> 3.1.0) + sass (>= 3.1.4) + tilt (~> 1.3.2) + selenium-webdriver (2.5.0) + childprocess (>= 0.2.1) + ffi (>= 1.0.7) + json_pure + rubyzip + shoulda (2.11.3) + simplecov (0.5.3) + multi_json (~> 1.0.3) + simplecov-html (~> 0.5.3) + simplecov-html (0.5.3) + six (0.2.0) + sprockets (2.0.0) + hike (~> 1.2) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + spruz (0.2.13) + sqlite3 (1.3.4) + stamp (0.1.6) + therubyracer (0.9.4) + libv8 (~> 3.3.10) + thin (1.2.11) + daemons (>= 1.0.9) + eventmachine (>= 0.12.6) + rack (>= 1.0.0) + thor (0.14.6) + tilt (1.3.3) + treetop (1.4.10) + polyglot + polyglot (>= 0.3.1) + turn (0.8.2) + ansi (>= 1.2.2) + tzinfo (0.3.29) + uglifier (1.0.3) + execjs (>= 0.3.0) + multi_json (>= 1.0.2) + warden (1.0.5) + rack (>= 1.0) + will_paginate (3.0.0) + xpath (0.1.4) + nokogiri (~> 1.3) + +PLATFORMS + ruby + +DEPENDENCIES + albino! + annotate! + autotest + autotest-rails + awesome_print + capybara + carrierwave + coffee-rails (~> 3.1.0) + database_cleaner + devise (= 1.4.7) + faker + git + grit! + haml-rails + inifile + jquery-rails + kaminari + launchy + rails (= 3.1.0) + rails-footnotes (>= 3.7.5.rc4) + rspec-rails + ruby-debug19 + sass-rails (~> 3.1.0) + seed-fu! + shoulda + simplecov + six + sqlite3 + stamp + therubyracer + thin + turn + uglifier + will_paginate (~> 3.0) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..7cecc248 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011 Dmitriy Zaporozhets + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 00000000..20097787 --- /dev/null +++ b/README.rdoc @@ -0,0 +1,85 @@ +== Welcome to GitLab + +GitLAb is a free Project/Repository managment application + +== Application details + +rails 3.1 +works only with gitosis +sqlite as default db + + +== Requirements + +* ruby 1.9.2 + +* sqlite + +* git + +* gitosis + +* ubuntu/debian + +* pygments lib - sudo easy_install pygments + + +== Install Project + + + git clone git://github.com/gitlabhq/gitlabhq.git + cd gitlabhq/ + + # install this library first + sudo easy_install pygments + + sudo gem install bundler + bundle + + RAILS_ENV=production rake db:setup + + # create admin user + # login....admin@local.host + # pass.....5iveL!fe + RAILS_ENV=production rake db:seed_fu + +Install gitosis, edit conf/gitosis.yml & start server + + rails s + +== Install Gitosis + sudo aptitude install gitosis + + sudo adduser \ + --system \ + --shell /bin/sh \ + --gecos 'git version control' \ + --group \ + --disabled-password \ + --home /home/git \ + git + + + ssh-keygen -t rsa + + sudo -H -u git gitosis-init < ~/.ssh/id_rsa.pub + sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update + + +== Install ruby 1.9.2 + + sudo aptitude install git-core curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline5-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev + + wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p290.tar.gz + + tar xfvz ruby-1.9.2-p290.tar.gz + + cd ruby-1.9.2-p290 + ./configure + make + sudo checkinstall -D + + sudo gem update --system + + + echo "gem: --no-rdoc --no-ri" > ~/.gemrc diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..35b2f05c --- /dev/null +++ b/Rakefile @@ -0,0 +1,7 @@ +#!/usr/bin/env rake +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Gitlab::Application.load_tasks diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..3eefcb9d --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/app/assets/images/.directory b/app/assets/images/.directory new file mode 100644 index 00000000..93a51f7c --- /dev/null +++ b/app/assets/images/.directory @@ -0,0 +1,4 @@ +[Dolphin] +ShowPreview=true +Timestamp=2011,9,14,20,34,18 +Version=2 diff --git a/app/assets/images/ajax-loader.gif b/app/assets/images/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ca7ada960568fff04400cda966fbdcb106abfa2 GIT binary patch literal 6820 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/blueprint_add.png b/app/assets/images/blueprint_add.png new file mode 100644 index 0000000000000000000000000000000000000000..0969428c865f152da486c9a8cc580e565a44bacd GIT binary patch literal 4544 zcmV;x5kKyUP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000K-Nklwh1*X9H6guCQ+` zdz~j!2C?;c{ax$raeU{W0m#j~I}@E4SZ?oRWYDX3{9PqbAQEn6&4*j4yL5__MJqYJ z>n{Kt-0*g{CSpE&!_3&6e;qT}SrYD6MPYlvb<7kqqi@1crYu~6nUVI)t9DNY7Ed3H znUOxecb6(=JU*^BqRN8FgHbii3{fRMVF;5KEXT~4wd581!Ui@TuEEUMexkWc6)|=d zH{-G2=X(pbmLr(d=&WZoAoZ(JV& zHReqjikhOPh)Q(!Nf=D((=XG~SV!tpKexL!ka@5gGh<6(;~gqu>?mr}J;hBpG4>Qx zW2(@BK$OINLzuC66|If+q%QuMb^8<~&wbujXJpXhGf#mTh=Cf2wq1*YGb0jiMb!9s z-DVoDobD9$gn2J=a_?U$*!FJd^9iW&x15WZ8k_PPqUzMxdaMB_%Fdz&0#UMx+cfWt zM9Ovs|D6eXuv-i#& z1jatP)YiQB0iud_sJV-#w`lq{A{Lz;6N|K6Yy0%VEo}MVca-O5c28h!ZViERtj(^% z4;+~X+H~u|D*PZ|ciwsYAYgC)1p+@Hx9}1{;B%z-3cl}CSayvd@F_W6PvHAhRNbVk z^6K3Y7(Hu=tzPp!fgkx)a@U^zcD>Pm$ICA0wfpZj=UM6sk z;>sGFILgn~QdV&ZGi7eZjOgr?z^K&4_V&B)<9Xpv)!L~=dqBn7X|yM9Pp_&t@u_Xi zry){=uT7XaddBqUD>36Zy8b957GH@H$X=CyCjm9%j0_dSW@x&7Q-Ek=GbD{~AE@ z=k`G2^zYi68Smjm!X3JtPHNuX?d=r2po!9k->_)fH<>XemHKckw<1jh63{!QHwkeA zD8E$3wqu(cfEmEqP6?P9nfuP+MA?{il0cMg`$`Z|cITGiMA&=y6oCji1!r(hI8t<; z3%52fcVZe-Mo*=(p^TcQt2{IM`z#y#L#l6F=EUV=j2xWEf{BX;0DtPT300Nvq$LuF z@x<(LI58HaeH|ytoYb%3M0hmitB6x(OdN@b@bK7pZg@q^pOntU#wtADBMAKHn!Xpo z^E`?#9VdBsGDGegI_GvN?l6GCC;QGIqHM`Ji8y8Fz7m`WS-ItiQ}*Yb#))wF*g2dN ziq9P-C21NB;d)vk&8&F%C4Mw%RdmT$ANw`Gock7$a0}OOUS;Hc|yL@v};(K|LCuf5)$7wOOg9=`A62LTCv2T*;Z8sJdp1Tc2wRAR9``FlY% z8q%Ep!a zblr>i?M*o`F@@{5YPoWwx)M0j={|7(ga!9>GU_u>NKC)Qvon`6pzi=qRhLkA^E%Es z`o{HR?C@kf_1Ikai2!qfoa|NkU;b=(drxm4bAXRhN6mb2{P6J%h#!ckqoMf*mDegb zaxSk9SPAU7y%qnb4FL25-T)TF#>6IvLLr>Eav%rz6;RjlUC`sdaNunQUIShem0mzB e5bo;F{~7?M4ORypt&d0m0000KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000KXNkl1>~G=#?07X+Hp@5F%FgW#Sh9mabkQ>+>EKh zZ3Mz3zB-ZgP0!NP(MHCmU)Zp-Aa(VRZRd_1MBOzD%s>p(K(y~z6r34>-X27ax8He> z_Uo4iMLl=TPxCN^OP8-Mr|u?aKy_U0|bCd@!o2z0g$zYe6V{E_W^X$Mg;eFTg?r)m~< zEe1|O)Np2f=hO)Hb|Y$tDI$idBC3cQDnibmw^MoQ9pA7uu&=ZWGv(dFn>bPS72U*% zaj@8rC&tlIKb|PLIR+{qT+HJUMNIO!zWbL z{_Fk-Jes-LcJ6u=FBG`Lx$Ad7kZ-4k4!Ac(#roa+J6ZwX&RR z#YOEvI#53-0W%}#El{GT!;vS~Y znMwTog=o`tw51jMvKwHd+vDP^&yK;Rry}lR6H@hyD|kQMt0UL zoG7a@l5ip{Pn(7~C4JsE5D_vHM=|+&DGx19$69WJYTvs;9vTQCJprUAK%lIK@efZW zX3W@C1F49*XJQ)s<76G{(;wo%i3&EXoWqg4O1`yx7ROK5urecwyrRo2OPfaFg$5SS zn?j(hh`6LAd_Er<3=;E`X9xWtwf=l7ks*&Uv0o$D{pl*8Vvr(KHe@B@sj+@#3QmPJ zS;;sNR%Fb;sjzfWB2I*~d5<6}%$(q3#F(!P|Nj^Wp}`PQBVqvJha_Ua4`Y{}UZf|` zH+ab5i;P6X0dx#r17@ttoQ@Oa@fEWX5mqfr#yKTx@eD+S^aWE96&9sFf`~FQc^+Li zZeY&ck@LF;A85TDw*bxzDgcZ_`L$T&2#yywqY=^Mm9=0IBPgu!V-X`LsksG_F??9p zi7zUef}3OcSjXY7sw84c!jOZHT9QJi{{}sspVR{923-f@=Vm|9&S-j!}b^2PUt18aJJTLru|A#uj!adGiP z_y5!cd%EcKx6;;h#Sc6K92!`PqrT+5=1CyAt+D>MZH@KWK3_yCJ}}j4ARqW0;J^KW sFIxaW7w|mryqQL0L;}4--Ta>c0J}~)i9@k45C8xG07*qoM6N<$f){#qM*si- literal 0 HcmV?d00001 diff --git a/app/assets/images/blueprint_info.png b/app/assets/images/blueprint_info.png new file mode 100644 index 0000000000000000000000000000000000000000..8278b9da7af95d32b20874737e25bd147278c670 GIT binary patch literal 4512 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 RV8Q?Z002ovPDHLkV1kBFk8%J2 literal 0 HcmV?d00001 diff --git a/app/assets/images/dir.png b/app/assets/images/dir.png new file mode 100644 index 0000000000000000000000000000000000000000..bd941249c8797e0f13c4cd1235dc681ac8083433 GIT binary patch literal 485 zcmVMxZ8V0!t+`;Y=SCH)IKPdm;zP$R}ULiyv;!R~{7wO)X=ZcmE!;pFS`kJsy$wZ;_qaY#aVlftm`^b%;s20MrTT z@iVM%-kt{v!~7RQ@e0Ku3PTh|C{D=E--Ajl0VKr|o4sp-;~0eks|P3!Ar!5DgyIxb zLA|s_DkKY7{k_Q)hbR>7eb8ne%>h!FFSY@A$q`Zb)e4J6*>Q-%cpp1d%zFh(Ct;h7NS>XTv bjlTiDh#!C9+nP=Q0000vYhz#zuJz@P!dKp~(AL>x#lFaYJy!T45do8P~GGlTs0_3Ky8W5Z{NPHAt@>KUrbE=zp${#e*po(|Gd1s|KGoV&kxdj z{``3hpx(dc<`y58EnAj#>eMN_#Kfd+Dk`e~Z{5131=24gE%V>n%KG|*2@}fu`})g! zdwa{jfB()7(qCI!x4_WA=>LipE3!a*5N>X6o}{Lx4%B}etY1!6?tgSt^j4TWG7S_z zZ(?lv|MBC;${_L9mewgY);6y+H8lSN?bf<;=Z=QFyu$z3m{_d(Lqo!@o10nufA#8> zBuM|{Nt0VsQ&V>*CnxWI^7x57NWY?@(*M}lIIQ~f^9pubSz7-;dGeGqvb$hxkbY$) z<^S<<@mTe*UbQ;U*2eCCdRoTOPoF-4!}Q0GAM87J><9yy0n!f&%lLTg`ax>5va*kY z%y4#c`5X}*an;tw_Oq*t+f#`CyBeyhYX1}B6R_G3QUi<&PGA}+&CAW-n-HIPs=T~n z#qM3ZLqKvbfa$8Rpm5oY88ga3{NaTefc`3mA=IKEaI{L7G1F!TLu3$3LRfvb|8PU(Dp;p z(@z-g6|U3VctBxUftcon!xkM!uDnSOS?(YvSy#FHlNGC!a#%wDQ|3~6S^2F?@_%$% zw4_$3f7%tky8EPTr%}w+MJsi8s|ITB2@ZTD`aZn=pt#+}%*V#34&5%e_guNmQDvfs c%0F>++f46GOzWJ!0)5Be>FVdQ&MBb@0CXgQ?EnA( literal 0 HcmV?d00001 diff --git a/app/assets/images/git.png b/app/assets/images/git.png new file mode 100644 index 0000000000000000000000000000000000000000..cb5d0590efadff8b35007ac6f6dc07b2d6d326c9 GIT binary patch literal 21559 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 Ai2wiq literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_flat_0_aaaaaa_40x100.png b/app/assets/images/jquery_ui/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..5b5dab2ab7b1c50dea9cfe73dc5a269a92d2d4b4 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FscKIb$B>N1x91EQ4=4yQ7#`R^ z$vje}bP0l+XkK DSH>_4 literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_flat_75_ffffff_40x100.png b/app/assets/images/jquery_ui/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000000000000000000000000000000000000..ac8b229af950c29356abf64a6c4aa894575445f0 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^8bF-F!3HG1q!d*FsY*{5$B>N1x91EQ4=4yQYz+E8 zPo9&<{J;c_6SHRil>2s{Zw^OT)6@jj2u|u!(plXsM>LJD`vD!n;OXk;vd$@?2>^GI BH@yG= literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_glass_55_fbf9ee_1x400.png b/app/assets/images/jquery_ui/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..ad3d6346e00f246102f72f2e026ed0491988b394 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnour0hLi978O6-<~(*I$*%ybaDOn z{W;e!B}_MSUQoPXhYd^Y6RUoS1yepnPx`2Kz)7OXQG!!=-jY=F+d2OOy?#DnJ32>z UEim$g7SJdLPgg&ebxsLQ09~*s;{X5v literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_glass_65_ffffff_1x400.png b/app/assets/images/jquery_ui/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..42ccba269b6e91bef12ad0fa18be651b5ef0ee68 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouqzpV=978O6-=0?FV^9z|eBtf= z|7WztIJ;WT>{+tN>ySr~=F{k$>;_x^_y?afmf9pRKH0)6?eSP?3s5hEr>mdKI;Vst E0O;M1& literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_glass_75_dadada_1x400.png b/app/assets/images/jquery_ui/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..5a46b47cb16631068aee9e0bd61269fc4e95e5cd GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJjgAK^akKnouq|7{B978O6lPf+wIa#m9#>Unb zm^4K~wN3Zq+uP{vDV26o)#~38k_!`W=^oo1w6ixmPC4R1b Tyd6G3lNdZ*{an^LB{Ts5`idse literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/app/assets/images/jquery_ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000000000000000000000000000000000000..7c9fa6c6edcfcdd3e5b77e6f547b719e6fc66e30 GIT binary patch literal 101 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-icons_2e83ff_256x240.png b/app/assets/images/jquery_ui/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..84defe6e8ab878a83d7ed145c4734e5e1117cf0f GIT binary patch literal 5355 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 X_Gc^EhHU=dFY}4IzFMt{L(KmGE`UUf literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-icons_454545_256x240.png b/app/assets/images/jquery_ui/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..59bd45b907c4fd965697774ce8c5fc6b2fd9c105 GIT binary patch literal 4369 zcmd^?`8O2)_s3^p#%>toqJ#RmwV2==ic*rz7lOw=eaq=H~;_ux21)-Jpcgw zdj+hrf&W^f<%Qk9Zpqf#;jH;N^Z%VA?R|9mZ{esQd(2F=?y+!`XZ5CR?ue=UdHIfUDFM*m15I;g=VN2jw zQW9?wOhDI#+P0|`@JQoC3!pu=AzGMtYB>V&?8(2>_B5_p`1Sb1t{^|J%bZYv09RS? zQ*dcs7}$)taJ@vX0E<96P{ur)Eygr{&ALyNoMP%_94m}=qFVT)&CeG1DBBMLUSKP^ zp%%Q3$MEtKll)X*+$)3O_3x`4%cHY0uhy7U;5x^Ir}X1)mv&B%|A)@A$a>f}tP{5X z9-gkti`YyT+hk9)cZW7fAQhjT%$XLLI^&VR=qev36;`WGBOP!^&(?!sK6jSH0Dnz4 zoEMMNu}y&n=rd-GWI?rGBI8!GD*NJ$k&e5-6+~-9F^6tV<=5`FcY~t{iqRcncEU+F zkT~jww!oy(@~b~WGI8!lzjURX&IpJjFGxShOKUunP+rW$I{c|x0qM6!Gxf6n(;$D> z+QYiULqq)Fy4VDk&Mev)NyM@nvF z7O6M*A$C)kBi0HGMT_+xfQ^USTM)>*h_Rx%eSRxA%n|FuC&=F=Pz}E5uCqbcy;7j=%Qh`glqEA-jx0(a<)uKO5Fe|JLD-ndZ-vnW`G=O&^%pa}Ah(2%m?oANs{lJ`?RhrZ8n!`Q97TKw{YAw9 zD)=M{mD(~_jj`LTd%q6Veum)Cnd!7lw}(5h%ubHcg^2O`prn%u9es3C#&%TsnmSD3%3Ik^Yd@6-d%(I7kqT(B@dVX2 zIidXgd>qYT-oTZ=1sGI7^*_E9Q)1F2mooE0R zXopPnh^ci@+wz2ZDjo&Owyxh6t90Gt!u0miLxc!bue^LvHF?)O@Yf!dQUXfW$u8(f_n07^N)-vpIe;TrHv5uKm{h_v`-IN^zwWc>Lk ziGsSr89sDcdOR_wa~DjrqV&Nd*$18(vohPJ3hSzEJPF2d!u}415wrSMtS(zNa7 zbO0G4ajgKNp{`D7DO<(T?wowarQ0dIKLb<}#prQM)ytB73YNTPQgX^xoT zm>;yKSJ*c@QfD8HW`6&+mowOaA|A&~G0fO6&xwj;E3O9^Zu~ZXts~;-d%FyyeXrijORi<_S(dw_5@h&-fTY?#FJo% zQZZ1&ED%$if+n8JVM{s-ZoK@P>p@z4s`AoI6hYxE!Ie_Y)cpjZjc8@~uNMYVfy#J$ z)+sdEX7DK^{}kUAST8U6^p6#c>0Lc>T~9`0}`*2 zizaU)TFS4(u;BenUWZr?s{D)Z)rc9L5&gUvz3iSQaF#J)D)Ts{YgagdDcI1S`dtes zPqb4|h-RIkjhnpmn(Q2Je6Di5C?MkCUL)!WoKn|P#al41v#-Q8`K1$Gh64UhPQj|T zaZb%tJ}O{A?Cvl26!jeKS3OUkp5@8RDBYwh`Loxb5W<^m*R37+v}#*m-G{{ocF-#r z7!k3ZS^4Qu9sNRNZ3`laW2TqV{rsR#~gtVp6C zL0?}~gbLTv^jqtPQD@Cpq6{B6v&*Y)?tx})z=qQNB4Z_59 zpI2L)xQ`!|J8wWgs82jSw_8(;#}y7~Y^&hY9P1G)@`CGtIi*tZ%-%&;$PuG(!M%)E zQ?T#imBH8dCZxUBX^RWPwIh9LcnL3#$befQDr@UJl{=}o0){qIt52vU9X=3L_gvVW zPqp_YhhpM6XiE7Lvn-G0Wzo>0;g|$_-7|ucz~*w%bW@hr6M?~v9dT}L=>UotTj13& z?Uvt0_uOvzMq4iG6)gZqeU;W=P@EVod;}Vr7P*@=C19v;iz$4N+c5ewauTtKK5e;yIx(FQUec0 z`G)VlTUY|m2L=KusMRgMlapu#wt8MohK3=y`!J`tD6nYd%?xIZO`Q)skL)R%3Vf(P z__5Sx3h%fKF=sNdZo2p(w=_|}1M%ri7fO?8))sU1ySG;M4p4;zrr}4l0lzvA!WQ&a zrwX>%lJkv`Gr_u=K>kHOg6(AB(R3FOryElY)-vi|fRsBS<)$1;TC_?BnyScjY6>_ZD=T|bjcbjz@D6V+yfHd4SU+J*2Dh%n;$5ou zHh6R=)$>IH@%5js2KH#JkfFCVI}P>~U;|}>kk|06tA}^~B;|gJ$UvSF-l4GX43DAR z&M2mp8OgiTaK4li0|Q2qmGNYsm+Qq^JM8yfCP>5!31rjh4Mnq~+5X8+_$scfP1Fp!c zcQO*#6cfJ?ZRxn_$Se_|}Xo1oIF7s(7CllypCW@W8-y5%Bel_K*0G zd~8UWeYCWz>~^hF3ond|tQcClJ(8^9FW&&?U)a4O-pE;Y*u|FHGax>F*Kg_beOF5c z&?#xRN5Q?ckEwCnNr-${XC=w-te5%QH(6O~yxke=R!_ns))PU07Pu)CY`<>$+XicZ zCI=g^;q7NZnw=-vf;HoWLD+}`&Bph>kiqyX5jxjI1A41d$R3nahq@CHULV#9ItIwJ z0)^JGy{hB;@SD|}Zel8~2z;UjN96MR@dt;EV`9RP4X&zn8ib=n*107cICSp7z6srZ~4Qg|Vp$OB0By{IxAPaD7HGFw_HTza~wWN1A6 z3`7BZFse2a4{y#V^&;nRVcZOz*2>A?jm$%?)KawLR0cEz24qxxOOo9_2)9MrWpSg7 zPiPz+M7(zPRZ3$#11ti?uI!}bM!Dg%L#+uR+^2L2RX+QlMpL zg_DrR=GIT7C~b+^OZK)?l7*9c-78zWVbLo1oS}bItdscuF80}guwA8c^(47DfaBjV z^V@&JJHxYHqS+e7&X;ezZwsE2+t~n0?*m^(db@WnI{LgAnOqOa<8pRvo0E>*O&~J_ z&A)t2LOG)5=3$3n2_gi2Kpvgv)#LCUh2Y~ z!A&(~-8reT$sJk0=L;m~ES3k}k% zkF%gzzT(+nRU0IeUvuW8pq=8uzr&7HW>K5ZiD*8qL17AI^ zGqo>*mvIChU6+&t{A3|!W?~pi9_O$>k2d|#(Z721wcT{S1)_UFZ+}QS^KZ*u?5Y~bz z^cLI;2{$C_ZwWqM@sYMYwG+^N<^Ivq8ZOwV;7xT+WCh)I9PHC}ut;VNr?w z<@?HsG!Qg3zaV+-xQ3ldtad!U<6iGz_enGH*2akP_r)o1D&8p^5M)_c8IIj6Wy*7HJo&CBLuo~nj>(63pZzO(Vv^ZuB3 zMYigjkwA;FEy|G}1jpiMj6|NTm7Uyiw=@FDE*nX<>jR!W@9XIyf%$Fd*J5*D0Z0Lm z9}ZQxyT|x5ftNy?V>EbJz-K>bV9gs9RaXUP<^=;e?&Fqxj;6{ieR-a-@HycA1KMKhql8GOmcxwZ?_-(3hMK^^a*(gaFvBH ziIC!fgH4$W*NbKIaY&T?%&13``KbD@S-0`xQ%v3TV+B!;RC7O!+1a9QCA$H@3tR;k z)SSoR7(s4)f{zM}eWgFN{(ZH5d1O}l)f$ruT!)Q&NImXyZsTzOf9TwctcSfr+M)aJ z5otO+$jvm-P4)ykH)x|cO5xeb>?!`qGw$(>&axqLL6yoB${vsMXgL_-bz@2J_tS92 zdvZG-+vKl@K4Vr(EL{WQt@Z+Ea-hxX0}nTSZxnpi^#Kn8Ox8FgIS|hc}KJQ4tm*HO16ui{(O9} z1YN)GjiQt6fGq`Cj+^`zUf?8hk^(T{{cOQGWFP98am}is28A!5%{R#ENv8fCN!j69 zlMEK(2z?|BY=Je$XD9mB-Kkem*(d-j^9j$2#6r$Dz?s)-TCDCGCs z8>6Pvj{Y+YIeFA@qY22V$)awy@q!9A4rgk5b9TcC;s9Ig^G|6nDP+5=Fzg&?(L=vc zCbGd>fSu~@6!94td+o#d@sid!EIX$rx7*cawe6 z`dScJ+$HssdOjE)O#Ybs56vm-FQ$7yuJJD^Zqk%hMaIgAJ<2yb_MFQte_i;62ScT$ zpjifYyR_E=rQ+>H)pmlr-Udzg*-!|ssw(D7wJvC+Sf8bb9;;q8#z?0p!!bsd{wy|5 zpBaMHE-Ve>i#LLjHRaMLtp%9&(HCng7Sw96jVv!#0k%?F^K7&=T)mnYn)D9(i;4x5 z^NJTJwq~pv;kH@#ejTd*48~(J(r6j34|m`h9fEDj0im)~+%I5XphWymhT;_Zty|Q& zzjPg#-ufAHZ1M*Gccw?Kf|8Pnhtb0`!{N`Bqsa37J+>wC$!e z00k+2Egzz;rbcWoUB%Jvp8W1}$XD%e3>4y;;OZ1ccT-O#uW6Ys@C}Pa`nZrNKzR(2 z4e%3)@QI4SE&E!lW`5y14QhbepBG%_XBV-O(%5tj)@9#|;sC-MNev!zGDHk}JdpGC`iJF#8=8-P$Xoku_=Dw%Cv3{U7L>gf zRQ?<$t`cZ*MP5GQmbmx#!+*!zu>0MewRO9GFGS{b^m_fJ-N0?j@EqoFf>$khj+E|@ z7r3We&^tR^YZrxKe*d22agXqCO0l44&kqCv{u)T|(lv`~PK@DvE z{QI_TlCH5z*gR!>LO)k67{^R+vWx24U2^2ODXpwT;6y+6+$5m)_*w4WY&#do9dCeE z)>p+Ykdhq($DhmMiaYXey!@N%L26uz($aJ!QT{B^Wu}U$^9e#5)=c+XF9@Ill?ZmM zlNgHiz*9!vDc&uxOo;ZVxb`Q!Sk0*gnfxWzmbZh4(=%CD%qP?0=);n$&zaW_$UKV9 z8axdcN#AyZ{P)wj?V{P}vM)YY!>6@}^>U+iv$`9>nMTCPjN>z%yF&3yf%>+T@0vh4 zlC8Xa6zeo?%=o3}M8{aebLHcO{^1Ar8qiM=Gquf?Jo)q5`-+?sUpg?QXyEUpWSm+n z$K-UyqkIwHLquru~o(OF)hhz$Y*|X>ZIbswnxRvr~ z2=rdOGVuD|xRlpAZE<0!X1F(%Anpl^@V^D3vbM}qxe|NI;TTiZy7(IM;R69RkA>a& z6gwYE2sREzQ_LHmWqB+ogMk(fMaSFeoDq-!HkFB_nXt5+2ncFuk9BQL1I&oB1zZi) zYW{6_&-Ip1l*OVRA##1ILQS;5R{-K^0wGTiJbVSi@LA^$D$;@J>^G{6@&+%4{b3(s zC~LEHiTv(0b#zxt?YJ0r_~pUZM~mQ(??(n#>&tD%+@nq=Abj5*8R!~Ul1`G~=qFJ4 zfl|m8ZDCYgtr`4LcOpgiJYX9qRY5;DcWti~PmS$VB$E-Zt^f4)vLDOe_3XTq5^ylW zJ9PKm!V-8sAOJXnUfuFNIf0R9tK-pNs2hO04zr620}5B(Ok>yB)Of-3sP59qfQNbm zA4{w!2@cB;GbR(~szVrbO%(w=5S!X`o@o@x++wbN_tMPT0Vc)*I;Fgsbf^*g0 z2Di?HTApwKq3+YwfNsqd3iP%{hyK1iyuVZc@*0tO_3+N0#GFsz>8MjeJ2UJ%L!%hi zGYYAthH`E+ywA*u{(eJ=ia3h*%k?779rk-K<0VZAPkl;TFUbmei|$fqWO8!_zIvqt z$ly$VrlH46nnpX~X5Yk0iBJl;=WuA4>~X4-f&K0yWf42h&0b30t@NYX$7egQ1Fp!a zbui-D6cWCWV&|R1CY@G8(qOmWjWeX3eX7UggZPGimA}soOuQdXe4uZ#2>5zN>qlI0 z9xk}lE=tNpX1m6*nFr2EQ3xs79!^sCldDJYE$m(qYv3q7>}1R7?iZW7>$~*%zKaC| z=$N?ME$>#+%T&MZC`dW1wUl6Z)JgyCn~V%K&i0H|iwE%$>xsZW3tTfZxIUePci@p;cRu|d=ItIwF z1clVHy{hH?@SD|(Zfqi^0DQ1hczHN7xq85h)rzQqLHMX2^IkuK7FB!kI40s$|CY7~ zNX^{_UjN8}L%Med;|+=4RNTMozn8KT;2tb77bUPCmioh+rZBfIiM6f_P34cQ__o1G zWqQp3VL~~pE5?qODf%iiQQ3f42YF@09tQ*$4v_EKUx;t1KCPCBtgqg z@+Tn;O)a0uky_%jm+WjNB?=~VyH>V#L!*=l*@OS6SVyt_UEH&NA=?V2stHPyKkVNy z&jg<#cjros){#ji)dK z%)We0L_478=HZ8-@xnwsKrWs8)x`MB;(Y`Cmu2c-&SH(vN-F(*e`l?c%+l$|y_AJJ zhcDGnwLvN+bu;_sX|1AiePhx@u&%P$hf*xE+O=~D?_(_KGWQ!158YL-y9$*6mmPo;Rp*Dl5lm-mVM2i`h- zM@nxv590_tvMwPD_{l=b$iOm|+|S{D9&P%zeT$GgX6Akl-tfUF>tL@Ld!B&{pN39t zH>3Vhqkr}2Yul+jb7UiouWVGPNsxX7Ueba+9|~dz?d*QM$ng0DZfO0`7fAy?2yMm| zcnRzUhZ&IcwgjH9cuU!w+VStYa{p*)4IgBf|E8)sqMYtB2KH_}SfsFq(c9i(Q6S3U oBo%DI*Kv;w;*%(i9W@f3_WCF#rGn literal 0 HcmV?d00001 diff --git a/app/assets/images/jquery_ui/images/ui-icons_cd0a0a_256x240.png b/app/assets/images/jquery_ui/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab019b73ec11a485fa09378f3a0e155194f6a5d GIT binary patch literal 4369 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 AQ~&?~ literal 0 HcmV?d00001 diff --git a/app/assets/images/txt.png b/app/assets/images/txt.png new file mode 100644 index 0000000000000000000000000000000000000000..f3638cb4e1e109a4989fe8b2895d8c7071ec6bf2 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6UU<4VhG>Yg9yH7gc9dW{aP#=Q zMia*!O?^!o3q2G zY`JghdOyFg)mPme{y*5p+@0;BdH9~m9v0b*ytQqU7fyM}c7aikF>slX1N)CW2`^2< zSZ1pO)(nP%K>k9W%ONxF0r}D_j0`0W^Ot4LV!Fp<)$vV=p}}*LN}8-M1HiM%g8JmHAX7F_Nb6Mw<(8L7*1e|gF literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 00000000..01e3b416 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,18 @@ +// This is a manifest file that'll be compiled into including all the files listed below. +// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically +// be included in the compiled file accessible from http://example.com/assets/application.js +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// the compiled file. +// +//= require jquery +//= require jquery_ujs +//= require_tree . + +$(function(){ + $(".one_click_select").click(function(){ + $(this).select(); + }); + + $('select#branch').selectmenu({style:'popup', width:200}); + $('select#tag').selectmenu({style:'popup', width:200}); +}); diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js new file mode 100644 index 00000000..a62e9330 --- /dev/null +++ b/app/assets/javascripts/commits.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + $(".day-commits-table li.commit").live('click', function(e){ + if(e.target.nodeName != "A") { + location.href = $(this).attr("url"); + e.stopPropagation(); + return false; + } + }); +}); diff --git a/app/assets/javascripts/dashboard.js.coffee b/app/assets/javascripts/dashboard.js.coffee new file mode 100644 index 00000000..76156794 --- /dev/null +++ b/app/assets/javascripts/dashboard.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee new file mode 100644 index 00000000..76156794 --- /dev/null +++ b/app/assets/javascripts/issues.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/javascripts/jquery-ui-1.8.16.custom.min.js b/app/assets/javascripts/jquery-ui-1.8.16.custom.min.js new file mode 100644 index 00000000..14c9064f --- /dev/null +++ b/app/assets/javascripts/jquery-ui-1.8.16.custom.min.js @@ -0,0 +1,791 @@ +/*! + * jQuery UI 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16", +keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= +this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, +"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": +"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, +outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, +"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& +a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= +false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +;/* + * jQuery UI Position 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */ +(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, +left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= +k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= +m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= +d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= +a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), +g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); +;/* + * jQuery UI Draggable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== +"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= +this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;if(b.iframeFix)d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('
').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options; +this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); +this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true}, +_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b= +false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration, +10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle|| +!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&& +a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent= +this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"), +10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), +10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, +(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!= +"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"), +10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+ +this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&& +!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.leftg[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.topg[3])?h:!(h-this.offset.click.topg[2])?e:!(e-this.offset.click.left=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e=j&&f<=l||h>=j&&h<=l||fl)&&(e>= +i&&e<=k||g>=i&&g<=k||ek);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== +String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); +var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a= +false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"}); +this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff= +{width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis]; +if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false}, +_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f, +{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight: +Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(cb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left= +null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ +a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+ +c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]); +b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.16"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(), +10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top- +f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType? +e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a= +e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing, +step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= +e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset; +var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left: +a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top- +d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition, +f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, +display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b= +e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height= +d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); +;/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), +selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", +c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= +this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); +this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== +"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& +!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, +left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; +this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= +document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); +return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], +e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); +c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): +this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, +dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, +toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); +if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), +this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= +this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= +d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| +0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", +a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- +f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- +this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, +this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", +a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); +a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", +function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a= +this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); +this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); +b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); +a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ +c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; +if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(), +e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight|| +e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false", +"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.16", +animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/); +f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", +paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); +;/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.propAttr("readOnly"))){g= +false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= +a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; +this.menu=d("
    ").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& +a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); +d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& +b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= +this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length").data("item.autocomplete",b).append(d("
    ").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, +"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); +(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); +this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b, +this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("");e.secondary&&a.append("");if(!this.options.text){d.push(f?"ui-button-icons-only": +"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")=== +"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); +b.Widget.prototype.destroy.call(this)}})})(jQuery); +;/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, +position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
    ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&!i.isDefaultPrevented()&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), +h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== +b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1; +d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== +f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
    ").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, +function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", +handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, +originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", +f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): +[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); +if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): +e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= +this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height- +b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), +create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&& +c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(b.range==="min"||b.range==="max"?" ui-slider-range-"+b.range:""))}for(var j=c.length;j"); +this.handles=c.add(d(e.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle", +g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!a.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");i=a._start(g,l);if(i===false)return}break}m=a.options.step;i=a.options.values&&a.options.values.length? +(h=a.values(l)):(h=a.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(i+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(i-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===a._valueMax())return;h=a._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===a._valueMin())return;h=a._trimAlignValue(i- +m);break}a._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(g,k);a._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); +return this},_mouseCapture:function(a){var b=this.options,c,f,e,j,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(b.range===true&&this.values(1)===b.min){g+=1;e=d(this.handles[g])}if(this._start(a,g)===false)return false; +this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();b=e.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-e.width()/2,top:a.pageY-b.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b= +this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b= +this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b); +c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var f;if(this.options.values&&this.options.values.length){f=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>f||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= +this.options.range,b=this.options,c=this,f=!this._animateOff?b.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({width:e- +g+"%"},{queue:false,duration:b.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:b.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[f?"animate":"css"]({width:e+"%"}, +b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.16"})})(jQuery); +;/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
    ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& +e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= +d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| +(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); +if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); +this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ +g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", +function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; +this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= +-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; +d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= +d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, +e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); +j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); +if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, +this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, +load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, +"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, +url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.16"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k'))}function N(a){return a.bind("mouseout", +function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); +b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.16"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv}, +setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g, +"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('
    '))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker", +function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c== +"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f==""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker(): +d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a, +b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+= +1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ +2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b= +d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e= +a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a, +"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f== +a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input", +a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");c=c?c.apply(a,[a,b]):{};if(c!==false){H(b.settings,c);b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value= +"";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b); +c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing= +true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}); +a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&& +!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(), +h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b= +this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b); +this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, +_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"): +0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"? +"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a); +this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField"); +if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"? +b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd", +COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames: +null)||this._defaults.monthNames;var i=function(o){(o=k+1 +12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&& +a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay? +new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a)); +n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m, +g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+s+"":f?"":''+s+"";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&& +a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
    '+(c?h:"")+(this._isInRange(a,s)?'":"")+(c?"":h)+"
    ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='
    '+(/all|left/.test(t)&& +x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'
    ';var z=j?'":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="=5?' class="ui-datepicker-week-end"':"")+'>'+q[r]+""}y+=z+"";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay, +z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q";var R=!j?"":'";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&ro;R+='";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+""}g++;if(g>11){g=0;m++}y+="
    '+this._get(a,"weekHeader")+"
    '+this._get(a,"calculateWeek")(r)+""+(F&&!D?" ":L?''+ +r.getDate()+"":''+r.getDate()+"")+"
    "+(l?""+(i[0]>0&&G==i[1]-1?'
    ':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': +"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
    ',o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b, +e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
    ";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+ +(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input? +a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c, +e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a, +"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this; +if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a== +"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.16";window["DP_jQuery_"+B]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
    ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.16"})})(jQuery); +;/* + * jQuery UI Effects 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})}; +f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, +[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), +d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement; +if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)}); +return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this, +arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/ +2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b, +d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c, +a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b, +d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/app/assets/javascripts/jquery.cookie.js b/app/assets/javascripts/jquery.cookie.js new file mode 100644 index 00000000..6a3e394b --- /dev/null +++ b/app/assets/javascripts/jquery.cookie.js @@ -0,0 +1,41 @@ +/** + * jQuery Cookie plugin + * + * Copyright (c) 2010 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ +jQuery.cookie = function (key, value, options) { + + // key and at least value given, set cookie... + if (arguments.length > 1 && String(value) !== "[object Object]") { + options = jQuery.extend({}, options); + + if (value === null || value === undefined) { + options.expires = -1; + } + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setDate(t.getDate() + days); + } + + value = String(value); + + return (document.cookie = [ + encodeURIComponent(key), '=', + options.raw ? value : encodeURIComponent(value), + options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + options.secure ? '; secure' : '' + ].join('')); + } + + // key and possibly options given, get cookie... + options = value || {}; + var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; + return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; +}; diff --git a/app/assets/javascripts/jquery.ui.selectmenu.js b/app/assets/javascripts/jquery.ui.selectmenu.js new file mode 100644 index 00000000..d61d75f9 --- /dev/null +++ b/app/assets/javascripts/jquery.ui.selectmenu.js @@ -0,0 +1,845 @@ + /* + * jQuery UI selectmenu dev version + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI + * https://github.com/fnagel/jquery-ui/wiki/Selectmenu + */ + +(function($) { + +$.widget("ui.selectmenu", { + getter: "value", + version: "1.8", + eventPrefix: "selectmenu", + options: { + transferClasses: true, + typeAhead: "sequential", + style: 'dropdown', + positionOptions: { + my: "left top", + at: "left bottom", + offset: null + }, + width: null, + menuWidth: null, + handleWidth: 26, + maxHeight: null, + icons: null, + format: null, + bgImage: function() {}, + wrapperElement: "
    " + }, + + _create: function() { + var self = this, o = this.options; + + // set a default id value, generate a new random one if not set by developer + var selectmenuId = this.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 ); + + // quick array of button and menu id's + this.ids = [ selectmenuId + '-button', selectmenuId + '-menu' ]; + + // define safe mouseup for future toggling + this._safemouseup = true; + + // create menu button wrapper + this.newelement = $( '', { + 'class': this.widgetBaseClass + ' ui-widget ui-state-default ui-corner-all', + 'id' : this.ids[ 0 ], + 'role': 'button', + 'href': '#nogo', + 'tabindex': this.element.attr( 'disabled' ) ? 1 : 0, + 'aria-haspopup': true, + 'aria-owns': this.ids[ 1 ] + }); + this.newelementWrap = $( o.wrapperElement ) + .append( this.newelement ) + .insertAfter( this.element ); + + // transfer tabindex + var tabindex = this.element.attr( 'tabindex' ); + if ( tabindex ) { + this.newelement.attr( 'tabindex', tabindex ); + } + + // save reference to select in data for ease in calling methods + this.newelement.data( 'selectelement', this.element ); + + // menu icon + this.selectmenuIcon = $( '' ) + .prependTo( this.newelement ); + + // append status span to button + this.newelement.prepend( '' ); + + // make associated form label trigger focus + $( 'label[for="' + selectmenuId + '"]' ) + .attr( 'for', this.ids[0] ) + .bind( 'click.selectmenu', function() { + self.newelement[0].focus(); + return false; + }); + + // click toggle for menu visibility + this.newelement + .bind('mousedown.selectmenu', function(event) { + self._toggle(event, true); + // make sure a click won't open/close instantly + if (o.style == "popup") { + self._safemouseup = false; + setTimeout(function() { self._safemouseup = true; }, 300); + } + return false; + }) + .bind('click.selectmenu', function() { + return false; + }) + .bind("keydown.selectmenu", function(event) { + var ret = false; + switch (event.keyCode) { + case $.ui.keyCode.ENTER: + ret = true; + break; + case $.ui.keyCode.SPACE: + self._toggle(event); + break; + case $.ui.keyCode.UP: + if (event.altKey) { + self.open(event); + } else { + self._moveSelection(-1); + } + break; + case $.ui.keyCode.DOWN: + if (event.altKey) { + self.open(event); + } else { + self._moveSelection(1); + } + break; + case $.ui.keyCode.LEFT: + self._moveSelection(-1); + break; + case $.ui.keyCode.RIGHT: + self._moveSelection(1); + break; + case $.ui.keyCode.TAB: + ret = true; + break; + default: + ret = true; + } + return ret; + }) + .bind('keypress.selectmenu', function(event) { + self._typeAhead(event.which, 'mouseup'); + return true; + }) + .bind('mouseover.selectmenu focus.selectmenu', function() { + if (!o.disabled) { + $(this).addClass(self.widgetBaseClass + '-focus ui-state-hover'); + } + }) + .bind('mouseout.selectmenu blur.selectmenu', function() { + if (!o.disabled) { + $(this).removeClass(self.widgetBaseClass + '-focus ui-state-hover'); + } + }); + + // document click closes menu + $(document).bind("mousedown.selectmenu", function(event) { + self.close(event); + }); + + // change event on original selectmenu + this.element + .bind("click.selectmenu", function() { + self._refreshValue(); + }) + // FIXME: newelement can be null under unclear circumstances in IE8 + // TODO not sure if this is still a problem (fnagel 20.03.11) + .bind("focus.selectmenu", function() { + if (self.newelement) { + self.newelement[0].focus(); + } + }); + + // set width when not set via options + if (!o.width) { + o.width = this.element.outerWidth(); + } + // set menu button width + this.newelement.width(o.width); + + // hide original selectmenu element + this.element.hide(); + + // create menu portion, append to body + this.list = $( '
    <%= link_to truncate(@project.name, :length => 20), project_path(@project), :class => "current button" if @project && !@project.new_record? %> - <%= link_to 'Home', root_path, :class => current_page?(root_url) ? "current button" : "button" %> <%= link_to 'Projects', projects_path, :class => current_page?(projects_path) ? "current button" : "button" %> - <%= link_to 'Profile', profile_path, :class => (controller.controller_name == "keys") ? "current button" : "button" %> <%= link_to('Admin', admin_root_path, :class => admin_namespace? ? "current button" : "button" ) if current_user.is_admin? %> - <%#= link_to 'Profile', edit_user_registration_path, :class => "button" %> - <%= link_to 'Logout', destroy_user_session_path, :class => "button", :method => :delete %> + <%= link_to profile_path, :class => ((controller.controller_name == "keys" || controller.controller_name == "profile") ? "current button" : "button") do %> + <%= image_tag gravatar_icon(current_user.email) %> + <%= current_user.name.split(" ").first %> + <% end %> + <%= link_to 'Logout', destroy_user_session_path, :style => "border-left: 1px solid #666;", :class => "button", :method => :delete %>
    diff --git a/app/views/notify/note_commit_email.html.haml b/app/views/notify/note_commit_email.html.haml index 09ae54ac..81001d68 100644 --- a/app/views/notify/note_commit_email.html.haml +++ b/app/views/notify/note_commit_email.html.haml @@ -5,7 +5,7 @@ %td{:align => "left", :style => "padding: 20px 0 0;"} %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} New comment for commmit - = link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@project, :id => @commit.id) + = link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@project, :id => @commit.id, :anchor => "note_#{@note.id}") %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} %tr %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} diff --git a/app/views/notify/note_issue_email.html.haml b/app/views/notify/note_issue_email.html.haml index 54982af6..242c97bf 100644 --- a/app/views/notify/note_issue_email.html.haml +++ b/app/views/notify/note_issue_email.html.haml @@ -5,7 +5,7 @@ %td{:align => "left", :style => "padding: 20px 0 0;"} %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} New comment - - = link_to project_issue_url(@project, @issue) do + = link_to project_issue_url(@project, @issue, :anchor => "note_#{@note.id}") do = "Issue ##{@issue.id.to_s}" = truncate(@issue.title, :length => 35) %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} diff --git a/app/views/notify/note_wall_email.html.haml b/app/views/notify/note_wall_email.html.haml index 285fc763..c9fdae12 100644 --- a/app/views/notify/note_wall_email.html.haml +++ b/app/views/notify/note_wall_email.html.haml @@ -5,7 +5,7 @@ %td{:align => "left", :style => "padding: 20px 0 0;"} %h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} New message on - = link_to "Project Wall", wall_project_url(@project) + = link_to "Project Wall", wall_project_url(@project, :anchor => "note_#{@note.id}") %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} %tr %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"} diff --git a/app/views/projects/index.html.haml b/app/views/projects/index.html.haml index 22af6b75..888a72b6 100644 --- a/app/views/projects/index.html.haml +++ b/app/views/projects/index.html.haml @@ -1,4 +1,9 @@ -%div{:class => "tile", :style => view_mode_style("tile")} - = render "tile" -%div{:class => "list", :style => view_mode_style("list")} - = render "list" +- unless @projects.empty? + %div{:class => "tile", :style => view_mode_style("tile")} + = render "tile" + %div{:class => "list", :style => view_mode_style("list")} + = render "list" +- else + %center.prepend-top + %h2 + %cite Nothing here diff --git a/config/initializers/rails_footnotes.rb b/config/initializers/rails_footnotes.rb index da9d58e4..db71e39c 100644 --- a/config/initializers/rails_footnotes.rb +++ b/config/initializers/rails_footnotes.rb @@ -1,5 +1,5 @@ -if defined?(Footnotes) && Rails.env.development? - Footnotes.run! # first of all +#if defined?(Footnotes) && Rails.env.development? + #Footnotes.run! # first of all # ... other init code -end +#end diff --git a/config/routes.rb b/config/routes.rb index 00106b11..acf92536 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -32,7 +32,7 @@ Gitlab::Application.routes.draw do get "tree/:commit_id/:path" => "projects#tree", :as => :tree_file, :constraints => { - :id => /[a-zA-Z0-9]+/, + :id => /[a-zA-Z0-9_\-]+/, :commit_id => /[a-zA-Z0-9]+/, :path => /.*/ } @@ -40,7 +40,11 @@ Gitlab::Application.routes.draw do end resources :commits resources :team_members - resources :issues + resources :issues do + collection do + post :sort + end + end resources :notes, :only => [:create, :destroy] end root :to => "projects#index" diff --git a/db/migrate/20111015154310_add_position_to_issues.rb b/db/migrate/20111015154310_add_position_to_issues.rb new file mode 100644 index 00000000..41451a0c --- /dev/null +++ b/db/migrate/20111015154310_add_position_to_issues.rb @@ -0,0 +1,5 @@ +class AddPositionToIssues < ActiveRecord::Migration + def change + add_column :issues, :position, :integer, :default => 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index befe0b2a..ed37dbbb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111009111204) do +ActiveRecord::Schema.define(:version => 20111015154310) do create_table "issues", :force => true do |t| t.string "title" @@ -22,6 +22,7 @@ ActiveRecord::Schema.define(:version => 20111009111204) do t.datetime "created_at" t.datetime "updated_at" t.boolean "closed", :default => false, :null => false + t.integer "position", :default => 0 end create_table "keys", :force => true do |t| diff --git a/spec/requests/admin/admin_projects_spec.rb b/spec/requests/admin/admin_projects_spec.rb index 8aa311e8..e36ee441 100644 --- a/spec/requests/admin/admin_projects_spec.rb +++ b/spec/requests/admin/admin_projects_spec.rb @@ -88,7 +88,7 @@ describe "Admin::Projects" do visit new_admin_project_path fill_in 'Name', :with => 'NewProject' fill_in 'Code', :with => 'NPR' - fill_in 'Path', :with => '/tmp/legit_test/legit' + fill_in 'Path', :with => 'legit_1' expect { click_button "Save" }.to change { Project.count }.by(1) @project = Project.last end diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb index 329f0a50..2825a6a9 100644 --- a/spec/requests/projects_spec.rb +++ b/spec/requests/projects_spec.rb @@ -39,7 +39,7 @@ describe "Projects" do visit new_project_path fill_in 'Name', :with => 'NewProject' fill_in 'Code', :with => 'NPR' - fill_in 'Path', :with => '/tmp/legit_test/legit' + fill_in 'Path', :with => 'newproject' expect { click_button "Create Project" }.to change { Project.count }.by(1) @project = Project.last end From 4d37329c732b394dd521a6568be6b7a5b4c3bd68 Mon Sep 17 00:00:00 2001 From: Kevin Lynch Date: Mon, 17 Oct 2011 01:53:30 -0400 Subject: [PATCH 07/18] Must ensure that the lock is always removed. --- lib/gitosis.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/gitosis.rb b/lib/gitosis.rb index a9eef96c..4cc5e6e3 100644 --- a/lib/gitosis.rb +++ b/lib/gitosis.rb @@ -27,13 +27,16 @@ class Gitosis def configure status = Timeout::timeout(20) do File.open(File.join(Dir.tmpdir,"gitlabhq-gitosis.lock"), "w+") do |f| - f.flock(File::LOCK_EX) + begin + f.flock(File::LOCK_EX) - pull - yield(self) - push + pull + yield(self) + push - f.flock(File::LOCK_UN) + ensure + f.flock(File::LOCK_UN) + end end end rescue Exception => ex From a39d0431cb2dec082cd5353f3c212833e49b3490 Mon Sep 17 00:00:00 2001 From: Kevin Lynch Date: Mon, 17 Oct 2011 18:35:25 -0400 Subject: [PATCH 08/18] The project name should not be limited to 16 characters. 16 is too short --- app/models/project.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 3c07976d..2340940b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,7 +28,7 @@ class Project < ActiveRecord::Base :uniqueness => true, :format => { :with => /^[a-zA-Z0-9_\-]*$/, :message => "only letters, digits & '_' '-' allowed" }, - :length => { :within => 3..16 } + :length => { :within => 3..255 } validates :owner, :presence => true From c374eb80ff9fb71d37faffc15714bf98b632d3e5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Slinko Date: Tue, 18 Oct 2011 15:13:57 +0400 Subject: [PATCH 09/18] Increase max key length. Some keys has comment after key string. --- app/models/key.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/key.rb b/app/models/key.rb index 9fa89587..29dcbbce 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -8,7 +8,7 @@ class Key < ActiveRecord::Base validates :key, :presence => true, :uniqueness => true, - :length => { :within => 0..555 } + :length => { :within => 0..1024 } before_save :set_identifier after_save :update_gitosis From 6b030fd41d697e327d2935b406cba70b6a460504 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 21 Oct 2011 20:04:41 +0300 Subject: [PATCH 10/18] 1.1pre1 --- CHANGELOG | 19 ++++ Gemfile | 2 +- Gemfile.lock | 15 ++- VERSION | 2 +- app/assets/images/home.png | Bin 0 -> 271 bytes app/assets/javascripts/application.js | 4 + app/assets/javascripts/snippets.js | 9 ++ app/assets/stylesheets/highlight.css.scss | 6 +- app/assets/stylesheets/projects.css.scss | 95 +++++++++++++++- app/assets/stylesheets/snippets.css.scss | 3 + app/controllers/application_controller.rb | 8 +- app/controllers/issues_controller.rb | 14 ++- app/controllers/notes_controller.rb | 6 +- app/controllers/profile_controller.rb | 6 ++ app/controllers/projects_controller.rb | 30 ++++-- app/controllers/snippets_controller.rb | 62 +++++++++++ app/controllers/team_members_controller.rb | 4 +- app/helpers/application_helper.rb | 21 ---- app/helpers/commits_helper.rb | 9 ++ app/helpers/projects_helper.rb | 12 +++ app/helpers/snippets_helper.rb | 2 + app/models/ability.rb | 23 ++++ app/models/issue.rb | 1 + app/models/note.rb | 4 + app/models/project.rb | 29 +++++ app/models/snippet.rb | 51 +++++++++ app/models/user.rb | 6 +- app/views/admin/users/_form.html.haml | 17 ++- app/views/admin/users/show.html.haml | 11 ++ app/views/commits/_commits.html.haml | 6 +- app/views/commits/_diff.html.haml | 7 +- app/views/commits/show.html.haml | 2 +- app/views/commits/show.js.haml | 4 +- app/views/issues/show.js.haml | 2 + app/views/notes/_form.html.haml | 6 +- app/views/notes/_notes.html.haml | 29 +++-- app/views/notes/_notes_list.html.haml | 4 + app/views/notes/_show.html.haml | 12 +-- app/views/notes/create.js.haml | 5 +- app/views/profile/show.html.haml | 25 +++++ app/views/projects/_form.html.haml | 6 +- app/views/projects/_recent_commits.html.haml | 18 ++++ app/views/projects/_recent_messages.html.haml | 52 +++++++++ app/views/projects/_tile.html.haml | 2 +- app/views/projects/_top_menu.html.haml | 10 +- app/views/projects/_tree_file.html.haml | 11 +- app/views/projects/_tree_item.html.haml | 2 +- app/views/projects/empty.html.erb | 7 +- app/views/projects/show.html.haml | 24 ++++- app/views/projects/wall.html.haml | 28 +++++ app/views/projects/wall.js.haml | 2 + app/views/snippets/_form.html.haml | 22 ++++ app/views/snippets/_snippet.html.haml | 11 ++ app/views/snippets/edit.html.haml | 1 + app/views/snippets/index.html.haml | 14 +++ app/views/snippets/new.html.haml | 1 + app/views/snippets/show.html.haml | 22 ++++ app/views/team_members/_show.html.haml | 6 +- app/views/team_members/show.html.haml | 28 +++++ config/initializers/grit_ext.rb | 8 ++ config/routes.rb | 3 + db/migrate/20111016183422_create_snippets.rb | 12 +++ ...1016193417_add_content_type_to_snippets.rb | 5 + ...0111016195506_add_file_name_to_snippets.rb | 6 ++ .../20111019212429_add_social_to_user.rb | 7 ++ ...021101550_change_social_fields_in_users.rb | 14 +++ db/schema.rb | 15 ++- lib/color.rb | 4 + lib/gitosis.rb | 4 +- lib/utils.rb | 51 ++++++++- spec/factories.rb | 6 ++ spec/models/issue_spec.rb | 1 + spec/models/snippet_spec.rb | 30 ++++++ spec/models/user_spec.rb | 3 + spec/requests/profile_spec.rb | 16 +++ spec/requests/projects_security_spec.rb | 27 +++-- spec/requests/projects_spec.rb | 7 +- spec/requests/snippets_spec.rb | 101 ++++++++++++++++++ spec/requests/team_members_spec.rb | 9 ++ spec/requests/user_security_spec.rb | 8 +- spec/support/login.rb | 3 +- spec/support/matchers.rb | 17 ++- update.rb | 28 ++++- 83 files changed, 1089 insertions(+), 136 deletions(-) create mode 100644 app/assets/images/home.png create mode 100644 app/assets/javascripts/snippets.js create mode 100644 app/assets/stylesheets/snippets.css.scss create mode 100644 app/controllers/snippets_controller.rb create mode 100644 app/helpers/snippets_helper.rb create mode 100644 app/models/snippet.rb create mode 100644 app/views/issues/show.js.haml create mode 100644 app/views/notes/_notes_list.html.haml create mode 100644 app/views/projects/_recent_commits.html.haml create mode 100644 app/views/projects/_recent_messages.html.haml create mode 100644 app/views/projects/wall.js.haml create mode 100644 app/views/snippets/_form.html.haml create mode 100644 app/views/snippets/_snippet.html.haml create mode 100644 app/views/snippets/edit.html.haml create mode 100644 app/views/snippets/index.html.haml create mode 100644 app/views/snippets/new.html.haml create mode 100644 app/views/snippets/show.html.haml create mode 100644 app/views/team_members/show.html.haml create mode 100644 config/initializers/grit_ext.rb create mode 100644 db/migrate/20111016183422_create_snippets.rb create mode 100644 db/migrate/20111016193417_add_content_type_to_snippets.rb create mode 100644 db/migrate/20111016195506_add_file_name_to_snippets.rb create mode 100644 db/migrate/20111019212429_add_social_to_user.rb create mode 100644 db/migrate/20111021101550_change_social_fields_in_users.rb create mode 100644 spec/models/snippet_spec.rb create mode 100644 spec/requests/snippets_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 1201a857..96acfba1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,14 +1,32 @@ +v 1.1.0 + - project dashboard + - wall redesigned + - feature: code snippets + - fixed horizontal scroll on file preview + - fixed app crash if commit message has invalid chars + - bugfix & code cleaning + +v 1.0.2 + - fixed bug with empty project + - added adv validation for project path & code + - feature: issues can be sortable + - bugfix + - username dispalyed on top panel + v 1.0.1 - fixed: with invalid source code for commit - fixed: lose branch/tag selection when use tree navigateion - when history clicked - display path - bug fix & code cleaning + v 1.0.0 - bug fix - projects preview mode + v 0.9.6 - css fix - new repo empty tree until restart server - fixed + v 0.9.4 - security improved - authorization improved @@ -24,6 +42,7 @@ v 0.9.1 - updated app name - issue redesigned - issue can be edit + v 0.8.0 - sytax highlight for main file types - redesign diff --git a/Gemfile b/Gemfile index 523793e7..77a00659 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ gem 'therubyracer' gem 'faker' gem 'seed-fu', :git => 'git://github.com/mbleigh/seed-fu.git' gem "inifile" -gem "albino", :git => "git://github.com/gitlabhq/albino.git" +gem "pygments.rb", "0.2.3" gem "kaminari" gem "thin" gem "git" diff --git a/Gemfile.lock b/Gemfile.lock index 2aa894aa..5ba34459 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,13 +4,6 @@ GIT specs: annotate (2.4.1.beta1) -GIT - remote: git://github.com/gitlabhq/albino.git - revision: 118380924969f3a856659f86ea1f40c1ba7bfcb1 - specs: - albino (1.3.3) - posix-spawn (>= 0.3.6) - GIT remote: git://github.com/gitlabhq/grit.git revision: ff015074ef35bd94cba943f9c0f98e161ab5851c @@ -72,6 +65,7 @@ GEM ZenTest (= 4.5) awesome_print (0.4.0) bcrypt-ruby (3.0.1) + blankslate (2.1.2.4) builder (3.0.0) capybara (1.0.1) mime-types (>= 1.16) @@ -138,6 +132,8 @@ GEM orm_adapter (0.0.5) polyglot (0.3.2) posix-spawn (0.3.6) + pygments.rb (0.2.3) + rubypython (>= 0.5.1) rack (1.3.2) rack-cache (1.0.3) rack (>= 0.4) @@ -189,6 +185,9 @@ GEM ruby-debug-base19 (>= 0.11.19) ruby_core_source (0.1.5) archive-tar-minitar (>= 0.5.2) + rubypython (0.5.1) + blankslate (>= 2.1.2.3) + ffi (~> 1.0.7) rubyzip (0.9.4) sass (3.1.7) sass-rails (3.1.1) @@ -242,7 +241,6 @@ PLATFORMS DEPENDENCIES acts_as_list - albino! annotate! autotest autotest-rails @@ -260,6 +258,7 @@ DEPENDENCIES jquery-rails kaminari launchy + pygments.rb (= 0.2.3) rails (= 3.1.0) rails-footnotes (>= 3.7.5.rc4) rspec-rails diff --git a/VERSION b/VERSION index 7dea76ed..9084fa2f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.1.0 diff --git a/app/assets/images/home.png b/app/assets/images/home.png new file mode 100644 index 0000000000000000000000000000000000000000..316d5d4287a2766fa88ddf83b7c321e179e214b0 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}Y)RhkE)4%c zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmP?mk^hMVS7{2GoVnvr;B4q#=W=K zt+^N!d0YeU=a^&{FZHuN+ps@lO7-rLA`TXx&W?_bKgOGr(vJR?tyJDud@l01P<}fsu)YLqNfyfk9D8Y0<2>wS^vOYfBzo13Hbt)78&q Iol`;+0IP9Y=Kufz literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 01e3b416..024dfe11 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -16,3 +16,7 @@ $(function(){ $('select#branch').selectmenu({style:'popup', width:200}); $('select#tag').selectmenu({style:'popup', width:200}); }); + +function updatePage(){ + $.ajax({type: "GET", url: location.href, dataType: "script"}); +} diff --git a/app/assets/javascripts/snippets.js b/app/assets/javascripts/snippets.js new file mode 100644 index 00000000..11e18eb7 --- /dev/null +++ b/app/assets/javascripts/snippets.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + $("#snippets-table .snippet").live('click', function(e){ + if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") { + location.href = $(this).attr("url"); + e.stopPropagation(); + return false; + } + }); +}); diff --git a/app/assets/stylesheets/highlight.css.scss b/app/assets/stylesheets/highlight.css.scss index 05cb98e7..31f9369a 100644 --- a/app/assets/stylesheets/highlight.css.scss +++ b/app/assets/stylesheets/highlight.css.scss @@ -22,8 +22,8 @@ td.linenos{ .highlight{ background:none; - padding:10px 0px 0px 0; - margin-left:10px; + padding:10px 0px 0px 10px; + margin-left:0px; } .highlight pre{ } @@ -43,7 +43,7 @@ td.linenos { } td.code .highlight { - overflow-x: scroll; + overflow: auto; } table.highlighttable pre{ padding:0; diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss index bc15d8e2..51788672 100644 --- a/app/assets/stylesheets/projects.css.scss +++ b/app/assets/stylesheets/projects.css.scss @@ -310,6 +310,7 @@ input.ssh_project_url { } #projects-list .project, +#snippets-table .snippet, #issues-table .issue{ cursor:pointer; @@ -360,6 +361,8 @@ input.ssh_project_url { .user_new, .edit_user, .new_project, +.new_snippet, +.edit_snippet, .edit_project { input[type='text'], input[type='email'], @@ -488,8 +491,14 @@ tbody tr:nth-child(2n) td, tbody tr.even td { background: white; } p { - margin-bottom: 3px; - font-size: 12px; + margin-bottom: 4px; + font-size: 13px; + color:#111; + } + } + cite { + &.ago { + color:#666; } } } @@ -512,7 +521,7 @@ tbody tr:nth-child(2n) td, tbody tr.even td { } .note_content { float:left; - width:750px; + width:650px; } .issue_notes { @@ -549,3 +558,83 @@ tbody tr:nth-child(2n) td, tbody tr.even td { height: 12px; padding: 10px; } + +.recent_message_parent { + img { + padding-right:10px; + } + + float: left; + margin: 0 20px 20px 0px; + padding: 5px 0px;; + width: 420px; + + &.dash_wall{ + border-bottom: 2px solid orange; + span { + background: orange; + color:black; + } + } + + &.dash_issue{ + border-bottom: 2px solid #ffbbbb; + span { + background: #ffbbbb; + } + } + &.dash_commit{ + border-bottom: 2px solid #bbbbff; + + span{ + background: #bbbbff; + } + } + + &.dash_snippet{ + border-bottom: 2px solid #bbffbb; + + span{ + background: #bbffbb; + } + } + + + span{ + border: 1px solid #aaa; + color:black; + padding:1px 4px; + } + + h4 { + margin-bottom:3px; + } + +} +.commit, +.message, +#notes-list{ + .author { + background: #eaeaea; + color: #333; + border: 1px solid #aaa; + padding:1px 2px; + margin-right:5px; + } +} + +/* Note textare */ +#note_note { + height:100px; + width:97%; + font-size:14px; +} + +.wall_page { + #note_note { + height:25px; + } + .attach_holder { + display:none; + } +} diff --git a/app/assets/stylesheets/snippets.css.scss b/app/assets/stylesheets/snippets.css.scss new file mode 100644 index 00000000..1b680d87 --- /dev/null +++ b/app/assets/stylesheets/snippets.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Snippets controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2866d1a7..047c6cb7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,11 +27,15 @@ class ApplicationController < ActionController::Base end def authenticate_admin! - return redirect_to(new_user_session_path) unless current_user.is_admin? + return render_404 unless current_user.is_admin? end def authorize_project!(action) - return redirect_to(new_user_session_path) unless can?(current_user, action, project) + return render_404 unless can?(current_user, action, project) + end + + def access_denied! + render_404 end def method_missing(method_sym, *arguments, &block) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 6da5dea8..cf8e1ebe 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,12 +1,12 @@ class IssuesController < ApplicationController before_filter :authenticate_user! before_filter :project + before_filter :issue, :only => [:edit, :update, :destroy, :show] # Authorize before_filter :add_project_abilities before_filter :authorize_read_issue! before_filter :authorize_write_issue!, :only => [:new, :create, :close, :edit, :update, :sort] - before_filter :authorize_admin_issue!, :only => [:destroy] respond_to :js @@ -30,12 +30,10 @@ class IssuesController < ApplicationController end def edit - @issue = @project.issues.find(params[:id]) respond_with(@issue) end def show - @issue = @project.issues.find(params[:id]) @notes = @issue.notes @note = @project.notes.new(:noteable => @issue) end @@ -51,7 +49,6 @@ class IssuesController < ApplicationController end def update - @issue = @project.issues.find(params[:id]) @issue.update_attributes(params[:issue]) respond_to do |format| @@ -62,7 +59,8 @@ class IssuesController < ApplicationController def destroy - @issue = @project.issues.find(params[:id]) + return access_denied! unless can?(current_user, :admin_issue, @issue) + @issue.destroy respond_to do |format| @@ -79,4 +77,10 @@ class IssuesController < ApplicationController render :nothing => true end + + protected + + def issue + @issue ||= @project.issues.find(params[:id]) + end end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index d0a40eb1..46425664 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -4,7 +4,6 @@ class NotesController < ApplicationController # Authorize before_filter :add_project_abilities before_filter :authorize_write_note!, :only => [:create] - before_filter :authorize_admin_note!, :only => [:destroy] respond_to :js @@ -25,6 +24,9 @@ class NotesController < ApplicationController def destroy @note = @project.notes.find(params[:id]) + + return access_denied! unless can?(current_user, :admin_note, @note) + @note.destroy respond_to do |format| @@ -41,6 +43,8 @@ class NotesController < ApplicationController Notify.note_commit_email(u, @note).deliver when "Issue" then Notify.note_issue_email(u, @note).deliver + when "Snippet" + true else Notify.note_wall_email(u, @note).deliver end diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb index 666c6309..c8477729 100644 --- a/app/controllers/profile_controller.rb +++ b/app/controllers/profile_controller.rb @@ -3,6 +3,12 @@ class ProfileController < ApplicationController @user = current_user end + def social_update + @user = current_user + @user.update_attributes(params[:user]) + redirect_to [:profile] + end + def password @user = current_user end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index e8f1c392..54d19af7 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -60,14 +60,21 @@ class ProjectsController < ApplicationController end def show - @repo = project.repo - @commit = @repo.commits.first - @tree = @commit.tree - @tree = @tree / params[:path] if params[:path] + return render "projects/empty" unless @project.repo_exists? + @date = case params[:view] + when "week" then Date.today - 7.days + when "day" then Date.today + else nil + end - rescue Grit::NoSuchPathError => ex - respond_to do |format| - format.html {render "projects/empty"} + if @date + @date = @date.at_beginning_of_day + + @commits = @project.commits_since(@date) + @messages = project.notes.since(@date).order("created_at DESC") + else + @commits = @project.fresh_commits + @messages = project.notes.fresh.limit(10) end end @@ -76,8 +83,15 @@ class ProjectsController < ApplicationController # def wall - @notes = @project.common_notes @note = Note.new + @notes = @project.common_notes.order("created_at DESC") + + @notes = case params[:view] + when "week" then @notes.since((Date.today - 7.days).at_beginning_of_day) + when "all" then @notes.all + when "day" then @notes.since(Date.today.at_beginning_of_day) + else @notes.fresh.limit(10) + end end # diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb new file mode 100644 index 00000000..b31fe683 --- /dev/null +++ b/app/controllers/snippets_controller.rb @@ -0,0 +1,62 @@ +class SnippetsController < ApplicationController + before_filter :authenticate_user! + before_filter :project + + # Authorize + before_filter :add_project_abilities + before_filter :authorize_read_snippet! + before_filter :authorize_write_snippet!, :only => [:new, :create, :close, :edit, :update, :sort] + + respond_to :html + + def index + @snippets = @project.snippets + end + + def new + @snippet = @project.snippets.new + end + + def create + @snippet = @project.snippets.new(params[:snippet]) + @snippet.author = current_user + @snippet.save + + if @snippet.valid? + redirect_to [@project, @snippet] + else + respond_with(@snippet) + end + end + + def edit + @snippet = @project.snippets.find(params[:id]) + end + + def update + @snippet = @project.snippets.find(params[:id]) + @snippet.update_attributes(params[:snippet]) + + if @snippet.valid? + redirect_to [@project, @snippet] + else + respond_with(@snippet) + end + end + + def show + @snippet = @project.snippets.find(params[:id]) + @notes = @snippet.notes + @note = @project.notes.new(:noteable => @snippet) + end + + def destroy + @snippet = @project.snippets.find(params[:id]) + + return access_denied! unless can?(current_user, :admin_snippet, @snippet) + + @snippet.destroy + + redirect_to project_snippets_path(@project) + end +end diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb index e00cc36c..5fb2710d 100644 --- a/app/controllers/team_members_controller.rb +++ b/app/controllers/team_members_controller.rb @@ -3,8 +3,8 @@ class TeamMembersController < ApplicationController # Authorize before_filter :add_project_abilities - before_filter :authorize_read_team_member! - before_filter :authorize_admin_team_member!, :only => [:new, :create, :destroy, :update] + before_filter :authorize_read_project! + before_filter :authorize_admin_project!, :only => [:new, :create, :destroy, :update] def show @team_member = project.users_projects.find(params[:id]) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 89a906f0..0895eb0d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -53,25 +53,4 @@ module ApplicationHelper [projects, default_nav, project_nav].flatten.to_json end - def handle_file_type(file_name, mime_type) - if file_name =~ /(\.rb|\.ru|\.rake|Rakefile|\.gemspec|\.rbx|Gemfile)$/ - :ruby - elsif file_name =~ /\.py$/ - :python - elsif file_name =~ /(\.pl|\.scala|\.c|\.cpp|\.java|\.haml|\.html|\.sass|\.scss|\.xml|\.php|\.erb)$/ - $1[1..-1].to_sym - elsif file_name =~ /\.js$/ - :javascript - elsif file_name =~ /\.sh$/ - :bash - elsif file_name =~ /\.coffee$/ - :coffeescript - elsif file_name =~ /\.yml$/ - :yaml - elsif file_name =~ /\.md$/ - :minid - else - :text - end - end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index f1b54668..b79e5718 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -21,4 +21,13 @@ module CommitsHelper link_to "More", project_commits_path(@project, :offset => offset.to_i + limit.to_i, :limit => limit), :remote => true, :class => "lite_button vm", :style => "text-align:center; width:930px; ", :id => "more-commits-link" end + + # Cause some errors with trucate & encoding use this method + def truncate_commit_message(commit, size = 60) + message = commit.message + message.length > size ? (message[0..(size - 1)] + "...") : message + # if special characters occurs + rescue + commit.message + end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index d570dff4..4a6923af 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -3,4 +3,16 @@ module ProjectsHelper cookies["project_view"] ||= "tile" cookies["project_view"] == type ? nil : "display:none" end + + def load_note_parent(id, type, project) + case type + when "Issue" then @project.issues.find(id) + when "Commit" then @project.repo.commits(id).first + when "Snippet" then @project.snippets.find(id) + else + true + end + rescue + nil + end end diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb new file mode 100644 index 00000000..236b6c8c --- /dev/null +++ b/app/helpers/snippets_helper.rb @@ -0,0 +1,2 @@ +module SnippetsHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb index 0a2c45f1..b822f630 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -2,6 +2,9 @@ class Ability def self.allowed(object, subject) case subject.class.name when "Project" then project_abilities(object, subject) + when "Issue" then issue_abilities(object, subject) + when "Note" then note_abilities(object, subject) + when "Snippet" then snippet_abilities(object, subject) else [] end end @@ -12,6 +15,7 @@ class Ability rules << [ :read_project, :read_issue, + :read_snippet, :read_team_member, :read_note ] if project.readers.include?(user) @@ -19,16 +23,35 @@ class Ability rules << [ :write_project, :write_issue, + :write_snippet, :write_note ] if project.writers.include?(user) rules << [ :admin_project, :admin_issue, + :admin_snippet, :admin_team_member, :admin_note ] if project.admins.include?(user) rules.flatten end + + class << self + [:issue, :note, :snippet].each do |name| + define_method "#{name}_abilities" do |user, subject| + if subject.author == user + [ + :"read_#{name}", + :"write_#{name}", + :"admin_#{name}" + ] + else + subject.respond_to?(:project) ? + project_abilities(user, subject.project) : [] + end + end + end + end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 9b1b923e..556cdc1c 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -37,5 +37,6 @@ end # created_at :datetime # updated_at :datetime # closed :boolean default(FALSE), not null +# position :integer default(0) # diff --git a/app/models/note.rb b/app/models/note.rb index f89fb9f8..e3dabce4 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -22,6 +22,10 @@ class Note < ActiveRecord::Base scope :common, where(:noteable_id => nil) + scope :last_week, where("created_at >= :date", :date => (Date.today - 7.days)) + scope :since, lambda { |day| where("created_at >= :date", :date => (day)) } + scope :fresh, order("created_at DESC") + mount_uploader :attachment, AttachmentUploader end # == Schema Information diff --git a/app/models/project.rb b/app/models/project.rb index 2340940b..d70b18e7 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -7,6 +7,7 @@ class Project < ActiveRecord::Base has_many :users_projects, :dependent => :destroy has_many :users, :through => :users_projects has_many :notes, :dependent => :destroy + has_many :snippets, :dependent => :destroy validates :name, :uniqueness => true, @@ -125,6 +126,34 @@ class Project < ActiveRecord::Base end end + def heads + @heads ||= repo.heads + end + + def fresh_commits + commits = heads.map do |h| + repo.commits(h.name, 10) + end.flatten.uniq { |c| c.id } + + commits.sort! do |x, y| + y.committed_date <=> x.committed_date + end + + commits[0..10] + end + + def commits_since(date) + commits = heads.map do |h| + repo.log(h.name, nil, :since => date) + end.flatten.uniq { |c| c.id } + + commits.sort! do |x, y| + y.committed_date <=> x.committed_date + end + + commits + end + def tree(fcommit, path = nil) fcommit = commit if fcommit == :head tree = fcommit.tree diff --git a/app/models/snippet.rb b/app/models/snippet.rb new file mode 100644 index 00000000..95d6a07d --- /dev/null +++ b/app/models/snippet.rb @@ -0,0 +1,51 @@ +class Snippet < ActiveRecord::Base + include Utils::Colorize + + belongs_to :project + belongs_to :author, :class_name => "User" + has_many :notes, :as => :noteable + + attr_protected :author, :author_id, :project, :project_id + + validates_presence_of :project_id + validates_presence_of :author_id + + validates :title, + :presence => true, + :length => { :within => 0..255 } + + validates :file_name, + :presence => true, + :length => { :within => 0..255 } + + validates :content, + :presence => true, + :length => { :within => 0..10000 } + + + def self.content_types + [ + ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java", + ".haml", ".html", ".sass", ".scss", ".xml", ".php", ".erb", + ".js", ".sh", ".coffee", ".yml", ".md" + ] + end + + def colorize + system_colorize(content, file_name) + end +end +# == Schema Information +# +# Table name: snippets +# +# id :integer not null, primary key +# title :string(255) +# content :text +# author_id :integer not null +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# file_name :string(255) +# + diff --git a/app/models/user.rb b/app/models/user.rb index 0972f006..7736599e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,7 +5,8 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable # Setup accessible (or protected) attributes for your model - attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :projects_limit + attr_accessible :email, :password, :password_confirmation, :remember_me, + :name, :projects_limit, :skype, :linkedin, :twitter has_many :users_projects, :dependent => :destroy has_many :projects, :through => :users_projects @@ -58,5 +59,8 @@ end # name :string(255) # admin :boolean default(FALSE), not null # projects_limit :integer +# skype :string +# linkedin :string +# twitter :string # diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 17be416f..aa9df298 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -25,13 +25,26 @@ = f.label :password_confirmation %br = f.password_field :password_confirmation - .span-11 - .field.prepend-top.append-bottom + .field.prepend-top = f.check_box :admin = f.label :admin + .span-11 .field.prepend-top = f.text_field :projects_limit, :class => "small_input" = f.label :projects_limit + + .field + = f.label :skype + %br + = f.text_field :skype + .field + = f.label :linkedin + %br + = f.text_field :linkedin + .field + = f.label :twitter + %br + = f.text_field :twitter .clear %br .actions diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index b1d110be..aee73c38 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -14,6 +14,17 @@ %b Projects limit: = @admin_user.projects_limit + %p + %b Skype: + = @admin_user.skype + %p + %b LinkedIn: + = @admin_user.linkedin + %p + %b Twitter: + = @admin_user.twitter + + .clear = link_to 'Edit', edit_admin_user_path(@admin_user) \| diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml index 4eebb83a..94a1bd1b 100644 --- a/app/views/commits/_commits.html.haml +++ b/app/views/commits/_commits.html.haml @@ -11,12 +11,12 @@ = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" %p %strong - = commit.message.length > 60 ? (commit.message[0..59] + "...") : commit.message + = truncate_commit_message(commit) = link_to "Browse Code", tree_project_path(@project, :commit_id => commit.id), :class => "lite_button", :style => "float:right" = link_to truncate(commit.id.to_s, :length => 16), project_commit_path(@project, :id => commit.id), :class => "lite_button", :style => "width:120px;float:right" %span - %span - [ #{commit.author} ] + %span.author + = commit.author = time_ago_in_words(commit.committed_date) ago = more_commits_link if @commits.size > 99 diff --git a/app/views/commits/_diff.html.haml b/app/views/commits/_diff.html.haml index dff99bf1..73652aaf 100644 --- a/app/views/commits/_diff.html.haml +++ b/app/views/commits/_diff.html.haml @@ -1,4 +1,3 @@ -- require "utils" .file_stats - @commit.diffs.each do |diff| - if diff.deleted_file @@ -35,7 +34,7 @@ %strong{:id => "#{diff.b_path}"}= diff.b_path %br/ .diff_file_content - - if file.mime_type =~ /application|text/ && !Utils.binary?(file.data) + - if file.text? - lines_arr = diff.diff.lines.to_a - line_old = lines_arr[2].match(/-(\d)/)[0].to_i.abs rescue 0 - line_new = lines_arr[2].match(/\+(\d)/)[0].to_i.abs rescue 0 @@ -50,9 +49,9 @@ - else - line_new += 1 - line_old += 1 - - elsif file.mime_type =~ /image/ + - elsif file.image? .diff_file_content_image - %img{:src => "data:image/jpeg;base64,#{Base64.encode64(file.data)}"} + %img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - else %p %center No preview for this file type diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml index 147aaafb..a2c9149d 100644 --- a/app/views/commits/show.html.haml +++ b/app/views/commits/show.html.haml @@ -1,5 +1,5 @@ %h3 - = "[ #{@commit.committer} ] #{truncate @commit.message, :length => 80}" + = "[ #{@commit.committer} ] #{truncate_commit_message(@commit, 80)}" -#= link_to 'Back', project_commits_path(@project), :class => "button" %table.round-borders %tr diff --git a/app/views/commits/show.js.haml b/app/views/commits/show.js.haml index 2c46689b..cec1fe28 100644 --- a/app/views/commits/show.js.haml +++ b/app/views/commits/show.js.haml @@ -1,6 +1,8 @@ -:plain +-#:plain $("#side-commit-preview").remove(); var side = $("
    "); side.html("#{escape_javascript(render "commits/show")}"); $("##{dom_id(@project)}").parent().append(side); $("##{dom_id(@project)}").addClass("span-14"); +:plain + $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}"); diff --git a/app/views/issues/show.js.haml b/app/views/issues/show.js.haml new file mode 100644 index 00000000..5b9a34c0 --- /dev/null +++ b/app/views/issues/show.js.haml @@ -0,0 +1,2 @@ +:plain + $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}"); diff --git a/app/views/notes/_form.html.haml b/app/views/notes/_form.html.haml index ccb159f1..ca56a245 100644 --- a/app/views/notes/_form.html.haml +++ b/app/views/notes/_form.html.haml @@ -12,9 +12,9 @@ = f.label :note %cite (255 symbols only) %br - = f.text_area :note, :style => "width:97%;height:100px", :size => 255 + = f.text_area :note, :size => 255 - %div + %div.attach_holder = f.label :attachment %cite (less than 10 MB) %br @@ -25,4 +25,4 @@ .clear %br - = f.submit 'Add note', :class => "lbutton vm" + = f.submit 'Add note', :class => "lbutton vm", :id => "submit_note" diff --git a/app/views/notes/_notes.html.haml b/app/views/notes/_notes.html.haml index 9d1d4b94..2d110162 100644 --- a/app/views/notes/_notes.html.haml +++ b/app/views/notes/_notes.html.haml @@ -1,15 +1,28 @@ -%ul#notes-list - - @notes.each do |note| - - next unless note.author - = render :partial => "notes/show", :locals => {:note => note} +- if controller.action_name == "wall" + %ul#notes-list= render "notes/notes_list" -%br -%br -- if can? current_user, :write_note, @project - = render "notes/form" +- else + %ul#notes-list= render "notes/notes_list" + %br + %br + - if can? current_user, :write_note, @project + = render "notes/form" :javascript $('.delete-note').live('ajax:success', function() { $(this).closest('li').fadeOut(); }); + $("#new_note").live("ajax:before", function(){ + $("#submit_note").attr("disabled", "disabled"); + }) + $("#new_note").live("ajax:complete", function(){ + $("#submit_note").removeAttr("disabled"); + }) + + +- if ["issues", "projects"].include?(controller.controller_name) + :javascript + $(function(){ + var int =self.setInterval("updatePage()", 20000); + }); diff --git a/app/views/notes/_notes_list.html.haml b/app/views/notes/_notes_list.html.haml new file mode 100644 index 00000000..1e4a6bb2 --- /dev/null +++ b/app/views/notes/_notes_list.html.haml @@ -0,0 +1,4 @@ +- @notes.each do |note| + - next unless note.author + = render :partial => "notes/show", :locals => {:note => note} + diff --git a/app/views/notes/_show.html.haml b/app/views/notes/_show.html.haml index 2b0a6d2e..ee9f9ffa 100644 --- a/app/views/notes/_show.html.haml +++ b/app/views/notes/_show.html.haml @@ -1,19 +1,17 @@ %li{:id => dom_id(note)} %div.note_author = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;" - %div.note_content + %div.note_content.left = simple_format(html_escape(note.note)) - if note.attachment.url Attachment: - = link_to note.attachment_identifier, note.attachment.url + = link_to note.attachment_identifier, note.attachment.url, :target => "_blank" %br - %span - %span - [ #{note.author.name} ] -   + %span.author= note.author.name + %cite.ago = time_ago_in_words(note.updated_at) ago - %br + %br - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) = link_to 'Remove', [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-note right negative" .clear diff --git a/app/views/notes/create.js.haml b/app/views/notes/create.js.haml index 47cff1d8..15371dbc 100644 --- a/app/views/notes/create.js.haml +++ b/app/views/notes/create.js.haml @@ -1,8 +1,11 @@ - if @note.valid? :plain $("#new_note .errors").remove(); - $("#notes-list").append("#{escape_javascript(render(:partial => 'show', :locals => {:note => @note} ))}"); + updatePage(); $('#note_note').val(""); - else :plain $("#new_note").replaceWith("#{escape_javascript(render('form'))}"); + +:plain + $("#submit_note").removeAttr("disabled"); diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml index 12737ba8..ef23a169 100644 --- a/app/views/profile/show.html.haml +++ b/app/views/profile/show.html.haml @@ -6,3 +6,28 @@ %p %b Email: = @user.email + +%br + += form_for @user, :url => profile_edit_path, :method => :put do |f| + -if @user.errors.any? + #error_explanation + %ul + - @user.errors.full_messages.each do |msg| + %li= msg + + .div + = f.label :skype + %br + = f.text_field :skype + .div + = f.label :linkedin + %br + = f.text_field :linkedin + .div + = f.label :twitter + %br + = f.text_field :twitter + .actions + = f.submit 'Save', :class => "lbutton vm" + diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index baa1f14f..00ca98ef 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -1,8 +1,6 @@ = form_for(@project, :remote => true) do |f| %div.form_content - - if @project.new_record? - %h1 New Project - - else + - unless @project.new_record? %h1 Edit Project - if @project.errors.any? #error_explanation @@ -26,7 +24,7 @@ %td .left= f.label :code %cite.right http://yourserver/ - %td= f.text_field :code, :placeholder => "example (3..12 symbols only)" + %td= f.text_field :code, :placeholder => "example" .field = f.label :description %br/ diff --git a/app/views/projects/_recent_commits.html.haml b/app/views/projects/_recent_commits.html.haml new file mode 100644 index 00000000..e435ea30 --- /dev/null +++ b/app/views/projects/_recent_commits.html.haml @@ -0,0 +1,18 @@ +- @commits.each do |commit| + %div.commit + - if commit.author.email + = image_tag gravatar_icon(commit.author.email), :class => "left", :width => 40, :style => "padding-right:5px;" + - else + = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" + %p{:style => "margin-bottom: 3px;"} + %strong + = link_to truncate_commit_message(commit, 60), project_commit_path(@project, :id => commit.id) + + %span + %span.author + = commit.author.name.force_encoding("UTF-8") + %cite + = time_ago_in_words(commit.committed_date) + ago + %br + diff --git a/app/views/projects/_recent_messages.html.haml b/app/views/projects/_recent_messages.html.haml new file mode 100644 index 00000000..1af7fe3b --- /dev/null +++ b/app/views/projects/_recent_messages.html.haml @@ -0,0 +1,52 @@ +- @messages.group_by{ |x| [x.noteable_id, x.noteable_type]}.each do |item, notes| + - id, type = item[0], item[1] + - parent = load_note_parent(id, type, @project) + - next unless parent + + - case type + - when "Issue" + - css_class = "dash_issue" + - issue = parent + - item_code = issue.author.email + - link_item_name = truncate(issue.title, :length => 50) + - link_to_item = project_issue_path(@project, issue) + - when "Snippet" + - css_class = "dash_snippet" + - item_code = parent.author.email + - link_item_name = parent.title + - link_to_item = project_snippet_path(@project, parent) + - when "Commit" + - css_class = "dash_commit" + - commit = parent + - item_code = commit.author.email + - link_item_name = truncate_commit_message(commit, 50) + - link_to_item = project_commit_path(@project, :id => commit.id) + - else + - css_class = "dash_wall" + - item_code = @project.name + - link_item_name = "Project Wall" + - link_to_item = wall_project_path(@project) + + %div{ :class => "recent_message_parent #{css_class}"} + = image_tag gravatar_icon(item_code), :class => "left", :width => 40 + %h4 + = link_to(link_item_name, link_to_item) + %span + = type + .clear + - notes.sort {|x,y| x.updated_at <=> y.updated_at }.each do |note| + %div.message + = image_tag gravatar_icon(note.author.email), :class => "left", :width => 24, :style => "padding-right:5px;" + %p{:style => "margin-bottom: 3px;"} + %span.author + = note.author.name + = link_to truncate(note.note, :length => 200), link_to_item + "#note_#{note.id}" + - if note.attachment.url + %br + Attachment: + = link_to note.attachment_identifier, note.attachment.url + %br + %br + .append-bottom +   + .clear diff --git a/app/views/projects/_tile.html.haml b/app/views/projects/_tile.html.haml index 037aeccb..b2466d93 100644 --- a/app/views/projects/_tile.html.haml +++ b/app/views/projects/_tile.html.haml @@ -4,7 +4,7 @@ %div{ :class => "project", :url => project_path(project) } %h2 = image_tag gravatar_icon(project.name), :class => "left", :width => 40, :style => "padding-right:5px;" - = "/" + project.code + = link_to ("/" + project.code), project_path(project), :style => "text-decoration:none" %p= project.name %p= project.url_to_repo -#%p diff --git a/app/views/projects/_top_menu.html.haml b/app/views/projects/_top_menu.html.haml index b81ba6bb..59f2533e 100644 --- a/app/views/projects/_top_menu.html.haml +++ b/app/views/projects/_top_menu.html.haml @@ -1,10 +1,11 @@ %div.top_project_menu -#%span= link_to @project.code.capitalize, @project, :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil - if @project.repo_exists? - %span= link_to "Tree", tree_project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) || current_page?(:controller => "projects", :action => "tree", :id => @project) ? "current" : nil + %span= link_to image_tag("home.png", :width => 20), project_path(@project), :class => current_page?(:controller => "projects", :action => "show", :id => @project) ? "current" : nil + %span= link_to "Tree", tree_project_path(@project), :class => current_page?(:controller => "projects", :action => "tree", :id => @project) ? "current" : nil %span= link_to "Commits", project_commits_path(@project), :class => current_page?(:controller => "commits", :action => "index", :project_id => @project) ? "current" : nil %span - = link_to team_project_path(@project), :class => current_page?(:controller => "projects", :action => "team", :id => @project) ? "current" : nil do + = link_to team_project_path(@project), :class => (current_page?(:controller => "projects", :action => "team", :id => @project) || controller.controller_name == "team_members") ? "current" : nil do Team - if @project.users_projects.count > 0 %span{ :class => "top_menu_count" }= @project.users_projects.count @@ -18,6 +19,11 @@ Wall - if @project.common_notes.count > 0 %span{ :class => "top_menu_count" }= @project.common_notes.count + %span + = link_to project_snippets_path(@project), :class => (controller.controller_name == "snippets") ? "current" : nil do + Snippets + - if @project.snippets.count > 0 + %span{ :class => "top_menu_count" }= @project.snippets.count - if @commit %span= link_to truncate(commit_name(@project,@commit), :length => 15), project_commit_path(@project, :id => @commit.id), :class => current_page?(:controller => "commits", :action => "show", :project_id => @project, :id => @commit.id) ? "current" : nil diff --git a/app/views/projects/_tree_file.html.haml b/app/views/projects/_tree_file.html.haml index 3463bfc5..41a2287a 100644 --- a/app/views/projects/_tree_file.html.haml +++ b/app/views/projects/_tree_file.html.haml @@ -1,4 +1,4 @@ -- require "utils" +:css .view_file .view_file_header %strong @@ -6,14 +6,13 @@ = link_to "raw", blob_project_path(@project, :commit_id => @commit.id, :path => params[:path] ), :class => "right", :target => "_blank" = link_to "history", project_commits_path(@project, :path => params[:path]), :class => "right", :style => "margin-right:10px;" %br/ - - if file.mime_type =~ /application|text/ && !Utils.binary?(file.data) + - if file.text? .view_file_content - - ft = handle_file_type(file.name, file.mime_type) :erb - <%= raw Albino.colorize(content, ft, :html, 'utf-8', "linenos=True") %> - - elsif file.mime_type =~ /image/ + <%= raw file.colorize %> + - elsif file.image? .view_file_content_image - %img{ :src => "data:image/jpeg;base64,#{Base64.encode64(file.data)}"} + %img{ :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - else %p %center No preview for this file type diff --git a/app/views/projects/_tree_item.html.haml b/app/views/projects/_tree_item.html.haml index 9ba33c1e..4ebcfbef 100644 --- a/app/views/projects/_tree_item.html.haml +++ b/app/views/projects/_tree_item.html.haml @@ -12,4 +12,4 @@ = time_ago_in_words(content_commit.committed_date) ago %td - = link_to truncate(content_commit.message, :length => 40), project_commit_path(@project, content_commit) + = link_to truncate_commit_message(content_commit, 40), project_commit_path(@project, content_commit) diff --git a/app/views/projects/empty.html.erb b/app/views/projects/empty.html.erb index a8917471..4c60facd 100644 --- a/app/views/projects/empty.html.erb +++ b/app/views/projects/empty.html.erb @@ -1,3 +1,4 @@ +<% bash_lexer = Pygments::Lexer[:bash] %>

    Git global setup:

    @@ -6,7 +7,7 @@ git config --global user.name "#{current_user.name}" git config --global user.email "#{current_user.email}" eos %> - <%= raw Albino.colorize(setup_str, :bash) %> + <%= raw bash_lexer.highlight(setup_str) %>

    Next steps:

    @@ -21,7 +22,7 @@ git remote add origin #{@project.url_to_repo} git push -u origin master eos %> - <%= raw Albino.colorize(repo_setup_str, :bash) %> + <%= raw bash_lexer.highlight(repo_setup_str) %>

    Existing Git Repo?

    @@ -31,7 +32,7 @@ git remote add origin #{@project.url_to_repo} git push -u origin master eos %> - <%= raw Albino.colorize(exist_repo_setup_str, :bash) %> + <%= raw bash_lexer.highlight(exist_repo_setup_str) %>

    Remove this project?

    diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 0fd9c8ea..85019ecb 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,3 +1,23 @@ %div - %div#tree-holder - = render :partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @commit.tree} + %h2.left History + .right + = form_tag project_path(@project), :method => :get do + .span-2 + = radio_button_tag :view, "recent", (params[:view] || "recent") == "recent", :onclick => "this.form.submit()", :id => "recent_view" + = label_tag "recent_view","Recent" + .span-2 + = radio_button_tag :view, "day", params[:view] == "day", :onclick => "this.form.submit()", :id => "day_view" + = label_tag "day_view","Today" + .span-2 + = radio_button_tag :view, "week", params[:view] == "week", :onclick => "this.form.submit()", :id => "week_view" + = label_tag "week_view","Week" + .clear + %hr +.span-11 + %h3 Commits + =render "projects/recent_commits" + +.span-11.right + %h3 Talk + =render "projects/recent_messages" + diff --git a/app/views/projects/wall.html.haml b/app/views/projects/wall.html.haml index 479bb3cf..ed22478c 100644 --- a/app/views/projects/wall.html.haml +++ b/app/views/projects/wall.html.haml @@ -1 +1,29 @@ +%div.wall_page + - if can? current_user, :write_note, @project + = render "notes/form" + .right + = form_tag wall_project_path(@project), :method => :get do + .span-2 + = radio_button_tag :view, "recent", (params[:view] || "recent") == "recent", :onclick => "this.form.submit()", :id => "recent_view" + = label_tag "recent_view","Recent" + .span-2 + = radio_button_tag :view, "day", params[:view] == "day", :onclick => "this.form.submit()", :id => "day_view" + = label_tag "day_view","Today" + .span-2 + = radio_button_tag :view, "week", params[:view] == "week", :onclick => "this.form.submit()", :id => "week_view" + = label_tag "week_view","Week" + .span-2 + = radio_button_tag :view, "all", params[:view] == "all", :onclick => "this.form.submit()", :id => "all_view" + = label_tag "all_view","All" + .clear + %br + %hr = render "notes/notes" + +:javascript + $(function(){ + $("#note_note").live("click", function(){ + $(this).css("height", "100px"); + $('.attach_holder').show(); + }); + }); diff --git a/app/views/projects/wall.js.haml b/app/views/projects/wall.js.haml new file mode 100644 index 00000000..5b9a34c0 --- /dev/null +++ b/app/views/projects/wall.js.haml @@ -0,0 +1,2 @@ +:plain + $("#notes-list").html("#{escape_javascript(render(:partial => 'notes/notes_list'))}"); diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml new file mode 100644 index 00000000..571e2b06 --- /dev/null +++ b/app/views/snippets/_form.html.haml @@ -0,0 +1,22 @@ +%div + = form_for [@project, @snippet] do |f| + -if @snippet.errors.any? + %ul + - @snippet.errors.full_messages.each do |msg| + %li= msg + + %table.round-borders + %tr + %td= f.label :title + %td= f.text_field :title, :placeholder => "Example Snippet" + %tr + %td= f.label :file_name + %td= f.text_field :file_name, :placeholder => "example.rb" + %tr + %td{:colspan => 2} + = f.label :content, "Code" + %br + = f.text_area :content, :style => "height:240px;width:932px;" + + .actions.prepend-top + = f.submit 'Save', :class => "lbutton vm" diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml new file mode 100644 index 00000000..483ff42c --- /dev/null +++ b/app/views/snippets/_snippet.html.haml @@ -0,0 +1,11 @@ +%tr{ :id => dom_id(snippet), :class => "snippet", :url => project_snippet_path(@project, snippet) } + %td + = image_tag gravatar_icon(snippet.author.email), :class => "left", :width => 40, :style => "padding:0 5px;" + = truncate snippet.author.name, :lenght => 20 + %td= html_escape snippet.title + %td= html_escape snippet.file_name + %td + - if can?(current_user, :admin_snippet, @project) || snippet.author == current_user + = link_to 'Edit', edit_project_snippet_path(@project, snippet), :class => "lbutton positive" + - if can?(current_user, :admin_snippet, @project) || snippet.author == current_user + = link_to 'Destroy', [@project, snippet], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "lbutton delete-snippet negative", :id => "destroy_snippet_#{snippet.id}" diff --git a/app/views/snippets/edit.html.haml b/app/views/snippets/edit.html.haml new file mode 100644 index 00000000..f81c0b8b --- /dev/null +++ b/app/views/snippets/edit.html.haml @@ -0,0 +1 @@ += render "snippets/form" diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml new file mode 100644 index 00000000..6e5dbde5 --- /dev/null +++ b/app/views/snippets/index.html.haml @@ -0,0 +1,14 @@ +%div + - if can? current_user, :write_snippet, @project + .left= link_to 'New Snippet', new_project_snippet_path(@project), :class => "lbutton vm" + + %table.round-borders#snippets-table + %tr + %th Author + %th Title + %th File name + %th + = render @snippets +:javascript + $('.delete-snippet').live('ajax:success', function() { + $(this).closest('tr').fadeOut(); }); diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml new file mode 100644 index 00000000..f81c0b8b --- /dev/null +++ b/app/views/snippets/new.html.haml @@ -0,0 +1 @@ += render "snippets/form" diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml new file mode 100644 index 00000000..899950b7 --- /dev/null +++ b/app/views/snippets/show.html.haml @@ -0,0 +1,22 @@ +%h2 + = "Snippet ##{@snippet.id} - #{@snippet.title}" + +.view_file + .view_file_header + %strong + = @snippet.file_name + %br/ + .view_file_content + :erb + <%= raw @snippet.colorize %> + +- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user + = link_to 'Edit', edit_project_snippet_path(@project, @snippet), :class => "lbutton positive" +- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user + = link_to 'Destroy', [@project, @snippet], :confirm => 'Are you sure?', :method => :delete, :class => "lbutton delete-snippet negative", :id => "destroy_snippet_#{@snippet.id}" +.clear +%br +.snippet_notes= render "notes/notes" + +.clear + diff --git a/app/views/team_members/_show.html.haml b/app/views/team_members/_show.html.haml index 6d310768..b9a68e6c 100644 --- a/app/views/team_members/_show.html.haml +++ b/app/views/team_members/_show.html.haml @@ -1,8 +1,10 @@ - user = member.user %tr{:id => dom_id(member)} %td - = image_tag gravatar_icon(user.email), :class => "left", :width => 40, :style => "padding:0 5px;" - = truncate user.name, :lenght => 16 + = link_to image_tag(gravatar_icon(user.email), :class => "left", :width => 40, :style => "padding:0 5px;"), project_team_member_path(@project, member) + + = link_to truncate(user.name, :lenght => 16), project_team_member_path(@project, member) + %td= truncate user.email, :lenght => 16 - if can? current_user, :admin_project, @project = form_for(member, :as => :team_member, :url => project_team_member_path(@project, member)) do |f| diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml new file mode 100644 index 00000000..d07c54f8 --- /dev/null +++ b/app/views/team_members/show.html.haml @@ -0,0 +1,28 @@ +- user = @team_member.user +.span-2 + = image_tag gravatar_icon(user.email), :class => "left", :width => 60, :style => "padding-right:5px;" +%p + %b Name: + = user.name +%p + %b Email: + = user.email + +%br + +- unless user.skype.empty? + .div + %b Skype: + = user.skype + +- unless user.linkedin.empty? + .div + %b LinkedIn: + = user.linkedin + +- unless user.twitter.empty? + .div + %b Twitter: + = user.twitter + + diff --git a/config/initializers/grit_ext.rb b/config/initializers/grit_ext.rb new file mode 100644 index 00000000..4bd71003 --- /dev/null +++ b/config/initializers/grit_ext.rb @@ -0,0 +1,8 @@ +require 'grit' +require 'pygments' +require "utils" + +Grit::Blob.class_eval do + include Utils::FileHelper + include Utils::Colorize +end diff --git a/config/routes.rb b/config/routes.rb index acf92536..8a40a8fe 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,7 @@ Gitlab::Application.routes.draw do get "errors/gitosis" get "profile/password", :to => "profile#password" put "profile/password", :to => "profile#password_update" + put "profile/edit", :to => "profile#social_update" get "profile", :to => "profile#show" #get "profile/:id", :to => "profile#show" @@ -38,6 +39,8 @@ Gitlab::Application.routes.draw do } end + + resources :snippets resources :commits resources :team_members resources :issues do diff --git a/db/migrate/20111016183422_create_snippets.rb b/db/migrate/20111016183422_create_snippets.rb new file mode 100644 index 00000000..9b0bf201 --- /dev/null +++ b/db/migrate/20111016183422_create_snippets.rb @@ -0,0 +1,12 @@ +class CreateSnippets < ActiveRecord::Migration + def change + create_table :snippets do |t| + t.string :title + t.text :content + t.integer :author_id, :null => false + t.integer :project_id, :null => false + + t.timestamps + end + end +end diff --git a/db/migrate/20111016193417_add_content_type_to_snippets.rb b/db/migrate/20111016193417_add_content_type_to_snippets.rb new file mode 100644 index 00000000..511a6793 --- /dev/null +++ b/db/migrate/20111016193417_add_content_type_to_snippets.rb @@ -0,0 +1,5 @@ +class AddContentTypeToSnippets < ActiveRecord::Migration + def change + add_column :snippets, :content_type, :string, :null => false, :default => "txt" + end +end diff --git a/db/migrate/20111016195506_add_file_name_to_snippets.rb b/db/migrate/20111016195506_add_file_name_to_snippets.rb new file mode 100644 index 00000000..d378d225 --- /dev/null +++ b/db/migrate/20111016195506_add_file_name_to_snippets.rb @@ -0,0 +1,6 @@ +class AddFileNameToSnippets < ActiveRecord::Migration + def change + add_column :snippets, :file_name, :string + remove_column :snippets, :content_type + end +end diff --git a/db/migrate/20111019212429_add_social_to_user.rb b/db/migrate/20111019212429_add_social_to_user.rb new file mode 100644 index 00000000..b0ffe536 --- /dev/null +++ b/db/migrate/20111019212429_add_social_to_user.rb @@ -0,0 +1,7 @@ +class AddSocialToUser < ActiveRecord::Migration + def change + add_column :users, :skype, :string + add_column :users, :linkedin, :string + add_column :users, :twitter, :string + end +end diff --git a/db/migrate/20111021101550_change_social_fields_in_users.rb b/db/migrate/20111021101550_change_social_fields_in_users.rb new file mode 100644 index 00000000..6e506c1c --- /dev/null +++ b/db/migrate/20111021101550_change_social_fields_in_users.rb @@ -0,0 +1,14 @@ +class ChangeSocialFieldsInUsers < ActiveRecord::Migration + def up + remove_column :users, :skype + remove_column :users, :linkedin + remove_column :users, :twitter + + add_column :users, :skype, :string, {:null => false, :default => ''} + add_column :users, :linkedin, :string, {:null => false, :default => ''} + add_column :users, :twitter, :string, {:null => false, :default => ''} + end + + def down + end +end diff --git a/db/schema.rb b/db/schema.rb index ed37dbbb..cc805990 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111015154310) do +ActiveRecord::Schema.define(:version => 20111021101550) do create_table "issues", :force => true do |t| t.string "title" @@ -56,6 +56,16 @@ ActiveRecord::Schema.define(:version => 20111015154310) do t.integer "owner_id" end + create_table "snippets", :force => true do |t| + t.string "title" + t.text "content" + t.integer "author_id", :null => false + t.integer "project_id", :null => false + t.datetime "created_at" + t.datetime "updated_at" + t.string "file_name" + end + create_table "users", :force => true do |t| t.string "email", :default => "", :null => false t.string "encrypted_password", :limit => 128, :default => "", :null => false @@ -72,6 +82,9 @@ ActiveRecord::Schema.define(:version => 20111015154310) do t.string "name" t.boolean "admin", :default => false, :null => false t.integer "projects_limit", :default => 10 + t.string "skype", :default => "", :null => false + t.string "linkedin", :default => "", :null => false + t.string "twitter", :default => "", :null => false end add_index "users", ["email"], :name => "index_users_on_email", :unique => true diff --git a/lib/color.rb b/lib/color.rb index d5500aca..23feecf4 100644 --- a/lib/color.rb +++ b/lib/color.rb @@ -11,6 +11,10 @@ module Color colorize(text, "32m") end + def yellow(text) + colorize(text, "93m") + end + def command(string) `#{string}` if $?.to_i > 0 diff --git a/lib/gitosis.rb b/lib/gitosis.rb index 4cc5e6e3..cab7da2d 100644 --- a/lib/gitosis.rb +++ b/lib/gitosis.rb @@ -27,13 +27,11 @@ class Gitosis def configure status = Timeout::timeout(20) do File.open(File.join(Dir.tmpdir,"gitlabhq-gitosis.lock"), "w+") do |f| - begin + begin f.flock(File::LOCK_EX) - pull yield(self) push - ensure f.flock(File::LOCK_UN) end diff --git a/lib/utils.rb b/lib/utils.rb index 6e7460ed..e57121a3 100644 --- a/lib/utils.rb +++ b/lib/utils.rb @@ -1,8 +1,51 @@ module Utils - def self.binary?(string) - string.each_byte do |x| - x.nonzero? or return true + module FileHelper + def binary?(string) + string.each_byte do |x| + x.nonzero? or return true + end + false + end + + def image? + mime_type =~ /image/ + end + + def text? + mime_type =~ /application|text/ && !binary?(data) + end + end + + module Colorize + def colorize + system_colorize(data, name) + end + + def system_colorize(data, file_name) + ft = handle_file_type(file_name) + Pygments.highlight(data, :lexer => ft, :options => { :encoding => 'utf-8', :linenos => 'True' }) + end + + def handle_file_type(file_name, mime_type = nil) + if file_name =~ /(\.rb|\.ru|\.rake|Rakefile|\.gemspec|\.rbx|Gemfile)$/ + :ruby + elsif file_name =~ /\.py$/ + :python + elsif file_name =~ /(\.pl|\.scala|\.c|\.cpp|\.java|\.haml|\.html|\.sass|\.scss|\.xml|\.php|\.erb)$/ + $1[1..-1].to_sym + elsif file_name =~ /\.js$/ + :javascript + elsif file_name =~ /\.sh$/ + :bash + elsif file_name =~ /\.coffee$/ + :coffeescript + elsif file_name =~ /\.yml$/ + :yaml + elsif file_name =~ /\.md$/ + :minid + else + :text + end end - false end end diff --git a/spec/factories.rb b/spec/factories.rb index ea055d1b..cc0cd4e5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -35,6 +35,12 @@ Factory.add(:issue, Issue) do |obj| obj.content = Faker::Lorem.sentences end +Factory.add(:snippet, Snippet) do |obj| + obj.title = Faker::Lorem.sentence + obj.file_name = Faker::Lorem.sentence + obj.content = Faker::Lorem.sentences +end + Factory.add(:note, Note) do |obj| obj.note = Faker::Lorem.sentence end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 23609023..b2d594c9 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -38,5 +38,6 @@ end # created_at :datetime # updated_at :datetime # closed :boolean default(FALSE), not null +# position :integer default(0) # diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb new file mode 100644 index 00000000..9dab72ca --- /dev/null +++ b/spec/models/snippet_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Snippet do + describe "Associations" do + it { should belong_to(:project) } + it { should belong_to(:author) } + end + + describe "Validation" do + it { should validate_presence_of(:title) } + it { should validate_presence_of(:author_id) } + it { should validate_presence_of(:project_id) } + it { should validate_presence_of(:file_name) } + it { should validate_presence_of(:content) } + end +end +# == Schema Information +# +# Table name: snippets +# +# id :integer not null, primary key +# title :string(255) +# content :text +# author_id :integer not null +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# file_name :string(255) +# + diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 77abe2ca..32fb90a3 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -39,5 +39,8 @@ end # name :string(255) # admin :boolean default(FALSE), not null # projects_limit :integer +# skype :string +# linkedin :string +# twitter :string # diff --git a/spec/requests/profile_spec.rb b/spec/requests/profile_spec.rb index 07fdc4ab..5838f63b 100644 --- a/spec/requests/profile_spec.rb +++ b/spec/requests/profile_spec.rb @@ -14,6 +14,22 @@ describe "Profile" do it { page.should have_content(@user.email) } end + describe "Profile update" do + before do + visit profile_path + fill_in "user_skype", :with => "testskype" + fill_in "user_linkedin", :with => "testlinkedin" + fill_in "user_twitter", :with => "testtwitter" + click_button "Save" + @user.reload + end + + it { @user.skype.should == 'testskype' } + it { @user.linkedin.should == 'testlinkedin' } + it { @user.twitter.should == 'testtwitter' } + end + + describe "Password update" do before do visit profile_password_path diff --git a/spec/requests/projects_security_spec.rb b/spec/requests/projects_security_spec.rb index a725a49c..90f88d88 100644 --- a/spec/requests/projects_security_spec.rb +++ b/spec/requests/projects_security_spec.rb @@ -82,12 +82,18 @@ describe "Projects" do end describe "GET /project_code/blob" do - it { blob_project_path(@project).should be_allowed_for @u1 } - it { blob_project_path(@project).should be_allowed_for @u3 } - it { blob_project_path(@project).should be_denied_for :admin } - it { blob_project_path(@project).should be_denied_for @u2 } - it { blob_project_path(@project).should be_denied_for :user } - it { blob_project_path(@project).should be_denied_for :visitor } + before do + @commit = @project.commit + @path = @commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name + @blob_path = blob_project_path(@project, :commit_id => @commit.id, :path => @path) + end + + it { @blob_path.should be_allowed_for @u1 } + it { @blob_path.should be_allowed_for @u3 } + it { @blob_path.should be_denied_for :admin } + it { @blob_path.should be_denied_for @u2 } + it { @blob_path.should be_denied_for :user } + it { @blob_path.should be_denied_for :visitor } end describe "GET /project_code/edit" do @@ -107,5 +113,14 @@ describe "Projects" do it { project_issues_path(@project).should be_denied_for :user } it { project_issues_path(@project).should be_denied_for :visitor } end + + describe "GET /project_code/snippets" do + it { project_snippets_path(@project).should be_allowed_for @u1 } + it { project_snippets_path(@project).should be_allowed_for @u3 } + it { project_snippets_path(@project).should be_denied_for :admin } + it { project_snippets_path(@project).should be_denied_for @u2 } + it { project_snippets_path(@project).should be_denied_for :user } + it { project_snippets_path(@project).should be_denied_for :visitor } + end end end diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb index 2825a6a9..945c1ea2 100644 --- a/spec/requests/projects_spec.rb +++ b/spec/requests/projects_spec.rb @@ -72,7 +72,10 @@ describe "Projects" do current_path.should == project_path(@project) end - it_behaves_like :tree_view + it "should beahave like dashboard" do + page.should have_content("History") + end + end describe "GET /projects/team" do @@ -134,8 +137,6 @@ describe "Projects" do it "should show project" do page.should have_content("Awesome") end - - it_behaves_like :tree_view end #describe "DELETE /projects/:id", :js => true do diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb new file mode 100644 index 00000000..00ae58da --- /dev/null +++ b/spec/requests/snippets_spec.rb @@ -0,0 +1,101 @@ +require 'spec_helper' + +describe "Snippets" do + let(:project) { Factory :project } + + before do + login_as :user + project.add_access(@user, :read, :write) + end + + describe "GET /snippets" do + before do + @snippet = Factory :snippet, + :author => @user, + :project => project + + visit project_snippets_path(project) + end + + subject { page } + + it { should have_content(@snippet.title) } + it { should have_content(@snippet.project.name) } + it { should have_content(@snippet.author.name) } + + describe "Destroy" do + before do + # admin access to remove snippet + @user.users_projects.destroy_all + project.add_access(@user, :read, :write, :admin) + visit project_snippets_path(project) + end + + it "should remove entry" do + expect { + click_link "destroy_snippet_#{@snippet.id}" + }.to change { Snippet.count }.by(-1) + end + end + end + + describe "New snippet" do + before do + visit project_snippets_path(project) + click_link "New Snippet" + end + + it "should open new snippet popup" do + page.current_path.should == new_project_snippet_path(project) + end + + describe "fill in" do + before do + fill_in "snippet_title", :with => "login function" + fill_in "snippet_file_name", :with => "test.rb" + fill_in "snippet_content", :with => "def login; end" + end + + it { expect { click_button "Save" }.to change {Snippet.count}.by(1) } + + it "should add new snippet to table" do + click_button "Save" + page.current_path.should == project_snippet_path(project, Snippet.last) + page.should have_content "login function" + page.should have_content "test.rb" + end + end + end + + describe "Edit snippet" do + before do + @snippet = Factory :snippet, + :author => @user, + :project => project + visit project_snippets_path(project) + click_link "Edit" + end + + it "should open edit page" do + page.current_path.should == edit_project_snippet_path(project, @snippet) + end + + describe "fill in" do + before do + fill_in "snippet_title", :with => "login function" + fill_in "snippet_file_name", :with => "test.rb" + fill_in "snippet_content", :with => "def login; end" + end + + it { expect { click_button "Save" }.to_not change {Snippet.count} } + + it "should update snippet fields" do + click_button "Save" + + page.current_path.should == project_snippet_path(project, @snippet) + page.should have_content "login function" + page.should have_content "test.rb" + end + end + end +end diff --git a/spec/requests/team_members_spec.rb b/spec/requests/team_members_spec.rb index db7513ae..dd92febf 100644 --- a/spec/requests/team_members_spec.rb +++ b/spec/requests/team_members_spec.rb @@ -7,6 +7,15 @@ describe "TeamMembers" do @project.add_access(@user, :read, :admin) end + describe "View profile" do + it "should be available" do + visit(team_project_path(@project)) + find(:xpath, "//table[@id='team-table']//a[1]").click + page.should have_content @user.skype + page.should_not have_content 'Twitter' + end + end + describe "New Team member", :js => true do before do @user_1 = Factory :user diff --git a/spec/requests/user_security_spec.rb b/spec/requests/user_security_spec.rb index 3c923870..a27eb1ca 100644 --- a/spec/requests/user_security_spec.rb +++ b/spec/requests/user_security_spec.rb @@ -7,10 +7,10 @@ describe "Users Security" do end describe "GET /login" do - it { new_user_session_path.should be_denied_for @u1 } - it { new_user_session_path.should be_denied_for :admin } - it { new_user_session_path.should be_denied_for :user } - it { new_user_session_path.should be_allowed_for :visitor } + #it { new_user_session_path.should be_denied_for @u1 } + #it { new_user_session_path.should be_denied_for :admin } + #it { new_user_session_path.should be_denied_for :user } + it { new_user_session_path.should_not be_404_for :visitor } end describe "GET /keys" do diff --git a/spec/support/login.rb b/spec/support/login.rb index 09f64f9e..462647ab 100644 --- a/spec/support/login.rb +++ b/spec/support/login.rb @@ -3,7 +3,8 @@ module LoginMacros @user = User.create(:email => "user#{User.count}@mail.com", :name => "John Smith", :password => "123456", - :password_confirmation => "123456") + :password_confirmation => "123456", + :skype => 'user_skype') if role == :admin @user.admin = true diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 953b5356..dcdfa6d5 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -21,17 +21,30 @@ RSpec::Matchers.define :be_denied_for do |user| end end +RSpec::Matchers.define :be_404_for do |user| + match do |url| + include UrlAccess + url_404?(user, url) + end +end + module UrlAccess def url_allowed?(user, url) emulate_user(user) visit url - result = (current_path == url) + (page.status_code != 404 && current_path != new_user_session_path) end def url_denied?(user, url) emulate_user(user) visit url - result = (current_path != url) + (page.status_code == 404 || current_path == new_user_session_path) + end + + def url_404?(user, url) + emulate_user(user) + visit url + page.status_code == 404 end def emulate_user(user) diff --git a/update.rb b/update.rb index d7eec289..b81a4088 100644 --- a/update.rb +++ b/update.rb @@ -2,6 +2,10 @@ root_path = File.expand_path(File.dirname(__FILE__)) require File.join(root_path, "lib", "color") include Color +def version + File.read("VERSION") +end + # # ruby ./update.rb development # or test or production (default) # @@ -12,15 +16,29 @@ env = if envs.include?(ARGV[0]) "production" end -puts green " == Update for ENV=#{env}" +puts yellow "== RAILS ENV | #{env}" +current_version = version +puts yellow "Your version is #{current_version}" +puts yellow "Check for new version: $ git pull origin 1x" +`git pull origin 1x` # pull from origin -# pull from github -`git pull` +# latest version +if version == current_version + puts yellow "You have a latest version" +else + puts green "Update to #{version}" `bundle install` -# migrate db + # migrate db +if env == "development" +`bundle exec rake db:migrate RAILS_ENV=development` +`bundle exec rake db:migrate RAILS_ENV=test` +else `bundle exec rake db:migrate RAILS_ENV=#{env}` +end + + puts green "== Done! Now you can start/restart server" +end -puts green " == Done! Now you can start/restart server" From ba8048d71019b5aaa1f92ee5c3415bfddaa9babb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 22 Oct 2011 16:07:26 +0300 Subject: [PATCH 11/18] v1.1.0 --- README.rdoc | 20 ++++++++-- app/assets/stylesheets/projects.css.scss | 9 +++++ app/controllers/team_members_controller.rb | 28 ++++---------- app/models/project.rb | 9 ++++- app/models/users_project.rb | 7 +++- app/views/commits/_diff.html.haml | 44 +++------------------- app/views/commits/_diff_head.html.haml | 24 ++++++++++++ app/views/commits/_text_file.html.haml | 15 ++++++++ db/fixtures/development/001_admin.rb | 10 ++++- db/fixtures/production/001_admin.rb | 9 +++++ install.rb | 32 ---------------- lib/gitosis.rb | 2 +- spec/models/project_spec.rb | 9 +++++ spec/requests/team_members_spec.rb | 26 +++++++++++-- update.rb | 44 ---------------------- 15 files changed, 141 insertions(+), 147 deletions(-) create mode 100644 app/views/commits/_diff_head.html.haml create mode 100644 app/views/commits/_text_file.html.haml delete mode 100644 install.rb delete mode 100644 update.rb diff --git a/README.rdoc b/README.rdoc index dc749693..4016ebba 100644 --- a/README.rdoc +++ b/README.rdoc @@ -28,26 +28,34 @@ sqlite as default db git clone git://github.com/gitlabhq/gitlabhq.git + cd gitlabhq/ # install this library first sudo easy_install pygments + + # give your user access to remove git repo + # Ex. + # If you are going to use user 'gitlabhq' for rails server + # gitlabhq ALL = (git) NOPASSWD: /bin/rm" | sudo tee -a /etc/sudoers + # + echo "USERNAME ALL = (git) NOPASSWD: /bin/rm" | sudo tee -a /etc/sudoers sudo gem install bundler + bundle - RAILS_ENV=production rake db:setup + bundle exec rake db:setup RAILS_ENV=production # create admin user # login....admin@local.host # pass.....5iveL!fe - RAILS_ENV=production rake db:seed_fu + bundle exec rake db:seed_fu RAILS_ENV=production Install gitosis, edit conf/gitosis.yml & start server rails s -e production - == Install Gitosis sudo aptitude install gitosis @@ -64,6 +72,7 @@ Install gitosis, edit conf/gitosis.yml & start server ssh-keygen -t rsa sudo -H -u git gitosis-init < ~/.ssh/id_rsa.pub + sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update @@ -84,3 +93,8 @@ Install gitosis, edit conf/gitosis.yml & start server echo "gem: --no-rdoc --no-ri" > ~/.gemrc + +== Contribute + +We develop project on our private server. +Want to help? Contact us on twitter or email to become a team member. diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss index 51788672..8caa2810 100644 --- a/app/assets/stylesheets/projects.css.scss +++ b/app/assets/stylesheets/projects.css.scss @@ -638,3 +638,12 @@ tbody tr:nth-child(2n) td, tbody tr.even td { display:none; } } + +.field_with_errors { + input[type="text"], + input[type="password"], + textarea + { + background: none repeat scroll 0 0 #FFBBBB + } +} diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb index 5fb2710d..84addf8d 100644 --- a/app/controllers/team_members_controller.rb +++ b/app/controllers/team_members_controller.rb @@ -8,35 +8,16 @@ class TeamMembersController < ApplicationController def show @team_member = project.users_projects.find(params[:id]) - - respond_to do |format| - format.html # show.html.erb - format.js - end end def new @team_member = project.users_projects.new - - respond_to do |format| - format.html # new.html.erb - format.js - end end def create @team_member = UsersProject.new(params[:team_member]) @team_member.project = project - - respond_to do |format| - if @team_member.save - format.html { redirect_to @team_member, notice: 'Team member was successfully created.' } - format.js - else - format.html { render action: "new" } - format.js - end - end + @team_member.save end def update @@ -45,7 +26,12 @@ class TeamMembersController < ApplicationController respond_to do |format| format.js - format.html { redirect_to team_project_path(@project)} + format.html do + unless @team_member.valid? + flash[:alert] = "User should have at least one role" + end + redirect_to team_project_path(@project) + end end end diff --git a/app/models/project.rb b/app/models/project.rb index d70b18e7..5262e552 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -35,7 +35,8 @@ class Project < ActiveRecord::Base :presence => true validate :check_limit - + validate :repo_name + after_destroy :destroy_gitosis_project after_save :update_gitosis_project @@ -168,6 +169,12 @@ class Project < ActiveRecord::Base errors[:base] << ("Cant check your ability to create project") end + def repo_name + if path == "gitosis-admin" + errors.add(:path, " like 'gitosis-admin' is not allowed") + end + end + def valid_repo? repo rescue diff --git a/app/models/users_project.rb b/app/models/users_project.rb index bdc10633..96e2d16a 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -9,7 +9,8 @@ class UsersProject < ActiveRecord::Base validates_uniqueness_of :user_id, :scope => [:project_id] validates_presence_of :user_id validates_presence_of :project_id - + validate :user_has_a_role_selected + delegate :name, :email, :to => :user, :prefix => true def update_gitosis_project @@ -18,6 +19,10 @@ class UsersProject < ActiveRecord::Base end end + def user_has_a_role_selected + errors.add(:base, "Please choose at least one Role in the Access list") unless read || write || admin + end + end # == Schema Information # diff --git a/app/views/commits/_diff.html.haml b/app/views/commits/_diff.html.haml index 73652aaf..2807e090 100644 --- a/app/views/commits/_diff.html.haml +++ b/app/views/commits/_diff.html.haml @@ -1,27 +1,5 @@ -.file_stats - - @commit.diffs.each do |diff| - - if diff.deleted_file - %span.removed_file - %a{:href => "##{diff.a_path}"} - = diff.a_path - = image_tag "blueprint_delete.png" - - elsif diff.renamed_file - %span.moved_file - %a{:href => "##{diff.b_path}"} - = diff.a_path - = "->" - = diff.b_path - = image_tag "blueprint_notice.png" - - elsif diff.new_file - %span.new_file - %a{:href => "##{diff.b_path}"} - = diff.b_path - = image_tag "blueprint_add.png" - - else - %span.edit_file - %a{:href => "##{diff.b_path}"} - = diff.b_path - = image_tag "blueprint_info.png" +.file_stats= render "commits/diff_head" + - @commit.diffs.each do |diff| - next if diff.diff.empty? - file = (@commit.tree / diff.b_path) @@ -31,24 +9,12 @@ - if diff.deleted_file %strong{:id => "#{diff.b_path}"}= diff.a_path - else - %strong{:id => "#{diff.b_path}"}= diff.b_path + = link_to tree_file_project_path(@project, @commit.id, diff.b_path) do + %strong{:id => "#{diff.b_path}"}= diff.b_path %br/ .diff_file_content - if file.text? - - lines_arr = diff.diff.lines.to_a - - line_old = lines_arr[2].match(/-(\d)/)[0].to_i.abs rescue 0 - - line_new = lines_arr[2].match(/\+(\d)/)[0].to_i.abs rescue 0 - - lines = lines_arr[3..-1].join - - lines.each_line do |line| - = diff_line(line, line_new, line_old) - - if line[0] == "+" - - line_new += 1 - - elsif - - line[0] == "-" - - line_old += 1 - - else - - line_new += 1 - - line_old += 1 + = render :partial => "commits/text_file", :locals => { :diff => diff } - elsif file.image? .diff_file_content_image %img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} diff --git a/app/views/commits/_diff_head.html.haml b/app/views/commits/_diff_head.html.haml new file mode 100644 index 00000000..922c3599 --- /dev/null +++ b/app/views/commits/_diff_head.html.haml @@ -0,0 +1,24 @@ +- @commit.diffs.each do |diff| + - if diff.deleted_file + %span.removed_file + %a{:href => "##{diff.a_path}"} + = diff.a_path + = image_tag "blueprint_delete.png" + - elsif diff.renamed_file + %span.moved_file + %a{:href => "##{diff.b_path}"} + = diff.a_path + = "->" + = diff.b_path + = image_tag "blueprint_notice.png" + - elsif diff.new_file + %span.new_file + %a{:href => "##{diff.b_path}"} + = diff.b_path + = image_tag "blueprint_add.png" + - else + %span.edit_file + %a{:href => "##{diff.b_path}"} + = diff.b_path + = image_tag "blueprint_info.png" + diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml new file mode 100644 index 00000000..b20aa8af --- /dev/null +++ b/app/views/commits/_text_file.html.haml @@ -0,0 +1,15 @@ +- lines_arr = diff.diff.lines.to_a +- line_old = lines_arr[2].match(/-(\d)/)[0].to_i.abs rescue 0 +- line_new = lines_arr[2].match(/\+(\d)/)[0].to_i.abs rescue 0 +- lines = lines_arr[3..-1].join +- lines.each_line do |line| + = diff_line(line, line_new, line_old) + - if line[0] == "+" + - line_new += 1 + - elsif + - line[0] == "-" + - line_old += 1 + - else + - line_new += 1 + - line_old += 1 + diff --git a/db/fixtures/development/001_admin.rb b/db/fixtures/development/001_admin.rb index 9c5a6da0..cfff6bf8 100644 --- a/db/fixtures/development/001_admin.rb +++ b/db/fixtures/development/001_admin.rb @@ -1,4 +1,3 @@ -# Admin account admin = User.create( :email => "admin@local.host", :name => "Administrator", @@ -9,3 +8,12 @@ admin = User.create( admin.projects_limit = 10000 admin.admin = true admin.save! + +if admin.valid? +puts %q[ +Administrator account created: + +login.........admin@local.host +password......5iveL!fe +] +end diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb index 94d1abe8..cfff6bf8 100644 --- a/db/fixtures/production/001_admin.rb +++ b/db/fixtures/production/001_admin.rb @@ -8,3 +8,12 @@ admin = User.create( admin.projects_limit = 10000 admin.admin = true admin.save! + +if admin.valid? +puts %q[ +Administrator account created: + +login.........admin@local.host +password......5iveL!fe +] +end diff --git a/install.rb b/install.rb deleted file mode 100644 index a118cb5d..00000000 --- a/install.rb +++ /dev/null @@ -1,32 +0,0 @@ -root_path = File.expand_path(File.dirname(__FILE__)) -require File.join(root_path, "lib", "color") -include Color - -# -# ruby ./update.rb development # or test or production (default) -# -envs = ["production", "test", "development"] -env = if envs.include?(ARGV[0]) - ARGV[0] - else - "production" - end - -puts green " == Install for ENV=#{env} ..." - -# bundle install -`bundle install` - -# migrate db -`bundle exec rake db:create RAILS_ENV=#{env}` -`bundle exec rake db:schema:load RAILS_ENV=#{env}` -`bundle exec rake db:seed_fu RAILS_ENV=#{env}` - -puts green %q[ -Administrator account created: - -login.........admin@local.host -password......5iveL!fe -] - -puts green " == Done! Now you can start server" diff --git a/lib/gitosis.rb b/lib/gitosis.rb index cab7da2d..92d32d8b 100644 --- a/lib/gitosis.rb +++ b/lib/gitosis.rb @@ -42,7 +42,7 @@ class Gitosis end def destroy_project(project) - FileUtils.rm_rf(project.path_to_repo) + `sudo -u git rm -rf #{project.path_to_repo}` conf = IniFile.new(File.join(@local_dir,'gitosis','gitosis.conf')) diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 6ed8653d..0c62743d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -4,11 +4,15 @@ describe Project do describe "Associations" do it { should have_many(:users) } it { should have_many(:users_projects) } + it { should have_many(:issues) } + it { should have_many(:notes) } + it { should have_many(:snippets) } end describe "Validation" do it { should validate_presence_of(:name) } it { should validate_presence_of(:path) } + it { should validate_presence_of(:code) } end describe "Respond to" do @@ -31,6 +35,11 @@ describe Project do it { should respond_to(:commit) } end + it "should not allow 'gitosis-admin' as repo name" do + should allow_value("blah").for(:path) + should_not allow_value("gitosis-admin").for(:path) + end + it "should return valid url to repo" do project = Project.new(:path => "somewhere") project.url_to_repo.should == "git@localhost:somewhere.git" diff --git a/spec/requests/team_members_spec.rb b/spec/requests/team_members_spec.rb index dd92febf..ec0af321 100644 --- a/spec/requests/team_members_spec.rb +++ b/spec/requests/team_members_spec.rb @@ -29,19 +29,37 @@ describe "TeamMembers" do describe "fill in" do before do - check "team_member_read" click_link "Select user" click_link @user_1.name - #select @user_1.name, :from => "team_member_user_id" + + within "#team_member_new" do + check "team_member_read" + check "team_member_write" + end end - it { expect { click_button "Save" }.to change {UsersProject.count}.by(1) } + it { expect { click_button "Save";sleep(1) }.to change {UsersProject.count}.by(1) } it "should add new member to table" do click_button "Save" + @member = UsersProject.last - page.should_not have_content("Add new member") page.should have_content @user_1.name + + @member.read.should be_true + @member.write.should be_true + @member.admin.should be_false + end + + it "should not allow creation without access selected" do + within "#team_member_new" do + uncheck "team_member_read" + uncheck "team_member_write" + uncheck "team_member_admin" + end + + expect { click_button "Save" }.to_not change {UsersProject.count} + page.should have_content("Please choose at least one Role in the Access list") end end end diff --git a/update.rb b/update.rb deleted file mode 100644 index b81a4088..00000000 --- a/update.rb +++ /dev/null @@ -1,44 +0,0 @@ -root_path = File.expand_path(File.dirname(__FILE__)) -require File.join(root_path, "lib", "color") -include Color - -def version - File.read("VERSION") -end - -# -# ruby ./update.rb development # or test or production (default) -# -envs = ["production", "test", "development"] -env = if envs.include?(ARGV[0]) - ARGV[0] - else - "production" - end - -puts yellow "== RAILS ENV | #{env}" -current_version = version -puts yellow "Your version is #{current_version}" -puts yellow "Check for new version: $ git pull origin 1x" -`git pull origin 1x` # pull from origin - -# latest version -if version == current_version - puts yellow "You have a latest version" -else - puts green "Update to #{version}" - -`bundle install` - - # migrate db -if env == "development" -`bundle exec rake db:migrate RAILS_ENV=development` -`bundle exec rake db:migrate RAILS_ENV=test` -else -`bundle exec rake db:migrate RAILS_ENV=#{env}` -end - - puts green "== Done! Now you can start/restart server" -end - - From 016012b14598f65aedec6f859bc47da7b7311ae7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 24 Oct 2011 22:47:53 +0300 Subject: [PATCH 12/18] Fixed: Commit message encoding error --- app/helpers/commits_helper.rb | 9 --------- app/views/commits/_commits.html.haml | 2 +- app/views/commits/show.html.haml | 2 +- app/views/projects/_recent_commits.html.haml | 2 +- app/views/projects/_recent_messages.html.haml | 2 +- app/views/projects/_tree.html.haml | 8 ++++---- app/views/projects/_tree_file.html.haml | 4 ++-- app/views/projects/_tree_item.html.haml | 2 +- config/initializers/grit_ext.rb | 4 ++++ lib/commit_ext.rb | 9 +++++++++ 10 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 lib/commit_ext.rb diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index b79e5718..f1b54668 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -21,13 +21,4 @@ module CommitsHelper link_to "More", project_commits_path(@project, :offset => offset.to_i + limit.to_i, :limit => limit), :remote => true, :class => "lite_button vm", :style => "text-align:center; width:930px; ", :id => "more-commits-link" end - - # Cause some errors with trucate & encoding use this method - def truncate_commit_message(commit, size = 60) - message = commit.message - message.length > size ? (message[0..(size - 1)] + "...") : message - # if special characters occurs - rescue - commit.message - end end diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml index 94a1bd1b..3ed70f1c 100644 --- a/app/views/commits/_commits.html.haml +++ b/app/views/commits/_commits.html.haml @@ -11,7 +11,7 @@ = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" %p %strong - = truncate_commit_message(commit) + = commit.truncated_message = link_to "Browse Code", tree_project_path(@project, :commit_id => commit.id), :class => "lite_button", :style => "float:right" = link_to truncate(commit.id.to_s, :length => 16), project_commit_path(@project, :id => commit.id), :class => "lite_button", :style => "width:120px;float:right" %span diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml index a2c9149d..0ba42618 100644 --- a/app/views/commits/show.html.haml +++ b/app/views/commits/show.html.haml @@ -1,5 +1,5 @@ %h3 - = "[ #{@commit.committer} ] #{truncate_commit_message(@commit, 80)}" + = "[ #{@commit.committer} ] #{@commit.truncated_message(40)}" -#= link_to 'Back', project_commits_path(@project), :class => "button" %table.round-borders %tr diff --git a/app/views/projects/_recent_commits.html.haml b/app/views/projects/_recent_commits.html.haml index e435ea30..36f4b636 100644 --- a/app/views/projects/_recent_commits.html.haml +++ b/app/views/projects/_recent_commits.html.haml @@ -6,7 +6,7 @@ = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" %p{:style => "margin-bottom: 3px;"} %strong - = link_to truncate_commit_message(commit, 60), project_commit_path(@project, :id => commit.id) + = link_to commit.truncated_message(60), project_commit_path(@project, :id => commit.id) %span %span.author diff --git a/app/views/projects/_recent_messages.html.haml b/app/views/projects/_recent_messages.html.haml index 1af7fe3b..36f1435b 100644 --- a/app/views/projects/_recent_messages.html.haml +++ b/app/views/projects/_recent_messages.html.haml @@ -19,7 +19,7 @@ - css_class = "dash_commit" - commit = parent - item_code = commit.author.email - - link_item_name = truncate_commit_message(commit, 50) + - link_item_name = commit.truncated_message(50) - link_to_item = project_commit_path(@project, :id => commit.id) - else - css_class = "dash_wall" diff --git a/app/views/projects/_tree.html.haml b/app/views/projects/_tree.html.haml index d1903586..11b04a3b 100644 --- a/app/views/projects/_tree.html.haml +++ b/app/views/projects/_tree.html.haml @@ -30,15 +30,15 @@ %th Last Update %th Last commit - = link_to "history", project_commits_path(@project, :path => params[:path]), :class => "right" + = link_to "history", project_commits_path(@project, :path => params[:path], :branch => params[:branch],:tag => params[:tag]), :class => "right" - if params[:path] - file = File.join(params[:path], "..") %tr{ :class => "tree-item", :url => tree_file_project_path(@project, @commit.id, file) } %td.tree-item-file-name = image_tag "dir.png" = link_to "..", tree_file_project_path(@project, @commit.id, file, :branch => @branch, :tag => @tag), :remote => :true - %td - %td + %td + %td - contents.select{ |i| i.is_a?(Grit::Tree)}.each do |content| = render :partial => "projects/tree_item", :locals => { :content => content } @@ -52,7 +52,7 @@ }); - if params[:path] && request.xhr? - :javascript + :javascript $(window).unbind('popstate'); $(window).bind('popstate', function() { if(location.pathname.search("tree") != -1) { diff --git a/app/views/projects/_tree_file.html.haml b/app/views/projects/_tree_file.html.haml index 41a2287a..b5b18213 100644 --- a/app/views/projects/_tree_file.html.haml +++ b/app/views/projects/_tree_file.html.haml @@ -4,7 +4,7 @@ %strong = name = link_to "raw", blob_project_path(@project, :commit_id => @commit.id, :path => params[:path] ), :class => "right", :target => "_blank" - = link_to "history", project_commits_path(@project, :path => params[:path]), :class => "right", :style => "margin-right:10px;" + = link_to "history", project_commits_path(@project, :path => params[:path], :branch => params[:branch], :tag => params[:tag] ), :class => "right", :style => "margin-right:10px;" %br/ - if file.text? .view_file_content @@ -14,6 +14,6 @@ .view_file_content_image %img{ :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - else - %p + %p %center No preview for this file type diff --git a/app/views/projects/_tree_item.html.haml b/app/views/projects/_tree_item.html.haml index 4ebcfbef..538d2cc6 100644 --- a/app/views/projects/_tree_item.html.haml +++ b/app/views/projects/_tree_item.html.haml @@ -12,4 +12,4 @@ = time_ago_in_words(content_commit.committed_date) ago %td - = link_to truncate_commit_message(content_commit, 40), project_commit_path(@project, content_commit) + = link_to content_commit.truncated_message(40), project_commit_path(@project, content_commit) diff --git a/config/initializers/grit_ext.rb b/config/initializers/grit_ext.rb index 4bd71003..9231da6f 100644 --- a/config/initializers/grit_ext.rb +++ b/config/initializers/grit_ext.rb @@ -6,3 +6,7 @@ Grit::Blob.class_eval do include Utils::FileHelper include Utils::Colorize end + +Grit::Commit.class_eval do + include CommitExt +end diff --git a/lib/commit_ext.rb b/lib/commit_ext.rb new file mode 100644 index 00000000..c175fa0c --- /dev/null +++ b/lib/commit_ext.rb @@ -0,0 +1,9 @@ +module CommitExt + # Cause of encoding rails truncate raise error + # this method is temporary decision + def truncated_message(size = 80) + message.length > size ? (message[0..(size - 1)] + "...") : message + rescue + "-- invalid encoding for commit message" + end +end From 1d69788099f4c28c8b6795cacc9a1ffaa8600ee0 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Oct 2011 19:23:39 +0300 Subject: [PATCH 13/18] fix encoding error, issues critical status added --- app/assets/stylesheets/projects.css.scss | 34 +++++++++++++++++++ app/controllers/issues_controller.rb | 2 +- app/models/issue.rb | 11 ++++++ app/views/commits/_commits.html.haml | 2 +- app/views/commits/show.html.haml | 4 +-- app/views/issues/_form.html.haml | 12 ++++--- app/views/issues/_issues.html.haml | 7 +++- app/views/issues/_show.html.haml | 20 +++++++++-- app/views/projects/_recent_commits.html.haml | 2 +- app/views/projects/_recent_messages.html.haml | 2 +- app/views/projects/_tree_item.html.haml | 2 +- .../20111025134235_add_high_label_to_issue.rb | 5 +++ db/schema.rb | 3 +- lib/commit_ext.rb | 10 +++--- spec/requests/team_members_spec.rb | 4 ++- 15 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 db/migrate/20111025134235_add_high_label_to_issue.rb diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss index 8caa2810..3e7633a6 100644 --- a/app/assets/stylesheets/projects.css.scss +++ b/app/assets/stylesheets/projects.css.scss @@ -647,3 +647,37 @@ tbody tr:nth-child(2n) td, tbody tr.even td { background: none repeat scroll 0 0 #FFBBBB } } + +.tag { + @include round-borders-all(4px); + padding:2px 4px; + border:none; + + &.high { + background: #D12F19; + color:white; + } + + &.today { + background: #44aa22; + color:white; + } + + &.yours { + background: #4466cc; + color:white; + } + &.notes { + background: #2c5c66; + color:white; + } +} + +#issues-table .issue { + &.critical { + td { + //background: #D12F19; + //color:#fff; + } + } +} diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index cf8e1ebe..757ada94 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -12,7 +12,7 @@ class IssuesController < ApplicationController def index @issues = case params[:f].to_i - when 1 then @project.issues.all + when 1 then @project.issues when 2 then @project.issues.closed when 3 then @project.issues.opened.assigned(current_user) else @project.issues.opened diff --git a/app/models/issue.rb b/app/models/issue.rb index 556cdc1c..904965ac 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -18,11 +18,22 @@ class Issue < ActiveRecord::Base :presence => true, :length => { :within => 0..2000 } + scope :critical, where(:critical => true) + scope :non_critical, where(:critical => false) + scope :opened, where(:closed => false) scope :closed, where(:closed => true) scope :assigned, lambda { |u| where(:assignee_id => u.id)} acts_as_list + + def today? + Date.today == created_at.to_date + end + + def new? + today? && created_at == updated_at + end end # == Schema Information # diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml index 3ed70f1c..99823065 100644 --- a/app/views/commits/_commits.html.haml +++ b/app/views/commits/_commits.html.haml @@ -11,7 +11,7 @@ = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" %p %strong - = commit.truncated_message + = truncate(commit.safe_message, :length => 60) = link_to "Browse Code", tree_project_path(@project, :commit_id => commit.id), :class => "lite_button", :style => "float:right" = link_to truncate(commit.id.to_s, :length => 16), project_commit_path(@project, :id => commit.id), :class => "lite_button", :style => "width:120px;float:right" %span diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml index 0ba42618..3beeada8 100644 --- a/app/views/commits/show.html.haml +++ b/app/views/commits/show.html.haml @@ -1,5 +1,5 @@ %h3 - = "[ #{@commit.committer} ] #{@commit.truncated_message(40)}" + = "[ #{@commit.committer} ] #{truncate(@commit.safe_message)}" -#= link_to 'Back', project_commits_path(@project), :class => "button" %table.round-borders %tr @@ -16,7 +16,7 @@ %td= @commit.committed_date %tr %td Message - %td= @commit.message + %td= @commit.safe_message %tr %td Tree %td= link_to 'Browse Code', tree_project_path(@project, :commit_id => @commit.id) diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml index 71acdba1..eae0ee0f 100644 --- a/app/views/issues/_form.html.haml +++ b/app/views/issues/_form.html.haml @@ -5,17 +5,21 @@ - @issue.errors.full_messages.each do |msg| %li= msg - .span-6 + .span-8 = f.label :title = f.text_field :title, :style => "width:450px" - .span-6 + .span-8 = f.label :content = f.text_area :content, :style => "width:450px; height:130px" - .span-6.append-bottom + .span-8.append-bottom = f.label :assignee_id = f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }) + .span-1 + = f.label :critical, "Critical" + %br + = f.check_box :critical - unless @issue.new_record? - .span-3.right + .span-2.right = f.label :closed %br = f.check_box :closed diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml index d3e21940..42e8371a 100644 --- a/app/views/issues/_issues.html.haml +++ b/app/views/issues/_issues.html.haml @@ -1,10 +1,15 @@ %table.round-borders#issues-table %tr + - if can?(current_user, :admin_issue, @project) && !params[:f] || params[:f] == "0" + %th %th Assignee %th ID %th Title %th Closed? %th - - @issues.each do |issue| + - @issues.critical.each do |issue| + = render(:partial => 'show', :locals => {:issue => issue}) + + - @issues.non_critical.each do |issue| = render(:partial => 'show', :locals => {:issue => issue}) diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml index 30157257..fcac006e 100644 --- a/app/views/issues/_show.html.haml +++ b/app/views/issues/_show.html.haml @@ -1,10 +1,24 @@ -%tr{ :id => dom_id(issue), :class => "issue", :url => project_issue_path(@project, issue) } +%tr{ :id => dom_id(issue), :class => "issue #{issue.critical ? "critical" : ""}", :url => project_issue_path(@project, issue) } + - if can?(current_user, :admin_issue, @project) && !params[:f] || params[:f] == "0" + %td + = image_tag "move.png" , :class => [:handle, :left] %td - = image_tag "move.png" , :class => [:handle, :left] = image_tag gravatar_icon(issue.assignee.email), :class => "left", :width => 40, :style => "padding:0 5px;" = truncate issue.assignee.name, :lenght => 20 %td ##{issue.id} - %td= html_escape issue.title + %td + = html_escape issue.title + %br + - if issue.critical + %span.tag.high critical + - if issue.today? + %span.tag.today today + -#- if issue.author == current_user + -#%span.tag.yours yours + -#- if issue.notes.count > 0 + -#%span.tag.notes + -#= issue.notes.count + -#notes %td - if can? current_user, :write_issue, @project = form_for([@project, issue], :remote => true) do |f| diff --git a/app/views/projects/_recent_commits.html.haml b/app/views/projects/_recent_commits.html.haml index 36f4b636..3157c356 100644 --- a/app/views/projects/_recent_commits.html.haml +++ b/app/views/projects/_recent_commits.html.haml @@ -6,7 +6,7 @@ = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;" %p{:style => "margin-bottom: 3px;"} %strong - = link_to commit.truncated_message(60), project_commit_path(@project, :id => commit.id) + = link_to truncate(commit.safe_message, :length => 60), project_commit_path(@project, :id => commit.id) %span %span.author diff --git a/app/views/projects/_recent_messages.html.haml b/app/views/projects/_recent_messages.html.haml index 36f1435b..67f3449b 100644 --- a/app/views/projects/_recent_messages.html.haml +++ b/app/views/projects/_recent_messages.html.haml @@ -19,7 +19,7 @@ - css_class = "dash_commit" - commit = parent - item_code = commit.author.email - - link_item_name = commit.truncated_message(50) + - link_item_name = truncate(commit.safe_message, :length => 50) - link_to_item = project_commit_path(@project, :id => commit.id) - else - css_class = "dash_wall" diff --git a/app/views/projects/_tree_item.html.haml b/app/views/projects/_tree_item.html.haml index 538d2cc6..53c05d5a 100644 --- a/app/views/projects/_tree_item.html.haml +++ b/app/views/projects/_tree_item.html.haml @@ -12,4 +12,4 @@ = time_ago_in_words(content_commit.committed_date) ago %td - = link_to content_commit.truncated_message(40), project_commit_path(@project, content_commit) + = link_to truncate(content_commit.safe_message, :length => 40), project_commit_path(@project, content_commit) diff --git a/db/migrate/20111025134235_add_high_label_to_issue.rb b/db/migrate/20111025134235_add_high_label_to_issue.rb new file mode 100644 index 00000000..676eaaf8 --- /dev/null +++ b/db/migrate/20111025134235_add_high_label_to_issue.rb @@ -0,0 +1,5 @@ +class AddHighLabelToIssue < ActiveRecord::Migration + def change + add_column :issues, :critical, :boolean, :default => false, :null => false + end +end diff --git a/db/schema.rb b/db/schema.rb index cc805990..21c224d4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111021101550) do +ActiveRecord::Schema.define(:version => 20111025134235) do create_table "issues", :force => true do |t| t.string "title" @@ -23,6 +23,7 @@ ActiveRecord::Schema.define(:version => 20111021101550) do t.datetime "updated_at" t.boolean "closed", :default => false, :null => false t.integer "position", :default => 0 + t.boolean "critical", :default => false, :null => false end create_table "keys", :force => true do |t| diff --git a/lib/commit_ext.rb b/lib/commit_ext.rb index c175fa0c..e09dbdaf 100644 --- a/lib/commit_ext.rb +++ b/lib/commit_ext.rb @@ -1,8 +1,10 @@ module CommitExt - # Cause of encoding rails truncate raise error - # this method is temporary decision - def truncated_message(size = 80) - message.length > size ? (message[0..(size - 1)] + "...") : message + def safe_message + message.encode("UTF-8", + :invalid => :replace, + :undef => :replace, + :universal_newline => true, + :replace => "") rescue "-- invalid encoding for commit message" end diff --git a/spec/requests/team_members_spec.rb b/spec/requests/team_members_spec.rb index ec0af321..650ed449 100644 --- a/spec/requests/team_members_spec.rb +++ b/spec/requests/team_members_spec.rb @@ -10,7 +10,9 @@ describe "TeamMembers" do describe "View profile" do it "should be available" do visit(team_project_path(@project)) - find(:xpath, "//table[@id='team-table']//a[1]").click + within "#team-table" do + click_link(@user.name) + end page.should have_content @user.skype page.should_not have_content 'Twitter' end From 23187d60c4eb3eb2d51459ab18fd16da9caa5b58 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 25 Oct 2011 21:07:39 +0300 Subject: [PATCH 14/18] fixed diff issue --- app/views/commits/_text_file.html.haml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml index b20aa8af..67033ade 100644 --- a/app/views/commits/_text_file.html.haml +++ b/app/views/commits/_text_file.html.haml @@ -1,8 +1,14 @@ +- line_old = 0 +- line_new = 0 - lines_arr = diff.diff.lines.to_a -- line_old = lines_arr[2].match(/-(\d)/)[0].to_i.abs rescue 0 -- line_new = lines_arr[2].match(/\+(\d)/)[0].to_i.abs rescue 0 -- lines = lines_arr[3..-1].join -- lines.each_line do |line| +- lines_arr.each do |line| + - next if line.match(/^--- a/) + - next if line.match(/^\+\+\+ b/) + - if line.match(/^@@ -/) + - line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0 + - line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0 + - next + = diff_line(line, line_new, line_old) - if line[0] == "+" - line_new += 1 From 121f6d04faedad570e6ce1d8d7e235b55c2a9048 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 6 Nov 2011 21:12:23 +0200 Subject: [PATCH 15/18] fixed conflicts --- app/assets/images/ajax-loader.gif | Bin 6820 -> 4178 bytes public/favicon.ico | Bin 0 -> 1150 bytes 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 public/favicon.ico diff --git a/app/assets/images/ajax-loader.gif b/app/assets/images/ajax-loader.gif index 0ca7ada960568fff04400cda966fbdcb106abfa2..c97ec6ea9739a68e25637c0aa4adaaea05e3e4ca 100644 GIT binary patch literal 4178 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 diff --git a/public/favicon.ico b/public/favicon.ico old mode 100644 new mode 100755 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ec0d298859a6e33a6cc40f7a502354b8cad5f76 GIT binary patch literal 1150 zcmZvc&rcIU6vv0?T~3}Vg?4v#yIp9zU1&k*FC;0yN&pE-r71xP79vXcVT>0+io~c1 z@uXK{B+(d6OeFpaN@9YEe?#HwsR-_La3ytienMto~)nRwQ- ztEU+|%NSFI377ELelaj6V$~l2tkU-O_ua*{^@FsA{g}@8q9dxKtviRl!Uob8+Ta!EAg$QvH?ga$D;u=7jC-I3O|)O%LUjBohDWow zICCGdrSIq+zm4V)7dd%ttzd{992)p}!V915J%{L}2T0!ff%9UY*uq!DZ@fotY!u;; zX657PiH$^CemQGdZh)@35gRKaxwM1C!WSeLx6xjBh3x1cW+(a)Yd0au_8EwEcrMo? z6gJQ~@d&A#Hk+9Lgv9)3Bo@CRI{6%#ksRiyhLGurTeTsU&cH?9ej|$5l_!YLeL(Em z8!>K)-xsXdBQ^KV${{lK5~)lcopIBu6|wgHNl^7h_yW!FH3p#g6d1kJ)*Ym0pP{F_ z6SAg53mD*f@Z|i&p43m&UQtACgmJkJTBrpbb03kpyo^>;fh5%*$L-vy=EPDDIQ`?? zBaNIlpe_Fx10z}ZRJ-Ptai@QXr(T?%DZH+X6CdcvAYh0yD}QTF8q!wwuhYl$ZW!U< z0rjZWr<9K>?&f$+vH!h44o_ogZ{NMVvQ|u{(z`B~x9oCBWtx+ZVwGB&AG#SUpJ8nK U6k~U4Y^(l{aMn(ow8Rkm2iEifo&W#< literal 0 HcmV?d00001 From 1d30877a68291ebd46fd995398394be6e7724141 Mon Sep 17 00:00:00 2001 From: Ariejan de Vroom Date: Wed, 9 Nov 2011 14:29:09 +0100 Subject: [PATCH 16/18] Moved shoulda to the :test group in Gemfile. This prevennts `rake test` from running after every other rake command. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index f32c13f0..806280fd 100644 --- a/Gemfile +++ b/Gemfile @@ -37,7 +37,6 @@ end group :development, :test do gem 'rspec-rails' - gem "shoulda", "~> 3.0.0.beta2" gem 'capybara' gem 'autotest' gem 'autotest-rails' @@ -51,4 +50,5 @@ end group :test do gem 'turn', :require => false gem 'simplecov', :require => false + gem "shoulda", "~> 3.0.0.beta2" end From 4dbed7ca88c2fe8f127deb752f82a5ee9ab4cade Mon Sep 17 00:00:00 2001 From: Ariejan de Vroom Date: Wed, 9 Nov 2011 15:15:21 +0100 Subject: [PATCH 17/18] Use secure.gravatar.com when running over SSL --- app/helpers/application_helper.rb | 4 ++- spec/helpers/application_helper_spec.rb | 35 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 spec/helpers/application_helper_spec.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 70047c41..a49d3dea 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,7 +1,9 @@ require 'digest/md5' module ApplicationHelper + def gravatar_icon(user_email) - "http://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon" + gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com" + "#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email)}?s=40&d=identicon" end def fixed_mode? diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb new file mode 100644 index 00000000..3e174ca4 --- /dev/null +++ b/spec/helpers/application_helper_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe ApplicationHelper do + context ".gravatar_icon" do + context "over http" do + it "returns the correct URL to www.gravatar.com" do + expected = "http://www.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon" + + # Pretend we're running over HTTP + helper.stub(:request) do + request = double('request') + request.stub(:ssl?) { false } + request + end + + helper.gravatar_icon("admin@local.host").should == expected + end + end + + context "over https" do + it "returns the correct URL to secure.gravatar.com" do + expected = "https://secure.gravatar.com/avatar/f7daa65b2aa96290bb47c4d68d11fe6a?s=40&d=identicon" + + # Pretend we're running over HTTPS + helper.stub(:request) do + request = double('request') + request.stub(:ssl?) { true } + request + end + + helper.gravatar_icon("admin@local.host").should == expected + end + end + end +end From 4454b6c593e51c5f23a7d391eb6a1f46aaa6bb45 Mon Sep 17 00:00:00 2001 From: Ariejan de Vroom Date: Wed, 9 Nov 2011 16:59:51 +0100 Subject: [PATCH 18/18] Show commits as 'Commit' instead of 'Grit::Commit' --- app/helpers/dashboard_helper.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 0560af5d..8921ee08 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -19,12 +19,15 @@ module DashboardHelper end def dashboard_feed_title(object) - title = case object.class.name.to_s + klass = object.class.to_s.split("::").last + + title = case klass when "Note" then markdown(object.note) when "Issue" then object.title - when "Grit::Commit" then object.safe_message + when "Commit" then object.safe_message else "" end - "[#{object.class.name}] #{truncate(sanitize(title, :tags => []), :length => 60)} " + + "[#{klass}] #{truncate(sanitize(title, :tags => []), :length => 60)} " end end